欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > 数据库 >内容正文

数据库

09丨缓存异常:如何解决缓存和数据库的数据不一致问题

发布时间:2024/10/6 数据库 37 豆豆
生活随笔 收集整理的这篇文章主要介绍了 09丨缓存异常:如何解决缓存和数据库的数据不一致问题 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1.缓存和数据库的数据不一致是如何发生的?

  首先,我们得清楚“数据的一致性”具体是啥意思。其实,这里的“一致性”包含了两种情况:

  • 缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
  • 缓存中本身没有数据,那么,数据库中的值必须是最新值。

  对于读写缓存来说,如果要对数据进行增删改,就需要在缓存中进行,同时还要根据采取的写回策略,决定是否同步写回到数据库中。
同步直写策略:写缓存时,也同步写数据库,缓存和数据库中的数据一致;

  • 异步写回策略:写缓存时不同步写数据库,等到数据从缓存中淘汰时,再写回数据库。使用这种策略时,
  • 如果数据还没有写回数据库,缓存就发生了故障,那么,此时,数据库就没有最新的数据了。

2. 如何解决数据不一致问题?

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

  当有大量并发请求时,应用还是有可能读到不一致,按照不同的删除和更新顺序,分成两种情况来看。在这两种情况下,我们的解决方法也有所不同。
情况一:先删除缓存,再更新数据库。
  假设线程 A 删除缓存值后,还没有来得及更新数据库(比如说有网络延迟),线程 B 就开始读取数据了,那么这个时候,线程 B 会发现缓存缺失,就只能去数据库读取。这会带来两个问题:

  • 线程 B 读取到了旧值;
  • 线程 B 是在缓存缺失的情况下读取的数据库,所以,它还会把旧值写入缓存,这可能会导致其他线程从缓存中读到旧值。

    在线程 A 更新完数据库值以后,我们可以让它先 sleep 一小段时间,再进行一次缓存删除操作。
    情况二:先更新数据库值,再删除缓存值。
      如果线程 A 删除了数据库中的值,但还没来得及删除缓存值,线程 B 就开始读取数据了,那么此时,线程 B 查询缓存时,发现缓存命中,就会直接从缓存中读取旧值。不过,在这种情况下,如果其他线程并发读缓存的请求不多,那么,就不会有很多请求读取到旧值。而且,线程 A 一般也会很快删除缓存值,这样一来,其他线程再次读取时,就会发生缓存缺失,进而从数据库中读取最新值。所以,这种情况对业务的影响较小。

      对于读写缓存来说,如果我们采用同步写回策略,那么可以保证缓存和数据库中的数据一致。只读缓存的情况比较复杂,我总结了一张表,以便于你更加清晰地了解数据不一致的问题原因、现象和应对方案。

3. 如何解决缓存雪崩、击穿、穿透

总结

以上是生活随笔为你收集整理的09丨缓存异常:如何解决缓存和数据库的数据不一致问题的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。