0
点赞
收藏
分享

微信扫一扫

缓存一致性解决方法

对于缓存 + 数据库读写,有个经典的Cache Aside Pattern:
读取:先读取缓存,缓存里没有,读取数据库,然后返回响应,顺便保存缓存:
缓存一致性解决方法_更新数据
更新:先更新数据库,然后删除缓存
缓存一致性解决方法_数据库_02

为什么是删除缓存而不是更新缓存?

  • 并发情况下更新缓存可能会带来更多问题,直接删除缓存更加稳妥
  • 缓存更新消耗更多资源,直接删除,用时再从数据库读取,写进缓存,更省性能

先更新数据库,然后删除缓存

一致性问题

假设更新数据库成功,接下来还没来得及删除缓存,或者删除缓存失败,此时其他线程进来读的就是脏数据。
缓存一致性解决方法_缓存_03
既然删除缓存失败会导致脏数据,那么就得想办法能让它删除成功。一般来说有两种方法:消息队列重试机制监听binlog异步删除
消息队列重试机制
如果删除缓存失败,向消息队列发送消息,把删除失败的key放进去,消费消息队列,获取要删除的key,然后重试删除。
缓存一致性解决方法_消息队列_04

这样做的话引入了消息队列,对现有的业务造成了入侵,复杂度升高

监听binlog异步删除
用一个服务去监听数据库的binlog,获取需要操作的数据。然后用另外一个服务获取订阅程序传来的信息,进行缓存删除操作。这样对于业务的入侵就小了。
缓存一致性解决方法_更新数据_05

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

在并发情况下,先删除缓存,再更新数据库,此时数据库还未更新成功,这时有其他线程进来,读取缓存,缓存不存在,读取数据库,读取的是就是旧值,此时缓存不一致就发生了
解决方案便是延时双删
就是在删除缓存,更新数据库之后,休眠一段时间后,再次删除缓存。延时删除之后,就把缓存里面缓存的旧值删除了。
再有请求进来,就是读取数据库里的新值,再把新值保存进缓存。如果第二次删除也失败,那么就再次重试。

缓存一致性解决方法_缓存_06 图1 缓存不一致


缓存一致性解决方法_更新数据_07图2 延时双删



举报

相关推荐

0 条评论