redis数据更新和持久化

103 阅读3分钟

一、数据有效期

(一) 更新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时间戳)。

image.png

二、过期key的删除策略

  1. 定时删除:设置 key 的同时创建一个定时器,让定时器在 key 的过期时间到的时候,立即执行。

    缺点:

    • 当过期 key 多的时候,会把 CPU 耗在删除上,影响吞吐率
    • 创建定时器需要用到时间事件(无序链表),查找一个事件的复杂度是 O(N)
  2. 惰性删除:不管它,等尝试读取出 key 的时候,先判断 key 是否过期,再进行操作。

    缺点:可能会导致某些 key 一直存在,无法被删除,一直占用内存

  3. 定期删除:隔一段时间进行一次检查,删除里面的过期 key。由算法决定删除多少,以及检测多少个数据库。

    实现:每次从一定量的数据库中选取一定量的随机key进行检查,删除过期的key。(可能随机key没有过期就不删除)

三、持久化

(一) RDB持久化

1. 创建RDB文件

RDB 是通过保存某一时刻 Redis 的内存数据快照来实现持久化的。Redis 会将内存中的数据结构序列化成一个 .rdb 文件。

创建RDB文件的时候,会对每一个key进行检查,已经过期的不会保存到RDB中

快照可以通过两种方式生成:

  • 定时触发(根据 save 配置)
  • 手动执行 SAVEBGSAVE 命令

2. 载入RDB文件

会根据服务器来进行不同的操作

  • 主服务器: 会对文件中的key进行检查,如果没过期就载入到数据库中,过期的会被忽略。
  • 从服务器:无论是否过期,都会被载入进来。不过主从服务器在进行数据同步的时候,会把从服务器的数据库情况,因此一般也不会产生太大的影响。

(二)AOF文件

  • 如果一个 key 已过期但还未被删除,Redis 不会立刻在 AOF 中记录它的删除。

    • 因为 Redis 的键值是懒惰删除(惰性淘汰 + 定期淘汰);
    • 没访问到它,Redis 就不会做多余工作;
    • 所以过期只是标记,不立即写入 DEL
  • 一旦该过期键被访问触发删除(惰性)或定时删除,Redis 才会:

    • 执行删除(从内存移除 key);
    • 并在 AOF 文件中追加 DEL 命令,记录这次删除操作**。
  • 举例说明:

    • 客户端发送 GET message

    • message 这个 key 已过期;

    • Redis:

      • 从数据库中删除该键;
      • DEL message 写入 AOF 文件;
      • 给客户端返回 nil。