您当前的位置 :三板富> 科技 > 正文
如何应对数据库缓存双写一致性问题
2022-02-20 12:16:00 来源:程序那点事官方百家号 编辑:news2020

我们在日常的工作中常常会使用缓存去优化我们程序的性能,但是在使用了缓存之后,往往会引发一个问题,那就是数据库缓存双写一致性的问题,当我们更新数据时应当如何去做,才能更好的保证数据库缓存数据的一致。

1 前言

日常开发中,我们接口响应缓慢,往往是因为数据库读写产生的,这时为了优化这些接口,往往我们会将数据库的数据写入缓存中,让接口直接从缓存中获取数据,这样能极大的提高接口的访问速度。但是随之而来的问题就是,在我们更新数据库的数据时,就需要去更新缓存中的数据,或者是删除缓存中的数据,让其再次访问时通过读数据库,再将读到的数据刷入缓存中。但是如果在这期间出现并发,就很容易导致数据库缓存中数据不一致,这也是本篇文章的主题如何应对数据库缓存双写一致性问题。

这里我们说的一致性是指最终一致性,并不是强一致性。

2 推荐方案 Cache Aside Pattern

命中:程序从缓存读取数据,读到数据即命中

失效:程序从缓存读取数据,未读到数据,此时缓存失效,需要先去数据库读取,再刷入缓存

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

3 更新方案

更新缓存

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

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

删除缓存

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

先更新数据库,再删除缓存(常用)

4 更新方案选择原因

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

如下图,当A线程更新完缓存的数据A,这时A线程出现延迟,B线程将A线程缓存的更新覆盖,并且将数据库中的数据A也更新,A线程恢复去更新数据库,这时又将B线程对数据库的修改覆盖,这样就会出现严重的双写不一致,导致后续每次读取到的缓存中的数据都是有问题的,并且数据库的数据对我们来说更为重要,我们一般持久化都是依赖数据库的,如果先更新缓存的话,后续程序宕机,数据库中的数据就得不到更新,我们一般是不会依赖缓存做持久化保存的,所以这种方案是一定不能选择的。

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

如下图,当A线程更新完数据库的数据A,这时A线程出现延迟,B线程将A线程数据库的更新覆盖,并且将缓存中的数据A也更新,A线程恢复去更新缓存,这时又将B线程对缓存的修改覆盖,这样就会出现严重的双写不一致,导致后续每次取到缓存中的数据都是有问题的。

与上个方案一样,凡是更新缓存数据的都会出现这种严重的双写不一致,所以一般我们不采取更新缓存的方案,而是从删除缓存中的方案做选择。

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

如下图,当A线程删除缓存数据A,这时A线程出现延迟,B线程将读取A,发现缓存无数据,将数据库A的旧值查出来,并且将其更新到缓存中,当A线程恢复时,又将A的新值写入数据库,这样也会出现严重的双写不一致,导致后续每次取到缓存中的数据都是有问题的。

所以,先删除缓存的方案也不建议选择。

4.4 先更新数据库,再删除缓存(常用)

先更新数据库再删除缓存这种方案是我们所选择的,当然这种也有几率出现缓存不一致的现象,当缓存失效时,就会出现和先删除缓存,在更新数据库一样的问题。如下图:

但是一般情况下,是不会出现上述情况,出现上述情况的机率是特别低的。出现上述情况也可以采取延迟双删,先删除一次,让线程休眠一会,再删除一次,就会将不小心写入的错误数据清掉。

所以说这种方案只会出现下一种情况,如果想要避免这种情况只能通过加锁来解决,避免读到脏数据。

5 优化方案

基于上述方案我们还可以做哪些优化

读数据加锁(分布式锁)防止高并发打垮数据库

延迟双删,防止缓存失效时(读写分离架构下,读从库延迟问题),存入旧数据,第二次删除可以异步执行等待删除

如果需要做重试机制可以依赖于消息队列的可靠消费

可以通过订阅Binlog日志来优化删除逻辑

禁忌:过度设计,一般简单的延迟双删就可以实现需求,无需增加系统复杂度

作者:CoderJie

链接:https://juejin.cn/post/706634485327724547

标签: 如何应对 双写一致

相关阅读
版权和免责申明

凡注有"三板富 | 专注于新三板的第一垂直服务平台"或电头为"三板富 | 专注于新三板的第一垂直服务平台"的稿件,均为三板富 | 专注于新三板的第一垂直服务平台独家版权所有,未经许可不得转载或镜像;授权转载必须注明来源为"三板富 | 专注于新三板的第一垂直服务平台",并保留"三板富 | 专注于新三板的第一垂直服务平台"的电头。

最新热点

精彩推送

 

Copyright © 1999-2020 www.3bf.cc All Rights Reserved 
三板富投资网  版权所有 沪ICP备2020036824号-16联系邮箱:562 66 29@qq.com