缓存异常(上):如何解决缓存和数据库的数据不一致问题?

184 阅读1分钟

重试机制

具体来说,可以把要删除的缓存值或者是要更新的数据库值暂存到消息队列中(例如使用 Kafka 消息队列)。当应用没有能够成功地删除缓存值或者是更新数据库值时,可以从消息队列中重新读取这些值,然后再次进行删除或更新。

image.png

高并发情形

刚刚说的是在更新数据库和删除缓存值的过程中,其中一个操作失败的情况,实际上,即使这两个操作第一次执行时都没有失败,当有大量并发请求时,应用还是有可能读到不一致的数据。

我们按照不同的删除和更新顺序,分成两种情况来看。在这两种情况下,我们的解决方法也有所不同。

情况一:先删除缓存,再更新数据库。

image.png

解决方案:

在线程 A 更新完数据库值以后,我们可以让它先 sleep 一小段时间,再进行一次缓存删除操作。

下面的这段伪代码就是“延迟双删”方案的示例:

redis.delKey(X)
db.update(X)
Thread.sleep(N)
redis.delKey(X)

情况二:先更新数据库值,再删除缓存值。

image.png

在这种情况下,如果其他线程并发读缓存的请求不多,那么,就不会有很多请求读取到旧值。而且,线程 A 一般也会很快删除缓存值,这样一来,其他线程再次读取时,就会发生缓存缺失,进而从数据库中读取最新值。所以,这种情况对业务的影响较小。

总结

image.png


此文章为8月Day19学习笔记,内容来源于极客时间《redis核心技术与实战》