RDB 是什么
Redis *.rdb 是内存的二进制文件,通过 *.rdb 能够完全回复 Redis 的运行状态。
![](
20220218175013.png?x-oss-process=style/yano)
详细信息可参考:Redis RDB Dump File Format。
HeaderRDB 文件的头部占用 9bytes,前 5bytes 为 Magic String, 后 4bytes 为版本号;
52 45 44 49 53 #"REDIS", 就像 java 的 class 文件以 0xCAFEBABE 开头一样 30 30 30 36 #RDB 版本号,30 表示‘0’,版本号为 0006=6注意:版本号是字符串而不是整型:
snprintf(magic,sizeof(magic),"REDIS%04d",RDB_VERSION);RDB_VERSION 详细信息可参考:Redis RDB Version History
FE 开头表示后跟表示 DB Selector,例如:
FE 00 #FE 表明数据库的哪个 db,此处为 db0注意:DB Selector 长度不固定,具体的编码方式请参见后文的 Length 编码。
AUX FieldsFA 开头表示后跟 AUX Fields, 记录生成 Dump 文件的 Redis 相关信息,例如 redis-ver、redis-bits、used-mem、aof-preamble 和 repl-id 等。这些信息采用 String 编码;
注意:redis3.0 版本的 RDB 版本号为 6,redis3.2 的版本号为 7;
Key-Valuekey-value 有三种格式:
expire 为 second
FD $unsigned int #失效时间(秒),4 个字节 $value-type #1 个字节,表明数据类型:set,map 等 $string-encoded-key #key 值,字符串类型 $encoded-value #value, 编码方式和类型有关
expire 为 millisecond
FC $unsigned long #失效时间(毫秒),8 个字节 $value-type #数据类型,1 个字节 $string-encoded-key #key,字符串类型 $encoded-value #value, 编码方式和类型有关
无 expire
$value-type #数据类型,1 个字节 $string-encoded-key #key,字符串类型 $encoded-value #value, 编码方式和类型有关 Footer FF #RDB 文件的结束 8byte checksum #循环冗余校验码,Redis 采用 crc-64-jones 算法,初始值为 0 编码算法说明 Length 编码长度采用 BigEndian 格式存储,为无符号整数
如果以"00"开头,那么接下来的 6 个 bit 表示长度;
如果以“01”开头,那么接下来的 14 个 bit 表示长度;
如果以"10"开头,该 byte 的剩余 6bit 废弃,接着读入 4 个 bytes 表示长度 (BigEndian);
如果以"11"开头,那么接下来的 6 个 bit 表示特殊的编码格式,一般用来存储数字:
0 表示用接下来的 1byte 表示长度
1 表示用接下来的 2bytes 表示长度;
2 表示用接下来的 4bytes 表示长度;
String 编码该编码方式首先采用 Length 编码 进行解析:
从上面的Length 编码知道,如果以"00","01","10"开头,首先读取长度;然后从接下来的内容中读取指定长度的字符;
如果以"11"开头,而且接下来的 6 个字节为“0”、“1”和“2”, 那么直接读取接下来的 1,2,4bytes 做为字符串的内容(实际上存储的是数字,只不过按照字符串的格式存储);
如果以“11”开头,而且接下来的 6 个字节为"3", 表明采用 LZF 压缩字符串格式:
LZF 编码的解析步骤为:
首先采用Length 编码读取压缩后字符串的长度 clen;
接着采用Length 编码读取压缩前的字符串长度;
读取 clen 长度的字节,并采用 lzf 算法解压得到原始的字符串
Score 编码读取 1 个字节,如果为 255,则返回负无穷;
如果为 254,返回正无穷;
如果为 253,返回非数字;
否则,将该字节的值做为长度,读取该长度的字节,将结果做为分值;
Value 编码Redis 中的 value 编码包括如下类型:
其中 String 编码在前面已经介绍过,接下来逐一介绍其他的 9 种编码方式;
List首先用 Length 编码读取 List 的长度 lsize;
采用 String 编码读取 lsize 个字符串
Set同 List
Sorted Set首先用 Length 编码读取 Sorted Set 的长度 zsize;
采用 String 编码读取字符串,采用 Score 编码读取分值;
循环读取 zsize 次;
Hash采用 Length 编码读取 Hash 的大小 hsize;
采用 String 编码读取 2*hsize 的字符串,按照 key,value 的方式组装成 Map
Zipmap用于存储 hashmap,Redis2.6 之后,该编码被废弃,转而采用 Ziplist 编码;