redis 缓存穿透和缓存击穿,缓存雪崩的原因及解决方案
缓存穿透
缓存穿透是指查询缓存中没有,数据库中也没有的数据 。从系统层面来看,请求像是穿透了缓存,直接访问数据库。这种情况会给系统带来潜在的风险,如果有大量的请求访问系统数据库中不存在的数据,会直接请求到数据库层导致DB瘫痪从而引起系统故障,服务不可用。
解决这种问题的方法有两个:
1、缓存空对象
缓存空对象是在第一次查询到数据库中也不存在的数据后,将该key与对应的空对象也放入缓存中,只不过设定为较短的失效时间,例如几分钟,这样则可以应对短时间的大量的该key攻击,设置为较短的失效时间是因为该值可能业务无关,存在意义不大,且该次的查询也未必是攻击者发起,无过久存储的必要,故可以早点失效。
2、采用布隆过滤器
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
缓存击穿
缓存击穿是指缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。
解决方案:
采用互斥锁。当大量的请求查询该已失效的key时,我们在第一个请求上用互斥锁锁住该key,其他请求就会锁等待。等第一个请求从DB中查询到了数据,并加入到缓存之后,后面的请求就可以直接从缓存中读取数据了
缓存雪崩
缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重雪崩。
解决方案:
给每个key设置不同的过期时间即可。
千万不要在该奋斗的年纪选择安逸