redis expire命令

命令格式:EXPIRE key seconds

给key设置超时时间(timeout)。设置的超时时间过期后,key会被自动删除。在Redis术语中带有超时时间的key通常被称为不稳定的(volatile)。

超时时间只能被删除或者覆盖key内容的命令清除,包括 DEL, SET, GETSET 和所有的 *STORE 命令。 从概念上来说,那些修改key中存储的值,而不是用新值替换旧值的命令,不会修改timeout。例如, 自增key存储的值的 INCR, 向list中新增一个值 LPUSH, 或者修改hash域的值 HSET ,这些都不会修改key的timeout。

通过使用 PERSIST命令把key改回持久类型(persistent)的key,这样key的timeout也可以被清除。

一个key使用RENAME改名后,生存时间被转移到新key上。

一个已存在的旧key使用RENAME重写,那么新key会继承所有旧key的属性。例如,一个名为Key_A的 key 使用命令 RENAME Key_B Key_A重写,原Key_A有没有设置timeout都没影响,新的Key_A会继承所有Key_B的属性。 

特别注意,使用非正的timeout调用 EXPIRE/PEXPIRE 或使用过去的时间调用 EXPIREAT/PEXPIREAT ,那么key会被删除 deleted 而不是过期。 (因此, 发出的 key event 将是 del, 而不是 expired).

*刷新超时时间

已经设置过期的key,可以调用 EXPIRE 重新设置。在这种情况下key的生存时间被更新为新值。因为这个特性出现了很多有用的应用,本文下面的 Navigation session pattern 部分就是一个例子。

*Expire在Redis 2.1.3之前版本的不同

在 2.1.3 之前的版本使用Expire修改已经设置过生存时间的key,将会和删掉key有同样的效果。这是被已被修复的复制层的限制所有需要的特性。

*返回值

Integer reply:

  • 1 设置成功。
  • 0 key不存在或设置失败。

*实际例子

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> 

*模式: 导航会话(Navigation session)

假设你有个web服务并且你关注用户最近最新访问的N个页面,考虑到每个相邻新页面的访问不会超过访问前一个页面60秒,概念上我们可以考虑把这一系列的页面访问作为一个用户的导航会话。 这里面包含了很多关于用户正在寻找什么样产品的有用信息,你可以据此给用户推荐产品。

在Redis中使用下面的策略你可以很容义给这种模式建模:用户每访问一个页面,你都执行下面的指令: 

MULTI
RPUSH pagewviews.user:<userid> http://.....
EXPIRE pagewviews.user:<userid> 60
EXEC

如果用户所访问的页面空闲时间超过 60 秒,,那么这个key将会被删除,只有那些接下来少于60秒空闲的页面访问将会被保留。这个模式可以修改为使用计数指令 INCR 替换列表的 RPUSH.

*附录: Redis expires

*带有生存时间的key

一般来说Redis中创建key的是不带生存时间,如果你不使用类似DEL 命令明确删除它,这个key将会一直存在。

EXPIRE 命令族可以给指定的key关联生存时间 ,key会额外多占用一些内存。一旦一个key设置了生存时间,那么指定的时间消耗完后,Redis需要确保指令被删除。

key的生存时间可以被EXPIRE命令更新或PERSIST 命令删掉 。

*生存时间的精度

Redis 2.4 生存时间并不精准,一般在0到1秒多。

从Redis 2.6起,生存时间精度提高到0到1毫秒多 。

*过期和持久性

key的生存时间以绝对Unix时间戳的方式存储。这意味无论Redis是否运行,生存时间都会流逝。

服务器的时间必须稳定,这样生存时间才能更准确。如果在两个时间相差多的机器之间移动RDB文件,那么可能会出现所有的key在加载的时候都过期了。

运行的Redis也会不停的检查服务器的时间,如果你设置一个带有1000秒生存时间的key,然后你把服务器的时间向前调了2000秒,那么这个key会立刻过期,不是等1000秒后过期。

*Redis如何淘汰过期Key

Redis的key有两种过期淘汰的方式:被动方式、主动方式。

被动过期:用户访问某个key的时候,key被发现过期。

当然,被动方式过期对于那些永远也不会再次被访问的key并没有效果。不管怎么,这些key都应被过期淘汰,所以Redis周期性随机检查一部分被设置生存时间的key,那些已经过期的key会被从key空间中删除。

Redis每秒执行10次下面的操作:

  1. 从带有生存时间的key的集合中随机选20进行检查。
  2. 删除所有过期的key。
  3. 如20里面有超过25%的key过期,立刻继续执行步骤1。

这是一个狭义概率算法,我们假设我们选出来的样本key代表整个key空间,我们继续过期检查直到过期key的比例降到25%以下。

这意味着在任意时刻已经过期但还占用内存的key的数量,最多等于每秒最多写操作的四分之一。

*复制连接和AOF文件是如何处理过期

为了获得正确结果而不牺牲一致性。当一个key过期, 一个 DEL 操作同时在AOF文件和当前配置的所有的从服务器实例上执行。过期处理中心化在主实例上处理,没有出现一致性错误的机会。

但是,尽管连接到主服务器的从服务器不会独立地使key过期(但会等待来自主服务器的del),但它们仍持有完整的存在数据集中的过期状态,因此当从服务器被选为主服务器时,它将能够独立地使key过期,完全充当主服务器。