数据存储和有效期
在 redis 工作流程中,过期的数据并不需要马上就要执行删除操作。因为这些删不删除只是一种状态表示,可以异步的去处理,在不忙的时候去把这些不紧急的删除操作做了,从而保证 redis 的高效
数据的存储
在redis中数据的存储不仅仅需要保存数据本身还要保存数据的生命周期,也就是过期时间。在redis 中 数据的存储结构如下图:

获取有效期
Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令获取其状态

删除策略
在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄漏。
定时删除
创建一个定时器,当key设置过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作
优点
节约内存,到时就删除,快速释放掉不必要的内存占用
缺点
CPU压力很大,无论CPU此时负载多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量
总结
用处理器性能换取存储空间
惰性删除
数据到达过期时间,不做处理。等下次访问该数据,如果未过期,返回数据。发现已经过期,删除,返回不存在。这样每次读写数据都需要检测数据是否已经到达过期时间。也就是惰性删除总是在数据的读写时发生的。
expireIfNeeded函数
对所有的读写命令进行检查,检查操作的对象是否过期。过期就删除返回过期,不过期就什么也不做~。
执行数据写入过程中,首先通过expireIfNeeded函数对写入的key进行过期判断。
/*
* 为执行写入操作而取出键 key 在数据库 db 中的值。
*
* 和 lookupKeyRead 不同,这个函数不会更新服务器的命中/不命中信息。
*
* 找到时返回值对象,没找到返回 NULL 。
*/
robj *lookupKeyWrite(redisDb *db, robj *key) {
// 删除过期键
expireIfNeeded(db,key);
// 查找并返回 key 的值对象
return lookupKey(db,key);
}
执行数据读取过程中,首先通过expireIfNeeded函数对写入的key进行过期判断。
/*
* 为执行读取操作而取出键 key 在数据库 db 中的值。
*
* 并根据是否成功找到值,更新服务器的命中/不命中信息。
*
* 找到时返回值对象,没找到返回 NULL 。
*/
robj *lookupKeyRead(redisDb *db, robj *key) {
robj *val;
// 检查 key 释放已经过期
expireIfNeeded(db,key);
// 从数据库中取出键的值
val = lookupKey(db,key);
// 更新命中/不命中信息
if (val == NULL)
server.stat_keyspace_misses++;
else
server.stat_keyspace_hits++;
// 返回值
return val;
}










