|
|
|
@ -0,0 +1,19 @@
|
|
|
|
|
Redis会将设置了过期时间的key放入一个独立字典中,由定时任务及惰性删除策略来删除过期key。
|
|
|
|
|
所谓惰性删除就是在客户端访问这个Key的时候,Redis对key的过期时间进行校验,如果过期了就删除
|
|
|
|
|
# 一、定期扫描
|
|
|
|
|
redis默认每秒进行10次过期扫描,它不会遍历字典中的所有Key,而是采用了贪心策略,步骤:
|
|
|
|
|
1. 从过期字典中随机选出20个key
|
|
|
|
|
2. 删除这20个key中已经过期的
|
|
|
|
|
3. 如果过期key的比例超过1/4,那就重复步骤1
|
|
|
|
|
为了保证过期扫描不会出现循环过度,导致线程卡死,算法还增加了扫描时间的上线,默认不超过25ms。
|
|
|
|
|
|
|
|
|
|
Redis会持续扫描过期字典,直到字典中的过期Key变得稀疏(不超过1/4)才会停止。这就导致线上读写出现明显的卡顿,这种卡顿的另外一种原因是内存管理器需要频繁回收内存页,产生了CPU消耗。
|
|
|
|
|
所以如果有大批量的key过期,要给过期时间设置一个随机范围,而不能全部在同一时间过期。
|
|
|
|
|
|
|
|
|
|
## 1.1 从节点的过期策略
|
|
|
|
|
从节点不会进行过期扫描,从节点对过期的处理是被动的。主节点在Key到期时会在AOF日志中添加del命令,同步到所有从节点,从节点通过执行命令进行删除,这就导致了主从数据不一致。
|
|
|
|
|
|
|
|
|
|
# 二、惰性删除
|
|
|
|
|
大部分情况下del命令执行很快,如果删除一个包含成千上万元素的Hash,那么删除会导致单线程卡顿。
|
|
|
|
|
Redis为了解决这个问题引入了unlink指令,它能对删除操作进行懒惰处理,交给后台其他线程来异步回收内存。
|
|
|
|
|
这个命令不会导致线程安全问题,可以将整个Redis内存里面的有效数据想象成一颗树,当使用unlink时,它只是把其中一个树枝剪断了扔到旁边,在离开树的一瞬间,它就再也无法被主线程中的其他指令访问。
|