缓存穿透(访问不存在的key)
含义
请求缓存中不存在的数据,导致所有的请求都转发到数据库上,从而数据库连接异常。
例子
如发起为id值为 -1 的数据或 id 为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大,严重会击垮数据库。
解决办法
- 对请求参数做好校验,不合法的直接return,例如负数id,很大的id,分页参数限制大小等。
- 使用互斥锁,缓存失效时,先加锁,再请求数据库,没有获得锁的暂时休眠。
- 即使数据库返回空,也直接更新缓存为null,然后设置一个较短的过期时间,例如30s。
- 使用布隆过滤器,内部维护所有合法的key,迅速判断出要查找的key是否存在。
缓存击穿(热点key持续被访问)
含义
指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库。
解决办法
- 使用互斥锁,到数据库获取数据,然后设置缓存。(go语言中的singleflight)
- 热点数据设置永不过期,例如电商或者部分app的首页。
缓存雪崩(缓存集体失效)
含义
即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都转到数据库上,从而导致数据库连接异常。
解决办法
- 给缓存失效时间,加上一个随机值,避免集体在同一时间失效。
- 如果Redis是集群部署,将热点数据均匀分布在不同的Redis库中也能避免全部失效的问题。
网友评论