【≅Redis】什么是缓存和数据库双写不一致?怎么解决?

连续写数据库和缓存,但是操作期间,出现并发了,数据不一致了。

通常,更新缓存和数据库有以下几种顺序:

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

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

两个请求同时更新数据,若不使用分布式锁,将无法控制最后缓存的值是什么,即存在并发写的的问题。

先删缓存,再更新数据库

写客户端先删除缓存,但是还未来得及更新数据库;读客户端就查数据库,并设置到缓存中,此时会导致缓存一直是老数据。

有 2 种解决方案:

  • 使用双删,写客户端更新数据库后,再进行一步异步的删除操作,防止客户端读取的时候向缓存设置了旧值。
  • 使用队列,当读客户端发现缓存中这个 key不存在时,将其放入队列,串行执行,必须等到写客户端更新数据库完毕才能读取数据。

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

常用的方案,可能会出现更新数据库之前有瞬间数据不是很及时。同时,如果在更新之前,缓存刚好失效了,读客户端有可能读到旧值,然后在写客户端删除结束后再次设置了旧值,非常巧合的情况。

有 2 个前提条件:缓存在写之前的时候失效,同时,在写客户端删除操作结束后,放置旧数据 —— 也就是读比写慢。甚至有的写操作还会锁表。

这个很难出现,但是如果出现了怎么办?使用双删!记录更新期间有没有客户端读数据库,如果有,在更新完数据库之后,执行延迟删除。

还有一种可能,如果执行更新数据库,准备执行删除缓存时,服务挂了,执行删除失败怎么办???

可以通过订阅数据库的 binlog 来删除

 

posted @ 2023-03-16 13:43  残城碎梦  阅读(36)  评论(0编辑  收藏  举报