缓存淘汰
- 缓存通常具有时效性,就是说一般缓存的数据都会有过期失效的时间
- 缓存淘汰的策略应该是:先淘汰缓存,再读写数据库
缓存穿透
- 含义:如果访问缓存中一定不存在的某个 key,无疑会穿透缓存,相关请求会转移到 DB,如果高并发下访问这个 key(也可能是恶意攻击),有可能导致 DB 负载过高奔溃
-
解决办法:
bitmap
记录所有存在的 key:请求接入后先查询bitmap
,如果请求的 key 不存在,则直接返回空,不进入 DB- 缓存值为空的所有 key,缺点是可能会浪费空间
缓存雪崩
- 定义:对于已经缓存的大量 key,如果某一时间这些键值全部过期,则请求的流量会在过期瞬间全部转移到 DB,导致数据库奔溃
-
解决办法:
- 缓存过期时间加随机数,保证缓存的过期时间随机分布
- 加锁请求或将请求加入队列:保证串行请求,缺点是并发性低
缓存击穿
- 定义:高并发访问的情况下,对于某个热点 key,在缓存过期瞬间大量请求击穿缓存直接进入 DB
- 与缓存雪崩的区别:缓存雪崩针对大量 key 同时过期的情况,而缓存击穿则针对单个 key 被高并发访问的情形
-
解决办法:
- 加互斥锁(Redis 中
setnx
):如果获取到缓存为空,不立即进入 DB,先获取锁,成功则进入 DB 获取数据并更新缓存,否则继续 get 缓存 - 设置永不过期的 key
- 额外缓存超时时间:即额外设置 value 为指定 key 的过期时间的缓存,此 value 必须小于指定键的实际过期时间,额外再开启一个线程不断检查 value 是否即将过期,如果发现 value 已经过期(此时特定的键还未过期),则马上更新 key 对于的缓存
- 请求熔断:如果检测到 DB 请求量达到指定的上限,则拒绝访问请求
- 加互斥锁(Redis 中