登录
    Technology changes quickly but people's minds change slowly.

缓存与数据库双写一致性问题

技术宅 破玉 1097次浏览 0个评论

  缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题?
  一般来说,我们无非以下几种策略:
1)先更新数据库,再更新缓存;
2)先删除缓存,再更新数据库;
3)先更新数据库,再删除缓存;
我们来逐一看一下这几种方式:

先更新数据库,再更新缓存

  这种方式在线程安全的角度来说,如果有多个线程同时对数据进行更新,我们没法保证他们更新缓存的先后(由于网络或者其他原因),这样就可能产生脏数据;另外在写场景比较多的情况下,频繁更新缓存,这种就比较浪费资源。而且可能更新了某个表的一个字段,然后其对应的缓存,是需要查询另外两个表的数据并进行运算,才能计算出缓存最新的值的

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

  数据发生了变更,先删除了缓存,然后要去修改数据库,此时还没修改。一个请求过来,去读缓存,发现缓存空了,去查询数据库,查到了修改前的旧数据,放到了缓存中。随后数据变更的程序完成了数据库的修改。完了,数据库和缓存中的数据不一样了…

先更新数据库,再删缓存

最经典的缓存+数据库读写的模式,就是 Cache Aside Pattern。

1)读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。
)
2)更新的时候,先更新数据库,然后再删除缓存。
如果删除缓存失败了,那么会导致数据库中是新数据,缓存中是旧数据,数据就出现了不一致。
所以说,在高并发的情况下,不一致的情况是可能存在的,这时候删除缓存,要保证提供一个保障的重试机制即可。

方案一

流程如下所示:
(1)更新数据库数据;
(2)缓存因为种种问题删除失败
(3)将需要删除的key发送至消息队列
(4)自己消费消息,获得需要删除的key
(5)继续重试删除操作,直到成功

方案二

流程如下图所示:
(1)更新数据库数据
(2)数据库会将操作信息写入binlog日志当中
(3)订阅程序提取出所需要的数据以及key
(4)另起一段非业务代码,获得该信息
(5)尝试删除缓存操作,发现删除失败
(6)将这些信息发送至消息队列
(7)重新从消息队列中获得该数据,重试操作。

最牛逼的方案

   无他,唯加机器尔

缓存与数据库双写一致性
华裳绕指柔, 版权所有丨如未注明 , 均为原创|转载请注明缓存与数据库双写一致性问题
喜欢 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址