参考:CSDN博客,8种方案
前言
为什么要一致
如果数据不一致,那么业务应用从缓存中读取的数据就不是最新的数据,这会导致严重的错误
数据一致性是什么
缓存中有数据,那么,缓存的数据需要和数据库中的值相同
缓存中本身没有数据,那么,数据库中的值就必须是最新值。
什么原因会导致数据不一致
- redis作为读写缓存的时候
定义:读写缓存,就是先处理缓存,再处理数据库,这里的处理策略有同步和异步两种
- 同步直写策略:写缓存时,也同步写数据库,缓存和数据库中的数据一致,这个时候要考虑添加
事务
,保证缓存和数据库的更新具有原子性 - 异步写回策略:写缓存时不同步写数据库,等到数据从缓存中淘汰时,再写回数据库。使用这种策略时,如果数据还没有写回数据库,
缓存就发生了故障
。那么,此时,数据库就没有最新数据了,如果对数据一致性没这么高,可以采取这种方式解决问题
- redis作为只读缓存的时候
- 如果有数据新增,会直接写入数据库
- 有数据
删改
时,就需要把只读缓存中的数据标记为无效
这样,应用后继在访问这些,些增删改的数据时,因为缓存中没有相应的数据,就会发生缓存缺失。
此时,应用再从数据库中把数据读入缓存,这样后续再访问数据时,就能够直接从缓存中读取了。
对于删改操作,删除缓存和数据库更新需要保证原子性,否则可能会出现数据不一致的问题;
解决方案
1、重试机制
将需要删除的缓存值或更新的数据库值暂存到消息队列中,如果操作失败,可以从队列中重新读取这些值进行操作,成功则从队列中移除,以保证数据库和缓存的一致性。
在线程 A 更新完数据库值以后,我们可以让它先 sleep 一小段时间,再进行一次缓存删除操作。
解决高并发的情况下出现,先删除缓存后,又读到了数据库的旧值,导致缓存起来了旧的值的问题。
2、同步更新
同步更新就是缓存更新和数据库更新放在同一个事务里面,同时完成更改后事务才算提交成功。
3、异步准实时解决方案
更新数据的时候,再同一事务内通过消息队列发布待更新数据的消息,缓存通过订阅消息队列异步更新,但数据库采用同步更新。
- 适合数据量大,性能要求高的情况