【夯实Redis】如何保证数据库与缓存双写一致性?        跟着大宇学Redis--------目录帖

网友投稿 614 2022-11-16

【夯实Redis】如何保证数据库与缓存双写一致性?        跟着大宇学Redis--------目录帖

【夯实Redis】如何保证数据库与缓存双写一致性?        跟着大宇学Redis--------目录帖

目录

​​一、更新操作​​

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

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

​​先删除缓存,再更新数据库,最后再次删除缓存​​

​​二、新增操作​​

一、更新操作

数据库与缓存双写一致性问题普遍出现在更新操作中。

场景1:先更新数据库,再更新缓存

缓存数据是多张数据表联合计算出来的,那么就要求在每次更新以后就要同步计算出新的值,然后更新缓存,这样效率很低。如果是写入场景比较多的业务,那么这种方式会很大程度的降低系统性能。

有一步操作失败,都会出现缓存数据库数据不一致得情况。不管先更新谁可能 会出现此异常情况。

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

如果先更新数据库,再删除缓存的话,还是有可能造成数据库与缓存双写不一致性。

例如,线程A在更新操作成功之前,线程B读取了旧值。线程A在删除缓存之后,线程B又把旧值存入了缓存。这样缓存中存放的是旧值,而数据库中存放的是新值,就出问题了。

场景3:先删除缓存,再更新数据库,最后再次删除缓存

想要解决这个问题,需要在按照下面的步骤。

先删除缓存,再更新数据库,最后休眠后再删除缓存。

在更新操作之前先删除了缓存,用户读取的数据也是数据库的旧值,然后把旧值存放到了缓存中,这没有出现双写一致性问题。

更新数据库成功后,休眠后再次删除缓存,目的是删除其它线程存入的老版本的数据。可把缓存的旧数删除。

当然这种方式会降低系统的吞吐量。另外,需要为缓存设置过期时间。其实从根本上此方案还是没有解决双写一致性的问题,比如有一个线程网络特别差,读取了旧值,然后过了很长时间后,再把旧数据存入了缓存中。。。尴尬,这样就又会出现问题。所以,解决双写一致性性的问题,还是保证原子性,需要使用同步锁。

二、新增操作

新增操作就很简单了,因为之前在缓存中没有数据,所以必须先执行新增操作,然后再把数据给缓存。

整体流程图如下。

三、解决方案

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

解决:我们遇到写请求时,可用先删除缓存数据,再更新数据库,这样不管数据库更新失败还是缓存删除失败,缓存与数据库始终一致。这种方案一般可满足上万人并发操作了,因为删除缓存到更新数据库的时间可以用毫秒计算,正常的并发影响不大。

场景二:读写分离

读请求只访问缓存,写请求只修改数据库和缓存

写请求修改数据库和缓存是事务性动作,如果更新数据库成功,更新缓存失败,则回滚数据库,保证缓存与数据库数据强一致。这样实现了读写分离,不仅提高了读的响应速度,由写请求负责缓存与数据库一致,只有写请求成功才会影响到缓存的内容,时效性大大增强。

方案二:队列存储请求

沿用场景一的解决方案,为解决其缺陷,添加队列,凡是遇到写请求,则将写请求放入队列中,由队列对写请求统一管理,写请求处理成功,则从队列中删除。当有一个读请求过来时,到队列查询,是否有对应的写请求,如果有则放入队列中,等待写请求执行完之后再执行读请求。为防止某个请求阻塞情况,为其设置超时机制或者过期机制。

场景三:访问量大,处理器来不及处理,队列内的请求数量越来越高,则会影响查询效率。使用分布式数据库集群,再加上消息队列(kafka等)

参考文章:​​浅析数据库与缓存的双写一致性问题​​

​​缓存与数据库的数据一致性的解决方案(转)​​

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:VMR9实现放大缩小
下一篇:使用BufferedReader读取TXT文件中数值,并输出最大值
相关文章

 发表评论

暂时没有评论,来抢沙发吧~