RDB parse
1 RDB 文件的结构和编码方式
1.1 RDB 文件的整体结构
RDB 文件划分为文件头、元属性区、数据区、结尾四个部分:
文件头包含 Magic Number 和版本号两部分
RDB文件以 ASCII 编码的 'REDIS' 开头作为魔数(File Magic Number)表示自身的文件类型
接下来的 4 个字节表示 RDB 文件的版本号,RDB 文件的版本历史可以参考:RDB_Version_History
元属性区保存诸如文件创建时间、创建它的 Redis 实例的版本号、文件中键的个数等信息
数据区按照数据库来组织,开头为当前数据库的编号和数据库中的键个数,随后是数据库中各键值对。
1.2 文件头
$ xxd bin/data/dump.rdb | head -n 1
00000000: 5245 4449 5330 3030 36fe 0002 3772 6564 REDIS0006...7red1.2.1 代码
1.2.2 RDB 版本
1.3 元属性区
1.3.1 RDB content
1.3.2 code
internal/rdb/structure/string.go:ReadString
1.4 数据区
数据区开头为数据库编号、数据库中键个数、有 TTL 的键个数,接下来为若干键值对
2 RDB 中的编码
2.1 LengthEncoding
Length Encoding 是一种可变长度的无符号整型编码,因为通常被用来存储字符串长度、列表长度等长度数据所以被称为 Length Encoding.
如果前两位是 00 那么下面剩下的 6 位就表示具体长度
如果前两位是 01 那么会再读取一个字节的数据,加上前面剩下的6位,共14位用于表示具体长度
如果前两位是 10
* 如果剩下的 6 位都是 0 那么后面 32 位表示具体长度(4 个字节)
* 如果剩下的 6 位为 000001, 那么后面的 64 位表示具体长度(8 个字节)
如果前两位是 11 表示为使用字符串存储整数的特殊编码
11 开头的Length Encoding 称为「特殊长度编码」,其它 3 种称为 「普通长度编码」
internal/rdb/structure/length.go:readEncodedLength
2.2 StringEncoding
RDB 的 StringEncoding 可以分为三种类型:
简单字符串编码
整数字符串
LZF 压缩字符串
internal/rdb/structure/string.go:ReadString
StringEncode 总是以 LengthEncoding 开头, 普通字符串编码由普通长度编码 + 字符串的 ASCII 序列组成, 整数字符串和 LZF 压缩字符串则以特殊长度编码开头。
2.3 ListEncoding & SetEncoding & HashEncoding
ListEncoding 开头为一个普通长度编码块表示 List 的长度,随后是对应个数的 StringEncoding 块。
SetEncoding 与 ListEncoding 完全相同。
HashEncoding 开头为一个普通长度编码块表示哈希表中的键值对个数,随后为对应个数的:Key StringEncoding + Value StringEncoding 组成的键值对。
\
传送门
Last updated