RDB持久化

redis是内存数据库,为了将数据存储到硬盘中,提供了RDB持久化功能。RDB可以手动执行也可以根据服务器配置定期执行。SAVE和BGSAVE命令可以生成RDB文件,前者阻塞后者非阻塞。如果服务器开启AOF持久化通常优先使用AOF。

设置保存条件,如

save 900 1

表示服务器在900秒内对数据库进行至少一次修改,BGSAVE命令就会执行。

服务器状态还维持了一个dirty计数器和lastsave属性

struct redisServer{
    //修改计数器
    long long dirty;

    //上次执行保存时间
    time_t lastsave;
}

dirty计数器对服务器修改命令进行计数,lastsave记录上次save时间的timestamp。

文件结构

RDB文件包含的部份为下:

REDIS|db_version|databases|EOF|check_sum

文件开头是REDIS五个字符,db_version用4字节表示文件版本,EOF表示数据库正文内容结束,check_sum表示RDB文件是否损坏或出错。

database部份可以保存任意多个非空数据库,每个database结构如下

SELECTDB|db_number|key_value_pairs

SELECTDB的长度为1字节,表示接下来读入数据库号码。db_number保存的数据库号码,根据读取的字段切换数据库。key_value_pairs保存部份键值对数据和过期时间(如果该字段含有过期时间),根据条件不同,该字段的长度不同。

不带过期时间的RDB文件的key_value_pairs由三个部份组成,TYPE,key和value。带有过期时间的多EXPIRETIME_MS和ms两个字段,表示标志位和过期时间。

value的编码需要保存多种类型的对象。

  • 字符串对象:大于20字节会压缩(LZF算法)保存
  • 列表对象:list_length字段记录列表长度,后续每个item保存每个对象
  • 集合对象:set_size表示集合大小,后续每个elem保存每个对象
  • 哈希表对象:hash_size表示大小,后续key和value连续保存
  • 有序集合对象:sorted_set_size表示有序集合大小,后续每个元素保存对象
  • INTSET编码:转换为字符串保存
  • ZIPLIST编码列表:转换为字符串对象并保存

RDB文件用于保存和还原redis服务器所有数据库中所有键值对
SAVE命令由服务器进程直接操作保存,会阻塞
BGSAVE由子进程操作保存,不会阻塞
服务器状态中由save选项的保存条件,当满足时会自动触发BGSAVE
RDB是二进制文件,od工具分析