Cache Aside Pattern

在《究竟先操作缓存,还是数据库?》,有同学在评论提出,相关方案违背了“Cache Aside Pattern”的原则,故今天聊一聊Cache Aside Pattern。

 

另外,在讨论技术方案时,尽量不说:

“你是错的,应该怎么样”

“facebook不是这样,所以你是错的”

画外音:凭什么facebook就是真理?它的方案只是适合它的业务而已。

说明适用场景,说明来龙去脉,说明前因后果,比具体使用什么方案更重要。

 

什么是“Cache Aside Pattern”?

旁路缓存方案的经验实践,这个实践又分读实践,写实践

 

对于读请求

  • 先读cache,再读db

  • 如果,cache hit,则直接返回数据

  • 如果,cache miss,则访问db,并将数据set回缓存

 

640?wx_fmt=png

如上图:

(1)先从cache中尝试get数据,结果miss了

(2)再从db中读取数据,从库,读写分离

(3)最后把数据set回cache,方便下次读命中

画外音:这一点上,与《究竟先操作缓存,还是数据库?》说的是一致的。

 

对于写请求

  • 淘汰缓存,而不是更新缓存

  • 先操作数据库,再淘汰缓存

 

640?wx_fmt=png

如上图:

(1)第一步要操作数据库,第二步操作缓存

画外音:这一点上,与《究竟先操作缓存,还是数据库?》说的不一致,也是评论反驳比较激烈的地方。

(2)缓存,采用delete淘汰,而不是set更新

画外音:这一点上,与《缓存,究竟是淘汰,还是修改?》说的是一致的。

 

Cache Aside Pattern为什么建议淘汰缓存,而不是更新缓存?

:如果更新缓存,在并发写时,可能出现数据不一致

 

640?wx_fmt=png

如上图所示,如果采用set缓存。


在1和2两个并发写发生时,由于无法保证时序,此时不管先操作缓存还是先操作数据库,都可能出现:

(1)请求1先操作数据库,请求2后操作数据库

(2)请求2先set了缓存,请求1后set了缓存

导致,数据库与缓存之间的数据不一致

 

所以,Cache Aside Pattern建议,delete缓存,而不是set缓存

 

Cache Aside Pattern为什么建议先操作数据库,再操作缓存?

:如果先操作缓存,在读写并发时,可能出现数据不一致


 640?wx_fmt=png

如上图所示,如果先操作缓存。


在1和2并发读写发生时,由于无法保证时序,可能出现:

(1)写请求淘汰了缓存

(2)写请求操作了数据库(主从同步没有完成

(3)读请求读了缓存(cache miss)

(4)读请求读了从库(读了一个旧数据

(5)读请求set回缓存(set了一个旧数据)

(6)数据库主从同步完成

导致,数据库与缓存的数据不一致

 

所以,Cache Aside Pattern建议,先操作数据库,再操作缓存

 

Cache Aside Pattern方案存在什么问题?

:如果先操作数据库,再淘汰缓存,在原子性被破坏时

(1)修改数据库成功了

(2)淘汰缓存失败了

导致,数据库与缓存的数据不一致

 

如何解决这类问题呢?

:详见《究竟先操作缓存,还是数据库?》。

 

任何技术方案的设计,都是折衷。

只有适合的方案,未必有最优的方案。

技术人,不是被动接受,而要主动思考。


640?wx_fmt=png

相关推荐:

进程内缓存,究竟怎么玩?

选redis还是memcache,源码怎么说?

缓存,你真的用对了么?

缓存,究竟是淘汰,还是修改?

缓存,并发更新的大坑?

数据库主从不一致,怎么解?

究竟先操作缓存,还是数据库?


文字很短,希望大家有启示,求帮

  • 12
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值