大萧条时期的野蛮生长——缓存策略

140 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划·4月更文挑战」的第6天,点击查看活动详情

大家都知道缓存是用来干嘛的,加速访问和分散数据库压力,最终给用户端提供的体验就是更快了。其实根本原因还是成本考量,如果有钱数据库全部部署在内存中,或者速度很内存一样快的固态硬盘中,解决一切问题。但目前技术水平和成本控制显然还没达到要求,所以各种内存框架和策略便应运而生。

下面描述一个典型的缓存使用场景(默认使用redis):

  1. 用户读数据请求
  2. 首先查缓存中的key能不能命中
  3. 命中则直接返回
  4. 每命中则向数据库发起查询并返回结果
  5. 设置新缓存

上面是读的场景,写的场景如下:

  1. 写数据请求
  2. 更新数据库
  3. 删除缓存
  4. 重新设置缓存

以上是一个典型的缓存读写的场景,在大部分时候都是稳定运行的。直到有一天有2个用户并发请求一条数据库记录了。

  1. A请求了数据,从1更新成2
  2. B请求了同一条数据,从1更新成3
  3. A重新设置缓存为2
  4. B重新设置缓存为3

第三步和第四步先后顺序不一定,这时候就是谁后执行完数据就更新成什么。这就带来了不一致的问题。对此我们怎么做呢?我们可以在更新数据时对缓存中的数据进行删除。

  1. A请求更新数据
  2. 删除缓存
  3. B请求更新数据
  4. 删除缓存

这样无论AB谁先执行,最终都是删除缓存,不会设置不一致的缓存。那么读怎么读呢?

  1. A请求查询数据
  2. 缓存命中则返回
  3. 缓存未命中则查询数据库
  4. 设置查询后的值

这样数据的一致性则由成熟的数据库来搞定,缓存则不用背负太多压力。