通过EXPIRE命令或者PEXPIRE命令,客户端可以以秒或者毫秒精度为数据库中的某个键设置生存时间(Time To Live,TTL),在经过指定的秒数或者毫秒数之后,服务器就会自动删除生存时间为0的键。
与EXPIRE命令和PEXPIRE命令类似,客户端可以通过EXPIREAT(多了个AT)命令或PEXPIREAT命令,以秒或者毫秒精度给数据库中的某个键设置过期时间。
过期时间是一个UNIX时间戳,当键的过期时间来临时,服务器就会自动从数据库中删除这个键。
虽然有多种不同单位和不同形式的设置命令,但实际上EXPIRE、PEXPIRE、EXPIREAT这三个命令都是使用PEXPIREAT命令来实现的:无论客户端执行的是以上四个命令中的哪个,经过转换之后,最终的执行效果都和执行PEXPIREAT命令一样。
保存过期时间
redisDb结构的expires字典保存了数据库中所有键的过期时间,我们称这个字典为过期字典:
- 过期字典的键是一个指针,这个指针指向键空间中的某个键对象,也就是某个数据库键。
- 过期字典的值是一个long long类型的整数,这个整数保存了键所指向的数据库键的过期时间——一个毫秒精度的UNIX时间戳。
过期键删除策略
如果一个键过期了,那么它什么时候会被删除呢?这个问题有三种可能的答案,它们分别代表了三种不同的删除策略:
- 定时删除:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。这种策略对CPU最不友好,对内存最友好。
- 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键。这种策略对CPU最友好,对内存最不友好(内存泄露)。
- 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。这种策略相当于对第一个和第二个策略的整合和折中。
在这三种策略中,第一种和第三种为主动删除策略,而第二种则为被动删除策略。
定期删除策略的难点是确定删除操作执行的时长和频率,服务器必须根据情况,合理地设置删除操作的执行时长和执行频率。
Redis的过期键删除策略
Redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可以很好地在合理使用CPU时间和避免浪费内存空间之间取得平衡。
AOF、RDB和复制功能对过期键的处理
RDB:
- 执行SAVE命令或者BGSAVE命令所产生的新RDB文件不会包含已经过期的键。
AOF:
- 执行BGREWRITEAOF命令所产生的重写AOF文件不会包含已经过期的键。
- 当一个过期键被删除之后,服务器会追加一条DEL命令到现有AOF文件的末尾,显式地删除过期键。
主从复制:
- 当主服务器删除一个过期键之后,它会向所有从服务器发送一条DEL命令,显式地删除过期键。
- 从服务器即使发现过期键也不会自作主张地删除它,而是等待主节点发来DEL命令,这种统一、中心化的过期键删除策略可以保证主从服务器数据的一致性。
版权声明:本文为sinat_30955745原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。