一起养成写作习惯!这是我参与「掘金日新计划·4月更文挑战」的第6天,点击查看活动详情。
大家都知道缓存是用来干嘛的,加速访问和分散数据库压力,最终给用户端提供的体验就是更快了。其实根本原因还是成本考量,如果有钱数据库全部部署在内存中,或者速度很内存一样快的固态硬盘中,解决一切问题。但目前技术水平和成本控制显然还没达到要求,所以各种内存框架和策略便应运而生。
下面描述一个典型的缓存使用场景(默认使用redis):
- 用户读数据请求
- 首先查缓存中的key能不能命中
- 命中则直接返回
- 每命中则向数据库发起查询并返回结果
- 设置新缓存
上面是读的场景,写的场景如下:
- 写数据请求
- 更新数据库
- 删除缓存
- 重新设置缓存
以上是一个典型的缓存读写的场景,在大部分时候都是稳定运行的。直到有一天有2个用户并发请求一条数据库记录了。
- A请求了数据,从1更新成2
- B请求了同一条数据,从1更新成3
- A重新设置缓存为2
- B重新设置缓存为3
第三步和第四步先后顺序不一定,这时候就是谁后执行完数据就更新成什么。这就带来了不一致的问题。对此我们怎么做呢?我们可以在更新数据时对缓存中的数据进行删除。
- A请求更新数据
- 删除缓存
- B请求更新数据
- 删除缓存
这样无论AB谁先执行,最终都是删除缓存,不会设置不一致的缓存。那么读怎么读呢?
- A请求查询数据
- 缓存命中则返回
- 缓存未命中则查询数据库
- 设置查询后的值
这样数据的一致性则由成熟的数据库来搞定,缓存则不用背负太多压力。