[redis] redis缓存雪崩、缓存击穿和缓存穿透
redis作为一种NoSQL数据库,其作用是将数据库数据缓存在内存中,向到来的请求快速返回结果,减轻数据库压力。
即:从数据库读取数据后,将数据缓存到内存中,下次读取直接从内存获得并返回,可以有效降低数据库请求(降低磁盘读取需求)。
在大量请求到来时,可能产生三种问题:
1. 缓存雪崩
某个时刻缓存大量失效(通常是因为设置了相同的数据过期时间)。此时到来的大量请求被直接发送到数据库上,造成巨大压力。
解决方案:
1)加锁/队列;针对某一数据的短期重复请求,不把所有请求全部处理,而是以队列形式处理。
2)缓存标记;给缓存的数据增加标记;当请求的缓存数据失效,则更新缓存(预先更新缓存)。
3)错开缓存时间;设置过期时间时,增加一个随机数。
2. 缓存击穿
当大量并发用户一同请求一个缓存中不存在但数据库中存在的数据,会导致对数据库短时间的大量请求,进而引起数据库压力增大。
看起来就是短时间内缓存被“击穿”了。
解决方案:
1)设置热点数据不过期。
2)增加互斥锁,仅让一个线程去数据库取数据到缓存,避免重复请求数据库。
3. 缓存穿透
对于缓存和数据库中都不存在的数据,有用户不断发起请求。
因为缓存的基本机制,对于这种情况,每一次缓存都会向数据库执行查询并得到空值。表现为用户绕过了缓存直接给到数据库压力。
解决方案:
1)接口层进行校验,过滤无效请求。
2)对于不存在的数据缓存key-null。
3)设置布隆过滤器(由bitmap实现)判断数据是否存在。