Redis缓存穿透、击穿、雪崩
一、缓存穿透
1.什么是缓存穿透
Redis的缓存穿透是指,外部一个请求访问了一个缓存中没有的key,导致这个请求直接到了mysql上,这就是缓存穿透
2.缓存穿透怎么解决
解决缓存穿透的方式有两种:
第一种:设置布隆过滤器
在设置了布隆过滤器后,请求访问redis之前会先到布隆过滤器,有布隆过滤器来判断redis中有没有这个key
布隆过滤器是怎么处理的呢?
布隆过滤器的底层是一个位数组,里面只存放0和1的数,用来标记key是否存在,
布隆过滤器会将请求的key的哈希值进行多次哈希函数运算,运算的结果会映射到数组上的一个位置
如果每次哈希运算得到的数组位置上的数都为1,那么redis中就很可能有这个key,如果有一处查询
到的数字是0,则redis中一定不会有这个key,过滤器直接拦截请求
第二种 返回一个null值到redis
二、缓存击穿
缓存击穿指在高并发的系统中,一个热点数据缓存过期或者在缓存中不存在,导致大量并发请求直接访问数据库,从而给数据库造成巨大压力,甚至可能引发宕机。
一般来说,解决缓存击穿主要有3个方案:热点数据永不过期,缓存预热以及分布式锁。
1.热点数据永不过期
热点数据可以设置在大促开始前,比如双 11的时候,已经知道哪些数据是热点数据,比如平板、电脑、化妆品等这些数据提前设置一个不可能过期的时间,这样就不会因为 key 过期导致大量请求打到数据库。
2.热点数据预热
这个就是我在数据库和缓存一致性,那里提到的登录接口优化解决方案,提前将一些热点数据写到数据库,避免海量请求第一次访问热点数据从数据库读取数据的流程。
组合方案:缓存预热 +提前预热
通过以上两个方案组合,保证热点数据在对应的期间不过期,然后通过后台任务的方案设置过期时间,从而降低Redis 存储压力。
4.通过分布式锁(双重判定锁)
这里的方案是分布式限制访问数据库的请求,然后为了提高效率,使用双重判定锁来判断缓存是否已经加载了对应数据,减少对于数据库的访问。
三、缓存雪崩
缓存雪崩是指在某个时间点,大量缓存同时失效或被清空,导致大量请求直接打到数据库或后端系统,造成系统负载激增 甚至引发系统崩溃。这通常是由于缓存中的大量数据在同一时间失效引起的。想象一个电商系统,用户量很大,假设某一系列的商品缓存突然同一时间失效,那就会造成我们的缓存雪崩,导致服务全部打到了数据库,引发严重后果。
解决办法
分布式锁
使用锁机制来避免多个相同的请求同时访问数据库,只让一个或少量请求去加载数据,其他请求等待。
缓存预热
系统使用冷启动,提前将热门数据加载到缓存中,避免高并发访问的时候出现数据库大量访问的情况。
热点数据永不过期
与上面一样,针对热点数据设置永不过期即可,然后搭配 Redis 的 LRU 机制实现内存淘汰。
随机设置缓存失效时间
采用随机分布的方式设置缓存失效时间,或者使用带有随机偏移的失效时间,减少批量过期的概率