前提
redis作为缓存使用时,在高并发下场景下发生缓存击穿、缓存穿透、缓存雪崩
缓存击穿
缓存击穿:
缓存击穿指的查询某一热点数据,但由于该数据在某一时刻过期失效,导致请求直接打到数据库,引发数据库负载激增。
解决方案:使用setnx分布式锁,在加锁了之后,由于锁会有过期时间,然而又不能保证,锁一定不会在执行结束过后过期,
那么,我们就可以采用多线程的方案,让锁每隔一定时间,就重新设置它的超时时间。
缓存穿透:在某个时间点,缓存中的大量数据同时过期失效,导致大量请求直接打到数据库上,引发数据库压力极速增加,甚至崩溃。
解决方案:使用布隆过滤器:布隆过滤器用于快速判断一个元素是否存在于集合中。部署在Redis的前面,去拦截数据,减少对Redis的冲击,将所有可能的查询值都加入布隆过滤器,当一个查询请求到来时,先经过布隆过滤器判断是否存在于缓存中,避免不必要的数据库查询。缺点是不能修改数据进行修改,可以是使用布谷鸟过滤器
缓存雪崩
缓存雪崩:在某个时间点,缓存中的大量数据同时过期失效,大量请求直接打到数据库,从而引发数据库压力激增,甚至崩溃的现象。
解决方案:这个没有完美解决方案,指的是大面积的 key 同时过期,导致大量并发打到我们的数据库
①正常的思路就是,就是让并发分散开来:让过期时间分散开,并发量就会分成一部分,一部分,少量的打到数据库上,减少数据库压力
②如果过期时间无法分散情况下,在 service 服务层,查询时,设置一个短暂的随机延迟时间,查询的操作就会被分散了开来;少量的请求,先查询,就会读数据库,然后存入 redis;
其他请求,由于随机时间,稍稍慢了点,就可以去 redis 读出数据,会有几十或者上百(可以根据业务实际预测情况来设置)毫秒级别,这个时间是比较短暂的。