官方文档:https://redis.io/commands/expire

 key上设置一个过期时间(timeout),一旦时间到了,这个key将会被自动删除。这种特性术语通常叫做Redis的不稳定性。

        一旦设置了过期时间,这个key只能被命令清除、删除或者重写其内容。这些命令包含del、set、getset以及所有的*store命令。这些命令只能改变key对应的value的存储值而不改变过期时间的设置。举个例子,使用incr改变key对应的value、使用lpush添加一个新的元素到lists中、使用hset设置field对应value的值等等这些操作都不影响已经对key设置的过期时间的属性。

       设置了过期时间的key依然可以使用persist命令重新持久化。

       如果key设置了过期时间,并且尚未被删除,使用rename命令重新命名后,该过期时间将转移到新的key上。事实上,rename命令重命名key后,原始的key对应属性全部发生转移。

       如果调用expire或者pexpire时传给一个负值作为参数以及expireat或者pexpireat调用的时候时间戳已经过去,那么该key将直接被删除而不是等待过期。

       刷新过期时间

       对一个设置了过期时间的key仍然可以调用expire更新其过期时间。这

       新版本和低于2.1.3版本的区别   

       在2.1.3版本之前,如果设置时间触发了修改value的工作,则key将会被删除,这会影响主从复制,之后的版本已经做了修正。

       返回值

       返回一个整数值

        1)如果过期时间被设置成功,返回1

        2)如果设置失败或者key不存在,则返回0

Java代码 

  1. 127.0.0.1:6379> flushdb  

  2. OK  

  3. 127.0.0.1:6379> set mykey "Hello"  

  4. OK  

  5. 127.0.0.1:6379> expire mykey 20  

  6. (integer) 1  

  7. 127.0.0.1:6379> ttl mykey  

  8. (integer) 16  

  9. 127.0.0.1:6379> expire m 10  

  10. (integer) 0  

  11. 127.0.0.1:6379> ttl mykey  

  12. (integer) -2  

  13. 127.0.0.1:6379> ttl m  

  14. (integer) -2  

  假设你有一个web服务并且对用户访问过的最新N页数据感兴趣,每60秒记录一次并放在lists中。这样整个list中就会包含有用的信心,如用户对哪个产品感兴趣。这在Redis中非常容易实现:

Java代码  收藏代码

  1. MULTI  

  2. RPUSH pagewviews.user:<userid> http://.....  

  3. EXPIRE pagewviews.user:<userid> 60  

  4. EXEC  

        如果用户超过60秒钟未访问网站,则这个key就会被删除,最终只能记录后来的。

        这个模式也可以使用incr代替rpush实现:

Java代码  

  1. multi  

  2. incr     pageview.user:<userid>:<productid> http:......  

  3. expire   pageview.user:<userid>:<productid> 60  

  4. exec  

       Redis Expires

       keys的过期时间,Redis并没有设置有效时间,换句话说,这个key将会一直存在直到用户显式删除,如del命令。expire的命令家族将会给key设置一个过期时间,这使得key存储将花费更多的时间。一旦被设置了过期时间,时间一到,key将会被删除。

       expire命令可以重新设置key的存活时间。persist命令则会持久化key。

Java代码  

  1. 127.0.0.1:6379> flushdb  

  2. OK  

  3. 127.0.0.1:6379> set str a  

  4. OK  

  5. 127.0.0.1:6379> ttl str  

  6. (integer) -1  

  7. 127.0.0.1:6379> expire str 20  

  8. (integer) 1  

  9. 127.0.0.1:6379> ttl str  

  10. (integer) 13  

  11. 127.0.0.1:6379> set str b  

  12. OK  

  13. 127.0.0.1:6379> ttl str  

  14. (integer) -1  

  15. 127.0.0.1:6379> expire str 100  

  16. (integer) 1  

  17. 127.0.0.1:6379> ttl str  

  18. (integer) 97  

  19. 127.0.0.1:6379> persist str  

  20. (integer) 1  

  21. 127.0.0.1:6379> ttl str  

  22. (integer) -1  

        Expire的精度

       在Redis 2.4过期时间的设置并不是高精度的,误差在0到1秒的误差。从2.6开始精度提高到0到1毫秒。

       expire 和persist

       过期时间的设置是以unix时间的绝对秒存储的(2.6以上版本是绝对毫秒)。也就是说,即使Redis 服务已经停止了,时间也还在流逝。

       为了精确度,计算机时间必须保持稳定。如果将rdb文件在两台有较大时差的服务器上移动,有趣的事情将会发生,就像所有的keys均被设置了过期时间一样。

       即使实在同一台正在运行的数据库实例上,它将总是检查计算机的时间设置。如果你设置某个key的过期时间是1000秒后,然后设置系统时间延后2000秒,那么该key则立即被删除而不是由1000秒的存活时间。

       Expire在Redis中keys的实现

       在实现方式上,有两中方法:被动和主动的。

       被动方式是指,设置了过期时间的keys只有在客户端访问的时候才会被发现并对其执行删除从操作。

       这种方法当然是不够好,因为有些keys是不会被再次访问到的。所以定期随机地检测keys的,对过期的keys执行清楚操作,以便于存key空间中删除。

       明确来说,Redis每分钟执行10次检测:

       1)在所有的建中随机找到20个设置了过期时间的keys

       2)删除其中已经过期的keys

       3)如果超过25%的keys被删除,那么从1)开始再次执行,知道被删除的keys比例降低到25%以下

       这意味着,任何给定的时刻,被过期删除的keys的数量最大等于每秒钟写操作执行次数除以4的最大值。

       过期清楚keys时复制链接和AOF文件的处理  

       为了保持一致性并获得较好的性能。当一个key过期时,删除AOF文件的del操作在master和slaves之间同步执行,这样不存在一致性错误的可能。

       然而,slaves是不可以单独的执行del操作的,而是等待master发送过来的del指令,而此时会携带全部的过期设置信息,所以当slave被选中成为master时,它就可以单独地清楚过期的keys,完全像一个master一样。