本文基于Redis 6.0.9版本,前提至少 Redis 3.0或更高版本。
目录
1.键(key)生存时间
Redis允许为每个键设置不同的生存时间,以便键过期后会自动将其从服务器中删除。
时间复杂度:O(1)
设置键(key)超时。 超时到期后,键(key)将自动删除。 在Redis术语中,通常将具有相关超时的键(key)称为可变键。
只有删除或覆盖键(key)内容的命令(包括 DEL, SET, GETSET 和所有 *STORE 命令)才能清除超时。这意味着所有在概念上更改存储在键(key)上的值而不用新键替换的操作都将保持超时不变。例如,使用INCR,递增键的值,使用LPUSH将新值推入列表或使用HSET更改哈希的字段值都是使超时保持不变的操作。也可以使用PERSIST命令清除超时,将密钥变回永久密钥。
如果使用RENAME重命名了键,则相关的生存时间将转移到新的键名称。
如果某个键被RENAME覆盖,例如现有的键 Key_A 被诸如 RENAME Key_B Key_A之类的调用覆盖,则原始Key_A是否与超时关联都无关紧要,新密钥Key_A将继承所有Key_B的特征。
请注意,使用非肯定超时调用EXPIRE/PEXPIRE或使用过去某个时间调用EXPIREAT/PEXPIREAT将导致键被删除而不是过期(因此,发出的键事件将被删除,而不是过期)。
1.1.刷新过期
可以使用已具有现有过期集的键作为参数来调用EXPIRE。 在这种情况下,键的生存时间将更新为新值。
1.2.Redis 2.1.3之前的版本差异
在Redis版本2.1.3之前的版本中,使用更改其值的命令来更改具有过期集的密钥具有完全删除键的作用。 由于现在已修复了复制层中的限制,因此需要此语义。
EXPIRE将返回0,并且不会通过设置超时来改变键的超时。
1.3.返回值
整数回复(Integer reply),具体是:
- 如果设置了超时,则为1。
- 如果键不存在,则为0。
1.4.例子
redis> SET mykey "Hello"
"OK"
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
"OK"
redis> TTL mykey
(integer) -1
redis>
1.5.模式:导航会话
想象一下,您拥有一个Web服务,并且您对用户最近访问的最新N页感兴趣,因此每个相邻的页面视图执行的时间都不超过前一个页面的60秒。 从概念上讲,您可以将这组页面视图视为用户的导航会话,其中可能包含有关他或她当前正在寻找哪种产品的有趣信息,以便您可以推荐相关产品。
您可以使用以下策略在Redis中轻松地对此模式进行建模:每次用户执行页面查看时,您都会调用以下命令:
MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC
如果用户空闲超过60秒,则将删除键,并且仅记录相差少于60秒的后续页面视图。
可以轻松修改此模式,以使用使用INCR的计数器而不是使用RPUSH的列表。
附录:Redis过期
1.带有过期键
通常,Redis键的创建没有关联的生存时间。 除非用户以明确的方式(例如,使用DEL命令)将其删除,否则该键将永远存在。
EXPIRE系列命令能够将过期与给定的键相关联,但要花一些键使用额外的内存的代价。 当键设置了过期时,Redis将确保在经过指定的时间后删除键。
可以使用EXPIRE 和PERSIST命令(或其他严格相关的命令)来更新或完全删除关键的生存时间。
2.过期精度
在Redis 2.4中,过期可能不是精确的,并且可能在零到一秒之间。
从Redis 2.6开始,过期错误为0到1毫秒。
3.过期和持久性
键过期信息存储为Unix timestamps(对于Redis 2.6或更高版本,以毫秒为单位)。 这意味着即使Redis实例未处于活动状态,时间也在流逝。
为使到期有效,计算机时间必须保持稳定。 如果您从两台时钟同步程度较大的计算机上移动RDB文件,则可能会发生有趣的事情(例如,所有加载的键在加载时都会过期)。
即使正在运行的实例也将始终检查计算机时钟,因此,例如,如果您将键的生存时间设置为1000秒,然后在将来将计算机时间设置为2000秒,则键将立即失效,而不是持续使用1000秒
4.Redis如何过期键
Redis密钥以两种方式过期:被动方式和主动方式。
仅当某些客户端尝试访问键时,键才会被动失效,并且发现该键超时。
当然,这还不够,因为有过期的键将永远不会再次访问。 这些键无论如何都应该过期,因此Redis会定期对具有过期集的键中的一些键进行随机测试。 从键空间中删除所有已过期的键。
具体来说,这是Redis每秒执行10次的操作:
- 从一组相关联的过期键中测试20个随机键。
- 删除找到的所有键已过期。
- 如果超过25%的键已过期,请从步骤1重新开始。
这是一个微不足道的概率算法,基本上是假设我们的样本可以代表整个键空间,并且我们会继续过期,直到可能过期的键百分比低于25%
这意味着在任何给定时刻,正在使用内存的已过期键的最大数量最大等于每秒最大写操作数量除以4。
5.复制链接和AOF文件中如何处理过期
为了在不牺牲一致性的情况下获得正确的行为,当键过期时,将在AOF文件中合成DEL操作,并获得所有附加的副本节点。 这样,到期过程就集中在主实例中,并且不会出现一致性错误。
然而当副本连接到主节点将不能独立到期键(但将等待DEL从主节点的),他们仍然会采取全状态的到期现有数据集中,所以当一个副本当选主节点,它将能够独立使键失效,从而完全充当主节点。