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工具分析