黑马点评项目实战(一)——缓存更新策略
一 缓存更新策略
内存淘汰 | 超时剔除 | 主动更新 | |
---|---|---|---|
说明 | 不用自己维护,利用Redis的内存淘汰机制,当内存不足时自动淘汰部分数据,当内存不足时自动淘汰部分数据。下次查询时更新缓存。 | 给缓存数据添加TTL时间,到期后自动删除缓存。下次查询时更新缓存。 | 编写业务逻辑,在修改数据库的同时,更新缓存。 |
一致性 | 差 | 一般 | 好 |
维护成本 | 无 | 低 | 高 |
业务场景:
- 低一致性需求:使用内存淘汰机制。例如店铺类型的缓存。
- 高一致性需求:主动更新, 并以超时剔除作为兜底方案。例如店铺详情的缓存。
二 主动更新策略
Cache Aside Pattern | Read/Write Through Pattern | Write Behind Caching Pattern |
---|---|---|
由缓存的调用者,在更新数据库的同时更新缓存。 | 缓存与数据库整合为一个服务,由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。 | 调用者只操作缓存,由其他线程异步的将缓存数据持久化到数据库,保证最终一致。 |
调用者需要写一些代码 | 维护一个这样的服务复杂,成本高 | 效率高,但维护异步服务难,可靠性和一致性较差 |
三 操作缓存和数据库
1.删除缓存还是更新缓存?
更新缓存:每次更新数据库都更新缓存,无效写操作较多。
删除缓存:更新数据库时让缓存失效,查询时在更新缓存。√
2.如何保证缓存与数据库的操作的同时成功或失败?
保证原子性。
单体系统:将缓存与数据库操作放在一个事务。
分布式系统:利用TCC等分布式事务方案。
3.先操作缓存还是先操作数据库?(线程安全问题)

由于更新数据库操作比较缓慢,而查询数据库和写入缓存操作很快,线程2很容易趁虚而入,因此该情况发生概率高。

发生该情况需要满足:1.两个线程并行;2.缓存恰好失效;3.在线程1查询缓存和写入缓存两个操作的微秒级空隙内,线程2完成更新数据库和删除缓存操作。因此该情况发生的概率很低。
因此先操作数据库再删除缓存。
四 缓存更新策略的最佳实践方案
- 低一致性需求:使用Redis自带的内存淘汰机制
- 高一致性需求:主动更新, 并以超时剔除作为兜底方案
- 读操作:
- 缓存命中则直接返回
- 缓存未命中则查询数据库,并写入缓存,设定超时时间
- 写操作
- 先写数据库,然后再删除缓存
- 要确保数据库与缓存事务的原子性
- 读操作: