Cache Aside Pattern

少于 1 分钟读完

Cache Aside Pattern 是由 facebook 提出的一个广受认可的缓存方案,核心操作有两点:

  • 读请求:先读缓存,如果命中缓存,直接返回结果;否则,访问数据库,并更新缓存;
  • 写请求:先更新数据库,再置缓存失效;

对于写请求为何是置缓存失效,而不是更新缓存?

设想如果将写请求改为先更新数据库,再更新缓存,如果有 A/B 两个请求同时写,由于无法保证时序,可能会出现下面的操作过程,导致数据库和缓存不一致:

  1. A 更新数据库
  2. B 更新数据库
  3. B 更新缓存
  4. A 更新缓存

但实际上,即使先更新数据库,再置缓存失效,也有可能会出现不一致的情况,譬如 A 为读请求,B 为写请求:

  1. A 读缓存不命中,读数据库旧值
  2. B 写数据库为新值
  3. B 设置缓存失效
  4. A 更新缓存为旧值

此时,缓存的数据为旧值,但这种场景发生的概率非常小。因为这个需要发生在读缓存时缓存失效,而且并发着一个写操作。实际上数据库的写操作比读操作慢得多,还要锁表;而读操作必须在写操作前进入数据库操作,并且晚于写操作更新缓存。这些条件都具备的概率不大。

另外,有一些复杂的缓存场景,缓存数据不是简单地从数据库里直接读取出来的,可能需要 join 其他表进行复杂的计算,如果更新很频繁,缓存也会被不必要地频繁更新。

更新时间: