黑马点评项目实战(一)——缓存更新策略

一 缓存更新策略

内存淘汰 超时剔除 主动更新
说明 不用自己维护,利用Redis的内存淘汰机制,当内存不足时自动淘汰部分数据,当内存不足时自动淘汰部分数据。下次查询时更新缓存。 给缓存数据添加TTL时间,到期后自动删除缓存。下次查询时更新缓存。 编写业务逻辑,在修改数据库的同时,更新缓存。
一致性 一般
维护成本

业务场景:

  • 低一致性需求:使用内存淘汰机制。例如店铺类型的缓存。
  • 高一致性需求:主动更新, 并以超时剔除作为兜底方案。例如店铺详情的缓存。

二 主动更新策略

Cache Aside Pattern Read/Write Through Pattern Write Behind Caching Pattern
由缓存的调用者,在更新数据库的同时更新缓存。 缓存与数据库整合为一个服务,由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。 调用者只操作缓存,由其他线程异步的将缓存数据持久化到数据库,保证最终一致。
调用者需要写一些代码 维护一个这样的服务复杂,成本高 效率高,但维护异步服务难,可靠性和一致性较差

三 操作缓存和数据库

1.删除缓存还是更新缓存?

更新缓存:每次更新数据库都更新缓存,无效写操作较多。

删除缓存:更新数据库时让缓存失效,查询时在更新缓存。√

2.如何保证缓存与数据库的操作的同时成功或失败?

保证原子性。

单体系统:将缓存与数据库操作放在一个事务。

分布式系统:利用TCC等分布式事务方案。

3.先操作缓存还是先操作数据库?(线程安全问题)

image-20250215150429038

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

image-20250215150750330

发生该情况需要满足:1.两个线程并行;2.缓存恰好失效;3.在线程1查询缓存和写入缓存两个操作的微秒级空隙内,线程2完成更新数据库和删除缓存操作。因此该情况发生的概率很低。

因此先操作数据库再删除缓存。

四 缓存更新策略的最佳实践方案

  1. 低一致性需求:使用Redis自带的内存淘汰机制
  2. 高一致性需求:主动更新, 并以超时剔除作为兜底方案
    • 读操作:
      • 缓存命中则直接返回
      • 缓存未命中则查询数据库,并写入缓存,设定超时时间
    • 写操作
      • 先写数据库,然后再删除缓存
      • 要确保数据库与缓存事务的原子性