缓存穿透
当查询Redis中没有的数据时,该查询会下沉到数据库层,同时数据库层也没有该数据,当这种情况大量出现或被
恶意攻击时,接口的访问全部透过Redis访问数据库,而数据库中也没有这些数据,我们称这种现象为"缓存穿透"。
缓存穿透会穿透Redis的保护,提升底层数据库的负载压力,同时这类穿透查询没有数据返回也造成了网络和计算
资源的浪费。
解决方案:
1、在接口访问层对用户做校验,如接口传参、登陆状态、n秒内访问接口的次数;
2、利用布隆过滤器,将数据库层有的数据key存储在位数组中,以判断访问的key在底层数据库中是否存在;
布隆过滤器
我们可以先将数据库中数据的key存储在布隆过滤器的位数组中,每次客户端查询数据时先访问Redis:
如果Redis内不存在该数据,则通过布隆过滤器判断数据是否在底层数据库内;
如果布隆过滤器告诉我们该key在底层库内不存在,返回null给客户端即可,避免了查询底层数据库的动作;
如果布隆过滤器告诉我们该key极有可能在底层数据库内存在,那么将查询下推到底层数据库即可;
(有一定概率错误)
缓存击穿
底层数据库有数据而缓存内没有数据。当热点数据key从缓存内失效时,大量访问同时请求这个数据,就会将查询下沉
到数据库层,此时数据库层的负载压力会骤增,我们称这种现象为"缓存击穿"。
解决方案:
1、延长热点key的过期时间或者设置永不过期,如排行榜,首页等一定会有高并发的接口;
2、利用互斥锁保证同一时刻只有一个客户端可以查询底层数据库的这个数据,一旦查到数据就缓存至Redis内,
避免其他大量请求同时穿过Redis访问底层数据库;
缓存雪崩
缓存雪崩是缓存击穿的"大面积"版,缓存击穿是数据库缓存到Redis内的热点数据失效导致大量并发查询穿过redis
直接击打到底层数据库,而缓存雪崩是指Redis中大量的key几乎同时过期,然后大量并发查询穿过redis击打到底
层数据库上,此时数据库层的负载压力会骤增,我们称这种现象为"缓存雪崩"。事实上缓存雪崩相比于缓存击穿更容
易发生,对于大多数公司来讲,同时超大并发量访问同一个过时key的场景的确太少见了,而大量key同时过期,大量
用户访问这些key的几率相比缓存击穿来说明显更大。
解决方案:
1、在可接受的时间范围内随机设置key的过期时间,分散key的过期时间,以防止大量的key在同一时刻过期;
2、对于一定要在固定时间让key失效的场景(例如每日12点准时更新所有最新排名),可以在固定的失效时间
时在接口服务端设置随机延时,将请求的时间打散,让一部分查询先将数据缓存起来;
3、延长热点key的过期时间或者设置永不过期,这一点和缓存击穿中的方案一样;