缓存击穿、缓存穿透、缓存雪崩解决方案

mac2025-07-14  9

1.缓存击穿【Cache breakdown】

对于某些具有过期时间的key,如果这些键可以在某个时间点并发地访问,那么它就是一个非常“hot”的数据。

而当该缓存在某个时间点过期时,就在此时,有很多对这个键的并发请求。这些请求发现缓存过期,,通常直接在后端加载数据并将其设置回缓存。此时,大型并发请求可能会立即淹没后端DB。

解决方案
互斥锁:业界更常见的做法是使用互斥锁。简单地说,当缓存失效时,并不是立即加载数据库,而是先设置一个互斥锁(该互斥锁可以是Java的内存锁,也可以是通过Redis提供的SETNX实现一个互斥锁),当互斥锁获取成功,则执行DB查询并缓存

SETNX是“set if not exists”的缩写,它只在key不存在的时候才会设置缓存,可以用来实现锁的效果。

2. 缓存穿透【Cache penetration】

缓存渗透指的是在查询某个不存在的数据时,因为只有在DB数据命中时,才会写入缓存,而当DB层数据未命中,我们并不会缓存,导致对不存在的数据的每次请求,都将直接到DB层查询,而失去了缓存的意义。当流量大时,DB可能会挂起。如果有人经常使用不存在的密钥攻击我们的应用程序,这就是一个漏洞。

解决方案
通过Bloom 过滤器拦截。缓存空结果,但是缓存的有效时间很短,不超过5分钟。

3. 缓存雪崩【Cache avalanche】

缓存雪崩【Cache avalanche】指的是由于使用相同的过期时间来设置缓存,而导致的缓存失效雪崩,所有请求都被转发给DB。DB的瞬时压力过大。

解决方案
使用锁或者队列,实现单线程缓存写入,从而避免在发生故障时大量并发请求落在底层存储系统上。向缓存的过期时间添加一个随机值,比如1-5分钟。
最新回复(0)