redis与数据库数据不一致解决方案

目前项目中,缓存应用广泛,一些故障或者并发问题可能会导致缓存信息和数据库不一致,从而导致脏数据的产生,目前我所了解的两种方案:延迟双删和异步更新缓存都能有效保证数据的一致性。

Redis与数据库一致性问题分析
缓存(Redis)和数据库间的数据一致性–笔记

异步更新缓存:通过使用mq来保证缓存更新的顺序进行,但是这样复杂性就提升了,可用性也降低了。
延迟双删:并发操作多,集群数量大的情况,这个方案不好,且会占用很多时间,也很难保持数据一致

因此我思考是不是从延时双删上做一个扩展,并不用每次都要对缓存进行删除。这里我考虑可以使用一个中间状态和版本号来控制并发问题。
在这里插入图片描述

1.先校验是否有缓存存在,如果没有缓存存在,会对缓存进行一个添加,这里是为了防止在数据更新期间,如果有查询操作进来“捣乱”,我们可以给一个临时的缓存,防止缓存命中不到时,来更新一个旧的且过期时间较长的缓存。同时这里也保证了数据库读写分离架构会出现的问题:主库更新完成后,从库却未及时更新,查询时通过从库去查询,然后缓存了一个脏数据。如果不太理解可以通过延时双删时主从架构出现问题的情况来考虑
(1)请求A进行写操作,删除缓存
(2)请求A将数据写入数据库了,
(3)请求B查询缓存发现,缓存没有值
(4)请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值
(5)请求B将旧值写入缓存
(6)数据库完成主从同步,从库变为新值
2. 这里对状态判断缓存状态是否为"DEL",这是一个数据正在更新的标志,如果不是这个状态说明缓存key的数据没有别的操作在修改,我们在最后缓存更新时,可以通过版本号的对比来判断是对缓存进行更新还是删除。但是当状态为"DEL"时我们可以认为有并发操作对同一个key的缓存数据进行操作,这时我们来生成一个新的random版本号,进行缓存更新,这样在最后的缓存更新时,不用考虑哪一个操作先执行完,直接进行删除。这也是延迟双删保证缓存与数据库一致的想法。

这是我对缓存一致性解决方案想法的一个扩展,当然这样做对缓存的性能要求提高了,如果有更好的想法,希望能够告知。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐