redis击穿、雪崩、穿透

目录

一、删除策略

二、淘汰策略

1、noeviction

2、lru( less recently used)

3、random

4、ttl(shorter time to live)

 5、lfu(least frequently use)

三、缓存击穿

四、缓存雪崩

五、缓存穿透


在了解redis中存在的击穿、雪崩、穿透问题之前需要先了解两个前置:删除策略和淘汰策略。

一、删除策略

        删除策略是针对设置了淘汰时间的key才会生效的,删除策略分为以下两种:

        1、被动删除:用户在访问某个key时,判断该key是否设置了过期时间,如果设置了,判断是否过期,如果已经过期,则进行删除;

        2、主动删除:由redis自己进行轮询、,随机从redis中获取20个key进行过期监测,删除已经过期的key,判断删除的key是否超过25%,如果超过则重复上面的这些流程,直到过期key地狱25%。

二、淘汰策略

        淘汰策略指的是当redis中的缓存大小达到设置的限制的时候,由maxmemory控制,当设置为0的时候,使用默认值,32位是默认3G。

淘汰策略整体分为三种:

1、noeviction

        当内存达到使用限制时,再新增key时,直接返回失败。只有当redis作为数据库使用的时候才会选用这个淘汰策略,如果redis作为缓存的时候,不建议选择这种淘汰策略。

        (redis在我们进行技术选型的时候,可以作为两个角色:数据库以及缓存,但作为数据库使用的时候,必须保证数据的完整性以及准确性,不能发生数据丢失,党作为缓存使用的时候,是允许数据丢失的,并且需要保证数据为热点数据,减少数据库压力)

2、lru( less recently used)

        最近最少使用,但是redis采用的是近似的lru算法,而不是一个完成的lru算法,通过对少量的key进行取样,删除最合适的key。可以通过修改设置采样数据,来接近真实的lru算法,配置属性为:maxmemory-sample。 在3.0以后添加了候选池的概念

        1)allkeys-lru:针对所有key采用lru算法淘汰key;

        2)volatile-lru:对设置了过期时间的key采用lru算法淘汰key;

3、random

        随机删除

        1)allkeys-random:针对所有key进行随机删除;

        2)volatile-random:针对设置了过期时间的key进行随机删除;

4、ttl(shorter time to live)

        更短存活时间,因为涉及到了存活时间,所以只有设置了存活时间的key才会存在这种淘汰策略,volatile-ttl。

 5、lfu(least frequently use)

        最少使用的key,使用一个bitmap类型的key,前16位存储使用时间,后8位作为计数器。可以使用lfu-log-factor(可以调整计数器的增长速度,值越大,计数器增长的越慢)和fu-decay-time(是一个以分钟为单位的数值,可以调整计数器的减少速度)来调整lfu算法

        1)allkeys-lfu:针对所有key使用lfu;

        2)volatile-lfu:针对设置了过期时间的key使用lfu;

三、缓存击穿

        出现原因:当redis中的某个key失效的时候,大量的并发请求同时请求这个key,由于key已经失效,所以大量的并发请求直接访问到数据库中,造成击穿现象。

        解决方案:通过setnx来进行一个加锁,当多个请求进来一个,拿到锁的那个请求来进行数据库查询并且回写到redis中。但是这里会存在几个问题:

        1、如果获得锁的请求在还没有释放锁之前就挂掉了,会出现死锁的问题,所以需要得锁设置过期时间;

        2、如果获得锁的请求在失效时间范围之内还没有处理完业务请求,就可能出险脏读的问题,针对这种情况可以在处理业务请求的过程中新开一个子线程用来进行过期时间监控,如果在快到期之前还没处理完请求,则通过子线程延长过期时间。

四、缓存雪崩

        出险原因:redis中大面积的key失效,然后大量并发请求进来,由于大范围的key失效,导致大量请求直接访问到数据库,注意与击穿的区别:击穿面对的是一个key,而雪崩面对的是多个key。

        解决方案:对key的过期时间进行随机设置,防止统一时间大批量的key失效。但是缓存雪崩存在一种特殊情况,就是零点失效问题,就是一批数据在业务场景里面要求在指定时间进行整体失效,此时随机设置失效时间是无法解决的,此时需要业务端针对这种情况进行特殊的业务处理,例如业务端在到达指定时间以后进行线程等待,根据数据同步时间指定等待时间或者进行中间态等待,提示用户稍后访问。

五、缓存穿透

        出现原因:redis中本身不存在某些key,然后大量的并发请求访问这些不存在的key,然后直接访问到数据库。

        解决方案:可以使用布隆过滤器进行处理,提前在布隆过滤器中添加允许访问的key,然后前端页面在进行查询的时候,先通过不同过滤器进行一次筛选,如果在布隆过滤器中,并且redis中不存在,则允许继续访问,如果在布隆过滤器中不存在,redis中也不存在,则对请求进行拒绝,防止恶意攻击。

        但是布隆过滤器存在两个主要问题:1)数据误判(在前一篇文章提到过)2)无法删除数据。针对不能删除的问题有两种处理方案:1)对需要删除的key进行置空操作;2)可以选择布谷鸟过滤器或者升级版的布隆过滤器。

              

        

猜你喜欢

转载自blog.csdn.net/weixin_38612401/article/details/123473686