缓存更新策略

数据写到缓存无非两种情况。

  1. 应用读缓存没有命中时,会去读db然后再将读取的数据写到缓存。
  2. 应用更新db中数据后,再更新缓存。
    所以更新缓存的方式可以分为以下几种:

1、先删缓存再更新db

对同一个key并发读写缓存可能导致缓存脏数据,一直到下一次数据更新或者缓存失效。

更新查询
删除缓存
读缓存(空)
读db(a=1)
更新db(a=100)
写缓存

如上图,缓存a=1,但是数据库a=100。

2、先更新db再删缓存

查询缓存,没有命中,从db读数据后写入缓存,也可能导致缓存脏数据。

更新查询
读缓存(空)
读db(a=1)
更新db(a=100)
删缓存
写缓存

如上图,缓存a=1,但是db中a=100,这种方式也会出现缓存脏数据,但是被广泛使用,因为这种缓存更新方式出现脏数据的条件为:

  1. 读缓存没有命中。
  2. 读缓存时同时更新key。
  3. 对同一条记录写db比读db先完成。
  4. 读db比写db先开始,后结束。
    一般情况下db的写比读要慢。所以上述四个条件同时发生的概率比较低。

3、先更新db再更新缓存

这种情况也会出现缓存脏数据的情况。
当有两个更新操作并发执行时。下图为可能情况之一。

更新 操作1更新 操作2
写db(a=1)
写db(a=100)
更新缓存(a=100)
更新db(a=1)

这种方式的优势在于主动准备好缓存的数据,可以避免缓存穿透。

4、先更新db,需要时才同步更新缓存(read/write though)

和第三种方式的不同之处在于,更新数据时,当数据被写入db后,缓存为空不主动更新缓存。
当对同一个key读/写缓存并发执行时,下图为可能情况之一。

更新查询
读缓存(空)
读db(a=100)
写db(a=1)
缓存为空不主动更新缓存
更新缓存(a=100)

此时缓存的数据为脏数据。

5、write back

更新数据时只写入缓存,后台线程负责将数据写入db。类似于linux os的page cache,需要记录那些被更新过,那些需要持久化,实现较为复杂。

小结

类似数据库的事务隔离,缓存的更新和数据库的更新很难用事务的方法将两个操作合并为一个原子操作,所以理论上无法避免在缓存更新时出现缓存脏数据的情况,但是先更新db再删缓存的cache aside模式出现缓存脏数据的概率比较低。

参考

https://coolshell.cn/articles/17416.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值