Redis Expire 原理
目录
简介
为给定的key设置生存时间(timeout),当key过期时,这个key就会自动地被删掉。在Redis术语中,一个关联了timeout的key经常称为“易失的”(volatile)。
在Redis中只有删除/覆盖一个key才能修改其timeout,比如:DEL、SET、GETSET和所有的存储(*STORE)命令。这意味着仅修改值而不用一个新的key来替代的话,timeout是不会改变的,比如:INCR、LPUSH、HSET。
另外,也可以使用PERSIST命令将timeout移除,使其变成给一个永久的key。如果是RENAME一个key,则其timeout在rename前后是一致的。比如:RENAME KeyB KeyA,则无论原始的KeyA是否带timeout,它都会被删掉,而KeyB改名为KeyA后继续保留KeyB的timeout。
返回值:
- 1:成功设置了timeout
- 0:key不存在
更新生存时间
对一个已经带有timeout的key执行EXPIRE命令,可以为它指定新的生存时间。
时间精度
在Redis 2.4中,过期时间的延迟在1秒内,也就是说即使key过期了仍可能在最后的一秒内被访问到。而在Redis 2.6以后,过期时间的精度降低到1毫秒。
过期与持久
一个key的过期时间信息是以绝对的Unix时间戳存储的,这意味着即使Redis实例没有启动,时间照常流逝。
为了让过期时间正常工作,服务器的时间必须正确设置。如果我们在两台时间不同步的服务器上移动RDB文件,那么可能会发生一些有趣的事情(比如在载入过程中,key已经过期了)。
即使在一台持续运行的服务器上,时间的设置也很重要。比如我们设置一个key的timeout为1000s,然后把服务器的时间改为将来的2000s后,那么这个key也会立即过期。
如何过期
Redis中一个key过期删除主要有两种方式:被动(passive way)和主动(active way)。
被动删除
当客户端尝试查询某个key,然后发现这个key的timeout已经过期了,则这个key会被删除,并返回空。
主动删除
对于那些从未被查询的key,即便它们已经过期,被动方式也无法清除。因此Redis会周期性地随机测试一些key,已过期的key将会被删掉。Redis每秒会进行10次操作,具体的流程:
- 随机测试 20 个带有timeout信息的key;
- 删除其中已经过期的key;
- 如果超过25%的key被删除,则重复执行步骤1;
这是一个简单的概率算法(trivial probabilistic algorithm),基于假设我们随机抽取的key代表了全部的key空间。
Replica和AOF
为了取得一致的行为而避免牺牲一致性(consistency),当一个key过期时,DEL操作会同步到AOF文件和所有关联的Slave实例。按这种方式,key的过期操作都是在Master实例上集中处理,所以就不会有一致性错误。
然而,尽管Slaves并不会独立地删除过期的key(而是等待从Master传来的DEL操作),Slaves仍然保存着每个key的全部状态信息。因此当一个Slave被选举为Master后,它仍然能够独立地删除过期地Key,跟正常的Master一样。
评论