缓存
2026年2月15日大约 4 分钟
缓存
缓存(Cache)就是数据交换的缓冲区,是用来临时存储数据的地方。它可以提高数据访问的速度,减少对数据库的访问次数,从而提升系统的性能。
- 缓存的优点:
- 降低后端负载。
- 提高读写效率。
- 缓存的缺点:
- 数据一致性问题:缓存中的数据可能与数据库中的数据不一致。
- 代码复杂度增加。
- 运维复杂度增加。
缓存更新策略
缓存更新策略是为了解决数据一致性问题而设计的。常见的缓存更新策略有:
| 内存淘汰 | 超时剔除 | 主动更新 | |
|---|---|---|---|
| 说明 | Redis自带的内存淘汰机制,当内存不足时,Redis会根据一定的策略淘汰一些数据。下次查询时才更新缓存。 | 给缓存设置一个过期时间,当缓存过期后,下一次查询时才更新缓存。 | 当修改数据库时,主动更新缓存。 |
| 一致性 | 差 | 一般 | 好 |
维护成本 | 无 | 低 | 高 |
根据实际的业务场景分为:
- 低一致性需求:使用内存淘汰机制或超时剔除策略。
- 高一致性需求:使用主动更新策略,并使用超时剔除策略兜底。
主动更新策略
主动更新策略又分不同的模式,这里使用缓存调用者来更新缓存的模式。
- 读操作:
- 先查询缓存,如果缓存命中,直接返回数据。
- 缓存未命中,查询数据库,并写入缓存,设置过期时间,然后返回数据。
- 写操作:
- 先写数据库,然后更新缓存。
缓存穿透
缓存穿透是指查询一个不存在的数据,导致每次查询都直接访问数据库,从而造成数据库压力过大,甚至崩溃。
解决缓存穿透的方法
- 缓存空对象:当查询数据库后发现数据不存在时,可以在缓存中存储一个空对象,并设置一个较短的过期时间。这样下次查询同样的数据时,就会命中缓存,避免访问数据库。
- 优点:简单易实现。
- 缺点:可能会占用一定的缓存空间。
- 使用布隆过滤器:在查询数据库之前,先使用布隆过滤器判断数据是否存在,如果不存在,直接返回,不访问数据库。
- 优点:节省缓存空间。
- 缺点:布隆过滤器有一定的误判率,可能会误判存在的数据为不存在。

图:缓存穿透的两种解决方法
缓存雪崩
缓存雪崩是指在某个时间点,大量的缓存同时失效或Redis宕机,导致大量的请求直接访问数据库,从而造成数据库压力过大,甚至崩溃。
图:缓存雪崩的两种情况
解决缓存雪崩的方法
- 设置不同的过期时间:为不同的缓存设置不同的过期时间,避免大量缓存同时失效。
- 利用Redis集群:使用Redis集群来分散缓存压力,避免单点故障。
- 给缓存业务添加降级限流策略:当缓存失效时,给业务添加降级限流策略,避免大量请求直接访问数据库。
- 给业务添加多级缓存。
缓存击穿(热点key问题)
缓存击穿也被称作热点key问题,是指高并发访问并且缓存重建业务复杂的key失效,导致大量请求直接访问数据库,从而造成数据库压力过大,甚至崩溃。
图:缓存击穿的示例
解决缓存击穿的方法
- 互斥锁:当缓存未命中,查询数据库前,先获取一个互斥锁,只有获取到锁的请求才去访问数据库并更新缓存,其他请求等待锁释放后再查询缓存。
- 逻辑过期:在缓存中存储一个过期时间。当查询缓存时,如果发现数据过期了,但不立即删除缓存,先获取一个互斥锁,再异步更新缓存,同时继续返回旧数据。这样可以避免大量请求同时访问数据库。

图:缓存击穿的示例

图:缓存击穿的解决方法的优缺点