解决缓存与数据库的数据一致性问题
2021-07-02 本文已影响0人
站得高看得远
解决缓存与数据库的数据一致性问题
问题分析
- 多个写请求执行顺序不同导致脏数据
- 存在更新缓存请求和读缓存请求,读缓存请求发生在更新缓存请求前,这样使得读缓存请求读取到旧数据
- 数据库读写分离,主数据库更新完,需要一定时间后从数据库才能被更新完成
不同搭配分析
更新数据库、更新缓存、删除数据库、删除缓存有以下四种搭配
- 先更新数据库,后更新缓存
- 有两个写请求,写请求A和写请求B,A先更新数据库,B后更新数据库,但是可能会出现B会先更新缓存,A后更新缓存,这样会导致缓存中保存的是旧数据
- 更新缓存失败也可能导致保存的是旧数据
- 先更新缓存,后更新数据库
- 这个搭配肯定不行。原因是更新缓存成功,更新数据库出现异常了,导致缓存数据与数据库数据完全不一致
- 先更新数据库,后删除缓存
- 更新数据库后删除缓存时,删除缓存失败也有可能导致缓存是旧数据
- 先删除缓存,后更新数据库
- 删除缓存后,更新数据库前假如有读请求,这时读请求会读取到旧数据
正确的解决方案
- 不推荐:使用分布式锁,读请求和写请求都要获得锁之后才能进一步操作,但是这样效率极低,但一致性得到保障
-
先更新数据库,异步删除缓存,删除失败后,继续异步重试,或者将操作放到消息队列中,再进行删除操作。(如果数据库是读写分离的,那么删除缓存时需要延迟删除,否则可能会在删除缓存时,从库还没有收到更新后的数据,其他读请求就去从库读到旧数据然后设置到缓存中。)
-
业务项目直接更新数据库,然后其他项目订略binlog,接收到更新数据库操作的消息后,更新缓存,更新缓存失败时,新建异步线程去重试或者将操作发到消息队列,然后后续进行处理。但是这种方案更新mysql后还是有一定延迟,缓冲中才是新值。