一、数据有效期
(一) 更新key的生存时间或过期时间
1.设置过期时间
EXPIRE <key> <ttl>:秒。把key的生存时间设置为ttl秒PEXPIRE <key> <ttl>:毫秒EXPIREAT <key> <timestamp>: 把key的过期时间设置为timestamp所指定的秒数时间戳PEXPIREAT <key> <timestamp>-
EXPIREAT key 1377257300 EXPIRE key 5 // 5s后过期 - 注意:上面四个,实际上都是通过调用
PEXPIREAT来实现的
2. 移除过期时间
PERSIST <key>
3. 查看剩余时间
TTL: 以秒为单位返回剩余生存时间PTTL: 以毫秒为单位返回剩余生成时间
(二) redis如何记录过期时间
typedef struct redisDb{
// 过期字典,保存着key的过期时间
dict* expires;
}
过期字典的key是一个指针,指向键空间的某个键对象。
过期字典的valie是一个longlong,保存这个key的过期时间(毫秒精度的UNIX时间戳)。
二、过期key的删除策略
-
定时删除:设置 key 的同时创建一个定时器,让定时器在 key 的过期时间到的时候,立即执行。
缺点:
- 当过期 key 多的时候,会把 CPU 耗在删除上,影响吞吐率
- 创建定时器需要用到时间事件(无序链表),查找一个事件的复杂度是 O(N)
-
惰性删除:不管它,等尝试读取出 key 的时候,先判断 key 是否过期,再进行操作。
缺点:可能会导致某些 key 一直存在,无法被删除,一直占用内存
-
定期删除:隔一段时间进行一次检查,删除里面的过期 key。由算法决定删除多少,以及检测多少个数据库。
实现:每次从一定量的数据库中选取一定量的随机key进行检查,删除过期的key。(可能随机key没有过期就不删除)
三、持久化
(一) RDB持久化
1. 创建RDB文件
RDB 是通过保存某一时刻 Redis 的内存数据快照来实现持久化的。Redis 会将内存中的数据结构序列化成一个 .rdb 文件。
创建RDB文件的时候,会对每一个key进行检查,已经过期的不会保存到RDB中
快照可以通过两种方式生成:
- 定时触发(根据
save配置) - 手动执行
SAVE或BGSAVE命令
2. 载入RDB文件
会根据服务器来进行不同的操作
- 主服务器: 会对文件中的key进行检查,如果没过期就载入到数据库中,过期的会被忽略。
- 从服务器:无论是否过期,都会被载入进来。不过主从服务器在进行数据同步的时候,会把从服务器的数据库情况,因此一般也不会产生太大的影响。
(二)AOF文件
-
如果一个 key 已过期但还未被删除,Redis 不会立刻在 AOF 中记录它的删除。
- 因为 Redis 的键值是懒惰删除(惰性淘汰 + 定期淘汰);
- 没访问到它,Redis 就不会做多余工作;
- 所以过期只是标记,不立即写入
DEL。
-
一旦该过期键被访问触发删除(惰性)或定时删除,Redis 才会:
- 执行删除(从内存移除 key);
- 并在 AOF 文件中追加
DEL命令,记录这次删除操作**。
-
举例说明:
-
客户端发送
GET message; -
message这个 key 已过期; -
Redis:
- 从数据库中删除该键;
- 把
DEL message写入 AOF 文件; - 给客户端返回 nil。
-