EXPIRE key seconds
为键设置一个超时时间。超时结束后,对应的键将会自动被删除。在Redis术语中,一个关联了超时时间的键通常被称为是不稳定的。
只有那些可以删除或者重写键内容的命令,包括DEL/SET/GETSET和所有的*STORE命令才可以清除超时时间。这意味着所有那些在只在概念上修改了存储在键上的值而没有用一个新值来替换它的操作都不会使超时时间发生变化。举个栗子,使用INCR命令对键作增加操作、使用LPUSH将一个新值推入列表,或者使用HSET改变了一个域的值等等这些操作都会维持超时时间不变。
使用PERSIST命令也可以把键的超时时间清除,将它设置为一个永久的键。
如果一个键被RENAME命令重命名,与之相关联的超时时间也会被转移至新的键。
如果一个键被RENAME命令重写,比如说,如果一个已经存在的键Key_A被这样的调用RENAME Key_B Key_A
重写,那么无论原始的键Key_A有没有设置超时时间,新的键Key_A都将会继承Key_B的特性。
请注意:当调用EXPIRE/PEXPIRE命令时使用了一个非正数的超时时间或者一个过去的时间,将会导致这个键被删除而不是过期(相应的,与之关联的注入时间也会被删除,而不是被设置为过期)。
刷新过期时间
对一个已经设置了过期时间的键再次调用EXPIRE命令也是可以的。在这种情况下键的生存时间将会被更新为新的值。这个特性有很多非常有用的应用场景,接下来的导航会话模式部分记录了一个例子。
2.1.3之前版本Redis的不同之处
在2.1.3之前的版本中,对一个带有过期设置的键,使用命令修改它的值将会导致这个键被完全删除。因为复制层的限制这种语义是必要,不过现在已经修复了。
EXPIRE命令会返回0,而不会更改键的超时时间。
返回值
EXPIRE命令的返回值是一个整数,更具体点来说是:
1 如果超时时间被成功设置
0 如果键不存在
例子
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>
案例:导航会话
想象一下你有一个web服务,并且你对被用户访问的最近N个页面感兴趣,这样的相邻页面视图与上一个页面的的间隔时间不超过60秒。概念上讲你可以将这些页面看作用户的导航会话,其中可能包含他/她当前正在寻找某种产品的有趣信息,这样一来你就可以向他/她推荐相关的产品。
在Redis中使用下面这种策略你可以很容易为这个案例进行建模:用户每次打开一个页面视图时,你可以调用下面的命令:
MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC
如果用户的停留之间超过60秒,这个键将会被删除,只有那些用户停留时间少于60秒的页面后续网页才会被记录下来。
这个案例很容易用使用INCR的计数器而不是用RPUSH的列表来进行修改。
附录:Redis过期时间
带过期时间的键
通常来说,创建Redis键时都没有关联存活时间。键将会一直存在,除非用户明确地删除它,比如说使用DEL命令。
EXPIRE系列类命令只需要键的一点点额外内存就可以为指定的键关联过期时间。如果一个键有过期时间设置,Redis将会确保当指定的时间消耗完以后删除这个键。
键的存活时间可以使用EXPIRE或PERSIST命令来进行更新或完全移除(或者其他严格相关的命令)。
过期精度
在2.4版本的Redis中,过期时间可能不是很准确,它可能会有0到1秒的误差。
从2.6版本开始,过期时间误差已经被优化到了0到1毫秒。
过期和持久
键的过期信息被存储为绝对的Unix时间戳(在2.6或更高的版本中以毫秒为单位)。这意味着时间会一直流逝,即使Redis实例不是活跃状态的。
为了让过期功能运行良好,电脑时间必须是稳定的。如果你在两台时钟同步很差的电脑中移动一个RDB文件,那么很可能会发生一些有趣的事情(比如说所有的键一加载就过期了)。
即使活跃的实例也会一直检查电脑时钟,所以如果你设置一个键的存活时间为1000秒,然后将电脑时间加快2000秒,那么键会立即过期而不是等1000秒之后。
Redis如何让键过期
Redis有两种方式让键过期:一种被动方式和一种主动方式。
当客户端试图访问一个键却发现它已经超时时,该键会被动地过期。
当然这是不够的,因为可能有些键一直都不会再被访问了。但是这些键应该被设置为过期,所以Redis会周期性的在带有过期时间的键中随机地挑选一些来进行测试。已经过期的键会从键空间中移除。
具体来说,Redis每秒钟会将以下工作重复10次:
在带有过期时间的键中随机测试20个键。
删除所有发现的已过期的键。
如果超过25%的键已过期,重复步骤1。
这是一个简单的概率算法,它的基本思想是假设我们选取的样本代表了整个键空间,我们不断地进行过期检测直到过期的键低于25%。这意味着在任意时刻,已经过期的键的最大数量等于每秒钟最大写入操作数量的四分之一。
如何在复制连接和AOF文件中处理过期
为了获得正确的行为而不牺牲一致性,当一个键过期时,在AOF文件中会合成一个DEL命令,并且获得所有的从服务器信息。在这种方式下,过期的处理集中在master实例中,并且没有任何发生一致性错误的可能性。
然而连接到主服务器的从服务器不会独立地使键过期(而是会等待来自主服务器的DEL命令),它们仍然会在数据集中维持过期的完整状态,因此当一个从服务器被选举为主服务器时,它将能够独立地使键过期,充分发挥主服务器的作用。
2017-09-06