通过EXPIRE 命令或者PEXPIRE 命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间( Time To Live , TTL) ,在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键: redis> SET key value OK redis> EXP 工RE key 5(integer) 1redis> GET key // 5 秒之内"value"redis> GET key // 5 秒之后(nil) 注意 与EXPlRE 命令和PEXPIRE 命令类似,客户端可以通过EXPlREAT 命令或PEXPlREAT命令,以秒或者毫秒精度给数据库中的某个键设置过期时间(expire time)。 redis> SET key value OK redis> EXPIREAT key 1377257300(integer) 1redis> TIME1)"1377257296"2)"296543"redis> GET key // 1377257300 之前"value"redis> TIME1)"1377257303"2)"230656 "redis> GET key // 1377257300 之后(nil) TTL 命令和PTTL 命令接受一个带有生存时间或者过期时间的键,返回这个键的剩余生存时间,也就是,返回距离这个键被服务器自动删除还有多长时间: redis> SET key va1ue OK redis> EXPlRE key 1000(integer) 1redis> TTL key (integer) 997redis> SET another_key another_value OK redis> TIME1) "1377333070 "2) "761687 "redis> EXPlREAT another key 1377333100(integer ) 1redis> TTL another key (integer) 10 设置过期时间 Redis 有四个不同的命令可以用于设置键的生存时间(键可以存在多久)或过期时间(键什么时候会被删除) : 虽然有多种不同单位和不同形式的设置命令,但实际上EXPlRE、PEXPlRE 、EXPIREAT三个命令都是使用PEXPlREAT 命令来实现的:无论客户端执行的是以上四个命令中的哪一个, 经过转换之后,最终的执行效果都和执行PEXPlREAT 命令一样。 def EXPIRE(key,ttl_in_sec): #将TTL 从秒转换成毫秒 ttl_in_ms = sec_to_ms(ttl_in_sec ) PEXPlRE(key, ttl_in_ms) 接着,PEXPlRE 命令又可以转换成PEXPlREAT 命令: def PEXPIRE(key,ttl_in_ms) : #获取以毫秒计算的当前UNIX 时间戳 now_ms = get_current_unix_timestamp_in_ms() #当前时间加上TTL,得出毫秒格式的键过期时间 PEXPlREAT(key,now_ms+ttl_in_ms) 并且,EXPlREAT命令也可以转换成PEXPlREAT命令: def EXPIREAT (key,expire_time_in_ sec): #将过期时间从秒转换为毫秒 expire_time_ in_ms = sec_to_ms (expire_time_in_sec) PEXPlREAT(key, expire_time_in_ms) 保存过期时间 redisDB结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典: 如下图展示了一个带有过期字典的数据库例子,在这个例子中,键空间保存了数据库中的所有键值对,而过期字典则保存了数据库键的过期时间。 过期字典将新增一个键值对, 其中键为message 键对象,而值则为1391234400000(2014年2月1日零时) ,如图9-13 所示。 图9-12 中的过期字典保存了两个键值对: redis> PEXPIREAT message 1 391234400000(integer) 1 过期字典将新增一个键值对,其中键为message键对象,而值则为1391234400000(2014年2月1日零时),如图9-13 所示。 以下是PEXPlREAT 命令的伪代码定义: def PEXPIREAT(key,expire_time_in_ms) : #如果给定的键不存在于键空间,那么不能设置过期时间if key not in redisDB.dict :return 0#在过期字典中关联键和过期时间 redisDB.expires[key]=expire_tirne_in_ms #过期时间设置成功return 1 移除过期时间 PERSIST命令可以移除一个键的过期时间: redis>PEXPlREAT message 1391234400000(integer) 1redis>TTL message (integer) 13893281redis> PERSIST message (integer) 1redis> TTL message (integer) - 1 PERSIST命令就是PEXPIREAT命令的反操作: PERSIST 命令在过期字典中查找给定的键,并解除键和值(过期时间)在过期字典中的关联。 redis> PERSIST book (integer) 1 数据库将更新成图9-14 所示的状态。 可以看到,当PERSIST命令执行之后,过期字典中原来的book键值对消失了,这代表数据库键book的过期时间已经被移除。 def PERSIST(key) : #如果键不存在,或者键没有设置过期时间,那么直接返回if key not in redisDB.expires:return 0#移除过期字典中给定键的键值对关联 redisDB.expires.remove(key) #键的过期时间移除成功return 1 计算并返回剩余生存时间 TTL 命令以秒为单位返回键的剩余生存时间, 而P TTL 命令则以毫秒为单位返回键的剩余生存时间: redis> PEXPIREAT alphabet 1385877600000(integer) 1redis> TTL alphabet (integer) 85 49007redis> PTTL alphabet (integer) 8549001011 TTL 和PTTL 两个命令都是通过计算键的过期时间和当前时间之间的差来实现的,以下 def PTTL (key) : #键不存在于数据库if key not in redisDb.dict: return -2#尝试取得键的过期时间 #如果键没有设置过期时间,那么expire_time_in_ms将为None expire_time_in_ms = redisDB.expires.get(key) #键没有设置过期时间if expire time in ms is None: return -1#获得当前时间 now_ms = get_current_unix _timestamp_in_ms () #过期时间减去当前时间, 得出的差就是键的剩余生存时间 return(expire_time_in_ms - now_ms) def TTL(key): #获取以毫秒为单位的剩余生存时间 ttl_in_ms = PTTL (key )if ttl_in_ms < 0: #处理返回值为2 和斗的情况 return ttl_in_mselse: #将毫秒转换为秒 return ms_to_sec(ttl_in_ms) 举个例子,对于一个过期时间为1385877600000(2013年12月1日零时)的键alphabet来说: 过期键的判定 通过过期字典,程序可以用以下步骤检查一个给定键是否过期: def is expired(key) : #取得键的过期时间 expire_time_in_ms = redisDB.expires.get(key) #键没有设置过期时间if expire_time_in_ms is none:return false#取得当前时间的UNIX 时间戳 now_ms = get_current_unix_timestamp_in_ms() #检查当前时间是否大于键的过期时间if now_ms > expire time_in_ms : #是,键已经过期return trueelse : # 否,键未过期return false 举个例子,对于一个过期时间为1385877600000 (2013年12月1日零时)的键alphabet来说: 如果当前时间为1383282000000 (2013 年II 月1 日零时),那么调用is_expired ( alphabet ) 将返回False ,因为当前时间小于alphabet 键的过期时间。 注意 |
|