在Redis中,内存的大小是有限的,所以为了防止内存饱和,需要实现某种键淘汰策略。主要有两种方法,一种是对过期键进行删除的策略。另一种是当Redis内存不足时所采用的内存释放策略。

1.对过期键进行删除的策略

1,定时删除:在设置键的过期时间的同时,创建一个timer,让定时器在键的过期时间到达时,立即执行对键的删除操作。(主动删除)

优缺点:对内存友好,但是对cpu时间不友好,有较多过期键的而情况下,删除过期键会占用相当一部分cpu时间。

2,定期删除:每隔一段时间就对数据库进行一次检查,删除里面的过期键。(主动删除)

优缺点:采用对内存和cpu时间折中的方法,每个一段时间执行一次删除过期键操作,并通过限制操作执行的时长和频率来减少对cpu时间的影响。难点在于,选择一个好的策略来设置删除操作的时长和执行频率。

3,惰性删除:放任过期键不管,但是每次从键空间中获取键时,都检查取到的键是否过去,如果过期就删除,如果没过期就返回该键。(被动删除)

优缺点:对cpu时间友好,程序只会在取出键的时候才会对键进行过期检查,这不会在删除其他无关过期键上花费任何cpu时间,但是如果一个键已经过期,而这个键又保留在数据库中,那么只要这个过期键不被删除,他所占用的内存就不会释放,对内存不友好。

注意:

主节点在key到期时,会在AOF文件里增加一条del指令。AOF文件被同步到从节点以后,从节点根据AOF中的这个del指令来执行删除过期key的操作。

从节点的这个过期key的处理策略,会导致一个问题,主节点已经删除的key,在从节点还是存在的。因为AOF同步del指令是异步的。

2.内存释放的策略

Redis中有专门释放内存的函数:freeMmoryIfNeeded。每当执行一个命令的时候,就会调用该函数来检测内存是否够用。如果已用内存大于最大内存限制,它就会进行内存释放。

当需要进行内存释放的时候,需要用某种策略对保存的的对象进行删除。Redis提供了八种策略:

  1. volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
  2. allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
  3. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰
  4. volatile-lfu:从已设置过期时间的数据集(server.db[i].expires)中挑选最近使用次数最少的数据淘汰
  5. allkeys-lfu:从数据集(server.db[i].dict)中挑选最近使用次数最少的数据淘汰
  6. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰
  7. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
  8. no-enviction(驱逐):禁止驱逐数据[默认策略]  永不过期,返回错误