Redis的过期键删除策略

本文介绍了Redis设置过期时间的四个命令,最终都转换为pexpireat实现,还阐述了过期键的三种删除策略。定时删除对内存友好但耗CPU;惰性删除省CPU但可能致内存泄露;定期删除较折中,需合理制定频率和时长。Redis实际采用惰性和定期删除结合。
设置过期时间

通过expire或者pexpire命令可以为Redis的键以秒或者毫秒级别设置生存时间(Time To Live,TTL)。在经过相应的秒或者毫秒之后,服务器会自动删除键:

redis> set msg "hello"
OK
redis> expire msg 5
(integer) 1
redis> get msg	//5秒内
"hello"
redis> get msg	//5秒后
(nil)

通过expireat或者pexpireat命令可以为Redis的键以秒或者毫秒级别设置过期时间(expire time)。过期时间是一个Unix时间戳,当键的时间戳来临,服务器会自动删除键:

redis> set msg "hello"
OK
redis> expireat msg 1562986813
(integer) 1
redis> get msg	//1562986813前
"hello"
redis> get msg	//1562986813后
(nil)

所以,Redis有四个命令来设置键的生存时间或者过期时间。

  • expire <key> <ttl> 将键key的生存时间设置为ttl秒。
  • pexpire <key> <ttl> 将键key的生存时间设置为ttl毫秒。
  • expireat <key> <timestamp> 将键key的过期时间设置为timestamp指定的秒级时间。
  • pexpireat <key> <timestamp> 将键key的过期时间设置为timestamp指定的毫秒级时间。

命令的单位和格式虽然不同,但是所有命令最终都是转换成pexpireat命令来实现的:

秒转换成毫秒
以毫秒计算当前Unix时间戳
过期时间由秒转换成毫秒
expire
pexpire
pexpireat
expireat

RedisDb使用过期字典保存了数据库中所有的过期时间

  • 过期字典的键的值是一个指针,指向键空间中的某个键对象。
  • 过期字典的值是一个long类型的整数,保存了所指向的键的过期时间(一个以毫秒精度的时间戳)。
    在这里插入图片描述
过期键的删除策略

Redis中,过期键的删除有三种策略:

  • 定时删除:在设置键的过期时间的同时,创建一个定时器,让定时器在键的过期时间来临是,立即执行键的删除操作。
  • 惰性删除:放任过期键不管,每次从键空间获取键时,都要对该键进行检查是否过期,如果过期,则删除该键,如果没有过期,则返回该键。
  • 定期删除:每隔一段时间,程序对数据库进行一次检查,删除库中的过期键。
定时删除

定时删除策略是对内存最友好的策略。通过创建定时器,保证过期键尽可能快的被删除,并释放过期键所占有的内存。

但是,定时删除策略确实对CPU最不友好的策略,如果过期键比较多,删除过期键这一行为可能占据大量的CPU时间。如果当前有大量的客户端命令请求在服务器等待处理,而且服务器内存情况并不紧张,那么服务器应该将CPU时间优先用在相应客户端命令上面,而不是用在和当前任务无关的删除过期键任务上,这样会对服务器的响应时间和吞吐量造成影响。

惰性删除

惰性删除策略是对CPU时间最友好的策略,程序只会在取出键的时候才会对键做过期检验,这个策略不会在删除其他无关过期键上浪费任何CPU时间。

惰性删除的缺点是对内存最不友好,如果一个键已经过期,然而一直没有读取该键,会导致该过期键一直留在数据库当中,如果这个键一直不被删除,那它所占用的内存将永远不会被释放。如果有大量的过期键存在,而这些过期键恰好又打不到访问,那么它们将永远不会被删除,这种垃圾数据占据大量的内存,而服务器又不会主动去删除的情况,可以说是一种内存泄露了。

惰性删除策略流程:

所有读写命令
调用expireIfNeeded函数
键是否过期?
删除过期键
执行实际命令
定期删除

从上面两种删除策略来看,都存在单一使用是的明线缺陷。

  • 定时删除占用太多CPU时间,影响服务器的吞吐量和相应时间。
  • 惰性删除浪费太多的内存,有内存泄露的风险。

定期删除则是一种这种的策略:

  • 没隔一段时间执行一次过期键的删除操作,并控制操作执行的时间和频率来减少对CPU时间的影响。
  • 通过定期删除过期键,有效的减少了因过期键带来的内存浪费。

定期删除的难点:频率和时长

  • 如果删除操作执行太过频繁,并且操作时间太长,定期删除则和定时删除一样,将太多的CPU时间浪费在删除过期键操作上面。
  • 如果执行的太少,或者执行时间太短,定期删除则和惰性删除一样,出现内存浪费的情况。
    因此,服务器应该根据具体情况,合理的制定定期删除的频率和时长。

Redis服务器实际上使用的是惰性删除和定期删除这两种策略,通过配合,可以很好的在CPU使用时间和内存占用两个方面取得平衡。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值