redis 过期键删除策略及内存淘汰策略

删除策略

过期键删除策略共有三种: 定时删除,惰性删除,定期删除.
redis的过期键删除策略采用的是: 惰性删除和定期删除策略. 通过两种策略的配合,达到cpu时间与浪费内存之间取得平衡.

惰性删除:
当键被访问时,如果发现键已经过期,先删除键,再返回客户端键已过期错误

定期删除:
redis.c/activeExpireCycle函数实现,当redis周期性的操作 redis.c/serverCron 函数时,这个函数就会被调用,它在规定的时间内.
分多次遍历服务器中的各个数据库,从数据库的expires(过期)字典中随机检查一部分键的过期时间,并删除其中的过期键.

内存淘汰策略:(redis8.0开始由6->8)

lru: 最近最少使用.
具体实现:

Redis维护了一个24位时钟,可以简单理解为当前系统的时间戳,每隔一定时间会更新这个时钟。每个key对象内部同样维护了一个24位的时钟,当新增key对象的时候会把系统的时钟赋值到这个内部对象时钟。比如我现在要进行LRU,那么首先拿到当前的全局时钟,然后再找到内部时钟与全局时钟距离时间最久的(差最大)进行淘汰,这里值得注意的是全局时钟只有24位,按秒为单位来表示才能存储194天,所以可能会出现key的时钟大于全局时钟的情况,如果这种情况出现那么就两个相加而不是相减来求最久的key.

A~~A~~A~~A~~A~~A~~A~~A~~A~~A~~~|
B~~~~~B~~~~~B~~~~~B~~~~~~~~~~~B|

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

LFU把原来的key对象的内部时钟的24位分成两部分,前16位还代表时钟,后8位代表一个计数器。16位的情况下如果还按照秒为单位就会导致不够用,所以一般这里以时钟为单位。而后8位表示当前key对象的访问频率,8位只能代表255,但是redis并没有采用线性上升的方式,而是通过一个复杂的公式,通过配置两个参数来调整数据的递增速度。

noeviction:默认策略,不淘汰任何数据,如果内存达到了设定的值,再添加数据时会报错。

allkeys-lru:加入键的时候,如果过限,首先通过LRU算法选取最近最少使用的数据抛弃。

volatile-lru:加入键的时候如果过限,首先在设置了过期时间的所有键中,选取最近最少使用的数据抛弃。

allkeys-random:加入键的时候如果过限,从所有 key 中随机抛弃。

volatile-random:加入键的时候如果过限,首先在设置了过期时间的所有 key 的集合中随机抛弃。

volatile-ttl:从设置了过期时间的所有 key 的集合中驱逐存活时间最短的数据。

volatile-lfu:从所有配置了过期时间的键中驱逐使用频率最少的 key 。

allkeys-lfu:从所有键中驱逐使用频率最少的 key 。

你可能感兴趣的:(redis 过期键删除策略及内存淘汰策略)