- 过期key设置
创建一个key value的时候设置过期key
set key1 value1 EX 60
设置已经存在的key的过期时间
expire key 60
#毫秒
PEXPIREAT key milliseconds-timestamp
查看过期时间
ttl key
- 清理策略
访问key时候 执行expireIfNeeded(db,key) 判断是否过期并进行淘汰
CPU空闲在定期serverCron任务中 逐出部分过期key
每次事件循环aemain执行的时候,会执行beforeSleep逐出部分过期的key
- 过期数据清理算法
1,redis 配置项hz定义了serverCron任务的执行周期,默认是10,即CPU空闲时每秒执行10次
2, 每次过期key清理的时间不超过CPU时间的25%,即hz=1 ,则一次清理时间最大为250ms,若hz=10,则一次清理时间最大为25ms
3, 清理时依次遍历所有的db
4, 从db中随机取20个key,判断是否过期,如果过期,则逐出
5, 如果5个以上过期,则重复上一步骤,否则遍历下一个db
6, 在清理过程中,如果达到25%CPU时间,则退出清理过程
- 数据逐出时机
redis 在处理命令之前进行内存的检查及淘汰,判断是否设置了maxmemory,如果有就执行freememoryIfNeeded函数
- 数据淘汰算法
1, volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
2, volatile-ttl: 从已设置过期时间的数据集(server.db[i].expires)中挑选 要过期的数据淘汰
3, volatile-random: 从已设置过期时间的数据集(server.db[i].expires) 中任意选择数据淘汰
4, allkey-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
5, allkey- random: 从数据集(server.db[i].dict)中任意选择数据淘汰
6, no-enviction(驱逐):禁止驱逐数据 拒绝所有写入操作并返回客户端错误信息"(error) OOM command not allowed when used memory",此时Redis只响应读操作
7,Redis 4.0 allkey-lfu 对全部key采用LFU淘汰算法。 驱逐使用频率最少的键
8, Redis 4.0 volatile-lfu 对有过期时间的key采用LFU淘汰算法 , 驱逐使用频率最少的键
在LFU算法中,可以为每个key维护一个计数器。每次key被访问的时候,计数器增大。计数器越大,可以约等于访问越频繁
./redis-cli --hotkeys
OBJECT FREQ key
- 实践
1,不要放垃圾数据,及时清理无用数据
实验数据和下线业务数据及时删除。
2, key尽量都设置过期时间
对具有时效性的key设置过期时间,通过redis自身的过期key清理策略来降低过期key对于内存的占用,同时对于能够减少业务的麻烦不需要定期手动清理。
3, 单key不要过大
key过大会导致网络传输延迟比较大,需要分配的输出缓冲区也比较大,在定期清理的时候也容易造成比较高的延迟,最好能通过业务拆分,数据压缩等方式避免这种过大的key的产生。
4, 不同业务如果公用一个业务的话,最好使用不同逻辑db分开
从上面的分析可以看出,redis的过期key清理策略和强制淘汰策略都会遍历各个db,将key分布在不同的db有助于过期key的及时清理,另外不同业务使用不同db有助于问题排查和无用数据的及时下线。