Redis数据过期策略探究(一)

2015-07-16 12:09:26 · 作者: · 浏览: 5

通过EXPIRE key seconds命令来设置数据的过期时间。返回1表明设置成功,返回0表明key不存在或者不能成功设置过期时间。


在key上设置了过期时间后key将在指定的秒数后被自动删除。被指定了过期时间的key在Redis中被称为是不稳定的。


当key被DEL命令删除或者被SET、GETSET命令重置后与之关联的过期时间会被清除。


redis 127.0.0.1:6379> set mykey "test expire"
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 97
redis 127.0.0.1:6379> ttl mykey
(integer) 93
redis 127.0.0.1:6379> set mykey "test expire reset"
OK
redis 127.0.0.1:6379> ttl mykey
(integer) -1


redis 127.0.0.1:6379> set mykey "test expire"
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 98
redis 127.0.0.1:6379> ttl mykey
(integer) 91
redis 127.0.0.1:6379> getset mykey "test expire reset"
"test expire"
redis 127.0.0.1:6379> ttl mykey
(integer) -1


这也意味着仅从概念上更新了存储在key中的值而没有用全新的值替换key原有值的所有操作都不会影响在该key上设置的过期时间。例如使用INCR命令增加key的值或者通过LPUSH命令在list中增加一个新的元素或者使用HSET命令更新hash字段的值都会回清除原有的过期时间设置。


redis 127.0.0.1:6379> set mykey 1
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 95
redis 127.0.0.1:6379> incr mykey
(integer) 2
redis 127.0.0.1:6379> ttl mykey
(integer) 77


redis 127.0.0.1:6379> lpush listkey 1
(integer) 1
redis 127.0.0.1:6379> expire listkey 100
(integer) 1
redis 127.0.0.1:6379> ttl listkey
(integer) 94
redis 127.0.0.1:6379> lpush listkey 2
(integer) 2
redis 127.0.0.1:6379> ttl listkey
(integer) 82


redis 127.0.0.1:6379> hmset hashkey name "redis" passwd "redis"
OK
redis 127.0.0.1:6379> expire hashkey 100
(integer) 1
redis 127.0.0.1:6379> ttl hashkey
(integer) 95
redis 127.0.0.1:6379> hset hashkey? passwd "redis.vs.mysql"
(integer) 0
redis 127.0.0.1:6379> ttl hashkey
(integer) 66


当然也可通过PERSIST命令清除已设置的过期时间重新将key变为持久的。


redis 127.0.0.1:6379> set mykey 'test clear expire'
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 96
redis 127.0.0.1:6379> persist mykey
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) -1


若key被RENAME命令重命名则与之关联的过期时间将传递到新名称的key。


redis 127.0.0.1:6379> get mykeynew
(nil)
redis 127.0.0.1:6379> set mykey 'test expire transfer'
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 96
redis 127.0.0.1:6379> rename mykey mykeynew
OK
redis 127.0.0.1:6379> ttl mykey
(integer) -1
redis 127.0.0.1:6379> ttl mykeynew
(integer) 80


若key被RENAME命令重写,比如本存在名为mykey_a和mykey_b的key一个RENAME mykey_b mykey_a命令将mykey_b重命名为本已存在的mykey_a那么无论mykey_a原来的设置如何都将继承mykey_b的所有特性,包括过期时间设置。


redis 127.0.0.1:6379> set mykey_b 'b'
OK
redis 127.0.0.1:6379> set mykey_a 'a'
OK
redis 127.0.0.1:6379> expire mykey_b 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey_b
(integer) 93
redis 127.0.0.1:6379> ttl mykey_a
(integer) -1
redis 127.0.0.1:6379> rename mykey_b mykey_a
OK
redis 127.0.0.1:6379> ttl mykey_b
(integer) -1
redis 127.0.0.1:6379> ttl mykey_a
(integer) 66


EXPIRE key seconds应用于一个已经设置了过期时间的key上时原有的过期时间将被更新为新的过期时间


redis 127.0.0.1:6379> set mykey 'test expire update'
OK
redis 127.0.0.1:6379> expire mykey 100
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 95
redis 127.0.0.1:6379> expire mykey 1000
(integer) 1
redis 127.0.0.1:6379> ttl mykey
(integer) 998


附录:
key的过期时间
通常,Redis key被创建时不会自动关联过期时间,key将长久存在,除非通过DEL等命令显示的删除。EXPIRE命令簇可以为指定的key关联一个过期时间,代价是一点额外的内存开销。当key被设置了过期时间后Redis要保证在超时时移除该key。key的过期时间可被EXPIRE命令更新或者被PERSIST命令完全移除。

过期时间的精度
Redis2.4中expire精度不高,通常在0到1秒间,Redis2.6以后expir