Redis的内存淘汰策略详解

Redis占用内存

Redis作为内存型数据库,在业务量过大的情况下,会出现内存不够的情况(达到[maxmemory]设置值),当然机器内存足够强大,数据可承受范围会更大,但是这不是解决问题的方法。

Redis提供了两种解决方法:

  • 设置key的超时时间
  • LRU算法

设置数据的超时时间(TTL)

关于设置数据的超时时间这个方法,是我们经常用到的,同时设置超时时间还可以在某些场景下满足我们的业务需要:

  • 验证码的失效时间
  • 用户token的失效时间
  • ......

但是有没有想过TTL的过期策略是什么呢?

Redis的过期策略

redis的过期策略分为:定期删除 和 惰性删除

定期删除

Redis会将每个设置了过期时间的 key 放入到一个独立的字典中,以后会定期遍历这个字典来删除到期的 key。

Redis 默认会每秒进行十次过期扫描(100ms一次),过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略:

  1. 从过期字典中随机20个key
  2. 删除这 20 个 key 中已经过期的 key
  3. 如果过期的 key 比率超过 1/4,那就重复步骤 1

这里随机抽取就是为了在数据量过大的情况下,遍历大量的key,给CPU增加负担

惰性删除

惰性删除就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。通常情况下我们在日常的使用过程中查询已经过期的key,是比较容易触发该机制的。

定期删除是从比较大的层面做key的过期删除,因为其随机性,导致会有过期key不能及时删除的情况发生,惰性删除是在某些情况下对定期删除的一种弥补策略。

LRU

什么是LRU算法?

  1. 新增key value的时候首先在链表结尾添加Node节点,如果超过LRU设置的阈值就淘汰队头的节点并删除掉HashMap中对应的节点。
  2. 修改key对应的值的时候先修改对应的Node中的值,然后把Node节点移动队尾。
  3. 访问key对应的值的时候把访问的Node节点移动到队尾即可。

Redis使用的是近似LRU算法:近似LRU算法通过随机采样法淘汰数据,每次随机出5(默认)个key,从里面淘汰掉最近最少使用的key,可以通过maxmemory-samples参数修改采样数量: 例:maxmemory-samples 10 maxmenory-samples配置的越大,淘汰的结果越接近于严格的LRU算法,但是同时对内存的消耗也越大。

Redis使用近似LRU算法,在基本满足策略需要的情况,尽可能的降低了内存的消耗,CPU的占用,在硬件满足的情况的下,也可以通过maxmemory-samples的调整,无线接近于标准LRU算法。

Redis为了实现近似LRU算法,给每个key增加了一个额外增加了一个24bit的字段,用来存储该key最后一次被访问的时间。

Redis3.0对近似LRU算法进行了一些优化。新算法会维护一个候选池(大小为16),池中的数据根据访问时间进行排序,第一次随机选取的key都会放入池中,随后每次随机选取的key只有在访问时间小于池中最小的时间才会放入池中,直到候选池被放满。当放满后,如果有新的key需要放入,则将池中最后访问时间最大(最近被访问)的移除。当需要淘汰的时候,则直接从池中选取最近访问时间最小(最久没被访问)的key淘汰掉就行。

内存淘汰策略

1. noeviction:当内存使用超过配置的时候会返回错误,不会驱逐任何键

2. allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键

3. volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键

4. allkeys-random:加入键的时候如果过限,从所有key随机删除

5. volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐

6. volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键

7. volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的键(Reidis4之后)

8. allkeys-lfu:从所有键中驱逐使用频率最少的键(Reidis4之后)

LFU

LFU是在Redis4.0后出现的,LRU的最近最少使用实际上并不精确,考虑下面的情况,如果在|处删除,那么A距离的时间最久,但实际上A的使用频率要比B频繁,所以合理的淘汰策略应该是淘汰B。LFU就是为应对这种情况而生的。

A~~A~~A~~A~~A~~A~~A~~A~~A~~A~~~|

B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~~B|

 

参考:

https://zhuanlan.zhihu.com/p/105587132

https://www.cnblogs.com/vegetableDD/p/11890570.html

https://www.bilibili.com/video/BV1Cb411j7RA?p=8

https://segmentfault.com/a/1190000017555834

 

猜你喜欢

转载自blog.csdn.net/qq_25805331/article/details/109287489