码迷,mamicode.com
首页 > 其他好文 > 详细

为什么说延时双删很扯淡

时间:2020-04-02 01:23:58      阅读:1538      评论:0      收藏:0      [点我收藏+]

标签:mysql   strong   str   访问   说明   串行化   操作   遇到   获取   

redis和mysql数据一致性的问题

在这里,我们讨论三种更新策略:

  1. 先更新缓存,再更新数据库
  2. 先更新数据库,再更新缓存
  3. 先删除缓存,再更新数据库
  4. 先更新数据库,再删除缓存

第一种,先更新缓存,再更新数据库

问题:更新缓存成功,更新数据库失败,导致数据不一致。

第二种,先更新数据库,再更新缓存

问题:

1、A更新数据库

2、B更新数据库

3、B写入缓存

4、A写入缓存

出现数据不一致。

第二种,先删除缓存,再更新数据库。网络上的方案

延时双删

1、先删除缓存

2、更新数据库

3、等待一会再删除缓存

问题之一:延时双删,演变成了:先更新数据库,再删除缓存。。。。

比如:

1、A删除缓存

2、B查询数据库获取旧值

3、B更新了缓存

4、A更新数据库

5、A延时删缓存

1~3步执行后,数据库和缓存是一致的,成了开支执行前的状态,相当于没执行。

4~5步:先更新数据库,再删缓存。

所以延时双删演变成了:先更新数据库,再删除缓存。问题还是没解决。。。

为什么?假设,此时,在第4步执行之前,又来了个查询C,C查询到旧值。第6步:C将旧值插入缓存。此时出现缓存和数据库不一致。

延时并不能解决:C插入缓存的操作在第5步后面执行,比如C遇到网络问题、GC问题等。当然这是小概率,但并不代表不存在。

当然,延时越长,这个问题越能规避。如果业务需求不是非常严格,是可以忽略的。

第三种,先更新数据库,再删除缓存

问题:上面C的查询,已经说明问题了。

出现数据不一致的概率,比较小。采取这个方案,取决于业务需求。

终极方案

真正靠谱的方案:将访问操作串行化

  1. 先删缓存,将更新数据库的操作放进有序队列中
  2. 从缓存查不到的查询操作,都进入有序队列

会面临的问题:

  1. 读请求积压,大量超时,导致数据库的压力:限流、熔断
  2. 如何避免大量请求积压:将队列水平拆分,提高并行度。
  3. 保证相同请求路由正确。

为什么说延时双删很扯淡

标签:mysql   strong   str   访问   说明   串行化   操作   遇到   获取   

原文地址:https://www.cnblogs.com/zhouj-happy/p/12616906.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!