关于缓存

缓存模式(Cache Aside Pattern)

什么是”Cache Aside Pattern”?

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

对于读请求
  • 先读cache,再读db
  • 如果,cache hit,则直接返回数据
  • 如果,cache miss,则访问db,并将数据set回缓存

如上图:

  1. 先从cache中尝试get数据,结果miss了
  2. 再从db中读取数据,从库,读写分离
  3. 最后把数据set回cache,方便下次读命中
对于写请求
  • 淘汰缓存,而不是更新缓存
  • 先操作数据库,再淘汰缓存

如上图:

  1. 第一步要操作数据库,第二步操作缓存
  2. 缓存,采用delete淘汰,而不是set更新

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

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

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

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

  1. 请求1先操作数据库,请求2后操作数据库
  2. 请求2先set了缓存,请求1后set了缓存

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

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

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

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

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

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

  1. 写请求淘汰了缓存
  2. 写请求操作了数据库(主从同步没有完成)
  3. 读请求读了缓存(cache miss)
  4. 读请求读了从库(读了一个旧数据)
  5. 读请求set回缓存(set了一个旧数据)
  6. 数据库主从同步完成
    导致,数据库与缓存的数据不一致。

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

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

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

  1. 修改数据库成功了
  2. 淘汰缓存失败了

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

原文来自58沈剑:
https://cloud.tencent.com/info/5e258c6f840423de68eda937db3e1c90.html

缓存问题

用一张脑图总结如下:

坚持原创技术分享,您的支持将鼓励我继续创作!