讲到redis的过期删除策略,就不得不说一下redis是如何判断键是否过期,让我们首先来了解下redis内部结构是如何存储键与过期时间之间的关系

过期字典

redisClientredisDb结构中存储着一个expires字典(key-value),专门用来存储过期时间,如下所示:

typedef struct client {
    redisDb *db; /* Pointer to currently SELECTed DB. */
} client;

typedef struct redisDb {
    // 字典类型,用于保存键的过期时间
    dict *expires;
} redisDb;

过期字典dict的键是一个指针,指向键对象;值是一个long long类型的整数,保存了其键的过期时间(毫秒精度的UNIX时间戳)

因为是字典类型key-value,所以查询的时间复杂度为O(1),当我们需要判断redis的键是否过期时,只需要从过期字典里面取出键所对应的值,如果键不存在,则表示没有过期;如果键存在,则判断值与当前的时间戳的大小,大于当前时间戳则不过期,小于则过期;

现在让我们来谈谈redis删除策略

删除策略

redis有三种过期删除策略:定时删除惰性删除定期删除

  1. 定时删除:在设置键的过期时间的同时,创建timer定时器,当键快过期时执行删除操作

  2. 惰性删除:当每次获取键时,检查获取的键是否过期,如果过期则删除该键

  3. 定期删除:每隔一段时间,redis就会对数据库进行一次检查,删除里面的过期键

优缺点

这三种过期删除策略的优缺点如下:

策略 优点 缺点
定时删除 对内存友好,因为总是能及时删除过期键 对CPU不友好,因为过期键较多的情况可能发生同时删除过期键导致占用太多CPU时间
惰性删除 对内存不友好,因为如果键过期了,但是没有被访问到,那么就会一直存在于内存中,导致内存占用 对CPU友好,因为只有当被访问到才会执行过期判断与删除
定期删除 折中,跟删除操作的执行时长与频率有关 折中,跟删除操作的执行时长与频率有关

由此可知,三种过期删除策略都有各自的优缺点,而定期删除是定时删除与惰性删除的折中方案

目前redis服务器采用的是惰性删除与定期删除两种策略,通过配合使用更好地保证CPU时间与内存的平衡

相关文档:

redis设计与实现

redis进阶: redisObject对象详解

原文地址:

redis进阶: 过期删除策略

happy coding!