当前位置: 首页 > 科技观察

CacheAsidePattern(缓存模式)分析

时间:2023-03-11 22:10:41 科技观察

在《究竟先操作缓存,还是数据库?》中,有同学评论说相关方案违背了“CacheAsidePattern”的原则,那么今天就来聊聊CacheAsidePattern。另外,在讨论技术方案时,尽量不要说:“你错了,你该怎么办?”“Facebook不是这样的,所以你错了”画外音:为什么Facebook是真相?它的解决方案只适合它的业务。说明适用场景,说明来龙去脉,说明前因后果,比具体使用什么方案更重要。什么是“缓存备用模式”?答:绕过缓存方案的经验实践,本次实践分为阅读实践和写作实践。对于读请求,先读cache,再读db。如果缓存命中,则直接返回数据。如果缓存未命中,将访问数据库并将数据设置回缓存。从db读取数据,从library读写,读写分离***将数据回cache,下次读取***画外音:这点和《究竟先操作缓存,还是数据库?》说的一致。对于写请求清除缓存,不是更新缓存,而是先操作数据库,再清除缓存,如上图所示:(1)第一步操作数据库,第二步操作缓存画外音:这点和《究竟先操作缓存,还是数据库?》说的不一致,也是评论反驳比较激烈的地方。(2)缓存,用delete消除而不是set更新画外音:这点和《缓存,究竟是淘汰,还是修改?》说的一致。为什么CacheAsidePattern建议消除缓存而不是更新缓存?答:如果更新了缓存,并发写入时可能会出现数据不一致的情况。如上图,如果使用setcache。当发生1和2的两次并发写入时,由于时序无法保证,无论是先操作缓存还是先操作数据库,都可能出现:请求1先操作数据库,再请求2操作数据库数据库。请求2先设置缓存,请求1后设置缓存,导致数据库和缓存数据不一致。因此,CacheAsidePattern建议删除缓存而不是设置缓存。为什么CacheAsidePattern建议先操作数据库,再操作缓存?答:如果先操作缓存,读写并发的时候可能会出现数据不一致的情况。如上图,如果先操作缓存。当发生1和2并发读写时,由于不能保证时序,可能会出现:写请求清除缓存写请求操作数据库(主从同步未完成)读请求读取缓存(缓存miss)读请求读取从库(读取了一个旧数据)读取请求设置回缓存(设置了一个旧数据)数据库主从同步完成,导致数据库和从库数据不一致缓存。所以CacheAsidePattern建议先操作数据库,再操作缓存。CacheAsidePattern解决方案有什么问题?答:如果先操作数据库,再清除缓存,破坏原子性时:修改数据库成功,清除缓存失败。导致数据库和缓存中的数据不一致。如何解决这类问题?答:详见《究竟先操作缓存,还是数据库?》。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文