缓存不一致指的是缓存中的数据与数据库中的数据发生了不一致的情况。一般常用的缓存方案有两种:

方案一:

  • 读的时候,先读缓存,缓存没有的话,读数据库,取出数据后放入缓存,同时返回响应。
  • 更新的时候,先删除缓存,再更新数据库

方案二:

  • 读的时候,先读缓存,缓存没有的话,读数据库,取出数据后放入缓存,同时返回响应。
  • 更新的时候,先更新数据库,再删除缓存

两种方案数据库缓存不一致发生的场景:

  • 方案一:T1删除缓存->T2读缓存(没有),读数据库,并放入缓存->T1更新数据库
  • 方案二:T1读缓存(没有),读数据库->T2更新数据库,删除缓存->T1放入缓存

解决方案:

一般来说,我们对缓存的一致性要求并没有很高,只要求最终一致性,在较短的时间内不一致都是能忍受的。不论是前面哪一种方案,就算发生了,再来一次更新请求只要不发生同样的情况,缓存都会被再次刷成一致的。所以解决方案从简易到复杂就有缓存过期时间兜底,保证“更新数据库、删除缓存”和“读数据库并设置缓存”的之间串行化。

  • 缓存过期时间兜底

    就算更新操作非常少,没有更新操作,也有一个缓存过期时间,在缓存过期之后再次刷新缓存。

  • 读若未命中,将读并放入缓存操作放入该线程的队列;更新操作也放入该线程的队列

  • 更新操作执行后,向MQ发消息置缓存失效。