Redis内存淘汰策略

当Redis内存超过最大允许的内存之后,Redis就会触发内存淘汰策略(阈值可配置)

  • 早期Redis版本:
    allkeys-random:在所有的缓存中随机删除(不推荐)
    allkeys-lru: 对所有的键都采取LRU淘汰
    volatile-lru: 仅对设置了过期时间的键采取LRU淘汰
  • Redis4.x版本后
    allkeys-lfu:对所有的键都采取LFU淘汰
    volatile-lfu:仅对设置了过期时间的键采取LFU淘汰

LRU:最近最少使用

以双向链表存放被访问的key,每次被访问到的就会放入表头,表尾就是最少被访问的。

LRU算法需要一个双向链表来记录数据的最近被访问顺序,但是出于节省内存的考虑,Redis的LRU算法并非完整的实现。

Redis的LRU并不维护队列,它会提供一个待淘汰候选key的pool,里面默认有16个key,按照空闲时间排好序。触发淘汰机制时从Redis键空间随机选择N个key,分别计算它们的空闲时间idle,key的空闲时间大于pool里最小的时,才会进入pool,然后从pool中选择空闲时间最大的key淘汰掉。

LFU:最不经常使用

在LFU算法中,可以为每个key维护一个计数器。每次key被访问的时候,计数器增大。计数器越大,可以约等于访问越频繁。

redisObject:

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;

LFU把原来的redisObject 对象的内部时钟的24位分成两部分,前16位还代表时钟,后8位代表一个计数器。但是redis并没有采用线性上升的方式,而是采用配置两个因子来影响计数器的递增和递减,例如:
lfu-log-factor 10
lfu-decay-time 1

递增:缓存一自被命中,则计数器会递增
递减:过几分钟后,没有被命中,则计数器会递减

你可能感兴趣的:(Redis内存淘汰策略)