Redis Expire
命令设置 key
的过期时间(seconds)。
设置的时间过期后,key 会被自动删除。带有超时时间的 key 通常被称为易失的(volatile)。
超时时间只能使用删除 key 或者覆盖 key 的命令清除,包括 DEL, SET, GETSET 和所有的 *STORE
命令。 对于修改 key 中存储的值,而不是用新值替换旧值的命令,不会修改超时时间。例如,自增 key 中存储的值的 INCR , 向list中新增一个值 LPUSH, 或者修改 hash 域的值 HSET ,这些都不会修改 key 的过期时间。
通过使用 PERSIST 命令把 key 改回持久的(persistent) key,这样 key 的过期时间也可以被清除。
key使用 RENAME 改名后,过期时间被转移到新 key 上。
已存在的旧 key 使用 RENAME 改名,那么新 key 会继承所有旧 key 的属性。例如,一个名为 KeyA 的 key 使用命令 RENAME Key_B Key_A
改名,新的 KeyA 会继承包括超时时间在内的所有 Key_B 的属性。
特别注意,使用负值调用 EXPIRE/PEXPIRE 或使用过去的时间调用 EXPIREAT/PEXPIREAT ,那么 key 会被删除 deleted 而不是过期。 (因为, 触发的key event 将是 del
, 而不是 expired
).
*语法
redis Expire
命令基本语法如下:
redis 127.0.0.1:6379> EXPIRE key seconds
*刷新过期时间
已经设置过期的key,可以调用 EXPIRE 重新设置。在这种情况下 key 的生存时间被更新为新值。因为这个特性出现了很多有用的应用,本文下面的 Navigation session pattern 部分就是一个例子。
*Expire 在 Redis 2.1.3 之前版本的不同
在 2.1.3 之前的版本使用 Expire 修改已经设置过生存时间的 key,将会和删掉 key 有同样的效果。这是被已被修复的复制层的限制所需要的特性。这种情况下 EXPIRE 将会返回 0。
*返回值
整数:
1
设置超时成功。0
key
不存在。
*例子
"OK"redis> EXPIRE mykey 10
(integer) 1redis> TTL mykey
(integer) 10redis> SET mykey "Hello World"
"OK"redis> TTL mykey
(integer) -1
*模式: 导航 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 被删除。
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次下面的操作:
- 从带有生存时间的 key 的集合中随机选 20 进行检查。
- 删除所有过期的key。
- 如20里面有超过25%的key过期,立刻继续执行步骤1。
这是一个狭义概率算法,我们假设我们选出来的样本 key 代表整个 key 空间,我们继续过期检查直到过期 key 的比例降到 25% 以下。
这意味着在任意时刻已经过期但还占用内存的 key 的数量,最多等于每秒最多写操作的四分之一。
*复制连接和 AOF 文件是如何处理过期
为了获得正确结果而不牺牲一致性。当一个 key 过期时,DEL 操作会同时在AOF文件和当前配置的所有的从服务器实例上执行。过期处理中心化在主实例上处理,没有出现一致性错误的机会。
但是,尽管连接到主服务器的从服务器不会独立地使 key 过期(但会等待来自主服务器的 del),但它们仍持有完整的存在数据集中的过期状态,因此当从服务器被选为主服务器时,它将能够独立地使 key 过期,完全充当主服务器。