Redis源码剖析(四)过期键的删除策略

Redis通过惰性删除和周期删除策略处理过期键。惰性删除在访问键时检查是否过期并删除,而周期删除定期随机检查并删除过期键,以平衡CPU使用和内存效率。
摘要由CSDN通过智能技术生成

Redis是支持时间事件的,所谓时间事件,是为某个键值对设置过期时间,时间一到,Redis会自动删除该键值对。例如使用SET命令添加字符串类型的键值对

127.0.0.1:6379> SET blog redis ex 10    //添加键值对<blog, redis>,10秒后删除
OK
127.0.0.1:6379> GET blog    //添加后马上查找,可以获取redis
"redis"
127.0.0.1:6379> GET blog    //上趟厕所回来,发现找不到了
(nil)

Redis是如何实现定时删除的呢,在数据库结构redisDb中,可以发现除了上篇提到的用于保存键值对的dict字典外,另有一个字典变量expires,实际上正是它保存着键和其过期时间(绝对时间)。当执行完SET命令后,两个字典的数据分布为

//server.h
typedef struct redisDb {
    dict *dict;            /* 保存键值对的字典 */     
    dict *expires;         /* 保存键和过期时间 */    
    int id;        /* 数据库唯一id */           
    ...
} redisDb;
dict字典
blog --> redis
expires字典
blog --> blog的过期时间

设置,获取,删除过期时间

以下键节点指字典中的哈希节点,保存键和值

设置键的过期时间

//db.c
/* 
 * 设置键的过期时间
 * db   : 数据库
 * key  : 键
 * when : 过期时间(绝对时间)
 */
void setExpire(redisDb *db, robj *key, long long when) {
    dictEntry *kde, *de;

    /* Reuse the sds from the main dict in the expire dict */
    /* 从数据字典中寻找键节点 */
    kde = dictFind(db->dict,key->ptr);
    serverAssertWithInfo(NULL,key,kde != NULL);
    /* 从时间字典中寻找键节点,如果不存在则创建一个 */
    de = dictReplaceRaw(db->expires,dictGetKey(kde));
    /* 设置键节点的值,值为过期时间(绝对时间) */
    dictSetSignedIntegerVal(de,when);
}

dictSetSignedIntegerVal是宏定义,设置键节点de的值为when。因为哈希节点中的值结构是联合,可以存储不同大小的数字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值