RDB parse

1 RDB 文件的结构和编码方式

1.1 RDB 文件的整体结构

RDB 文件划分为文件头、元属性区、数据区、结尾四个部分:

  • 文件头包含 Magic Number 和版本号两部分

    • RDB文件以 ASCII 编码的 'REDIS' 开头作为魔数(File Magic Number)表示自身的文件类型

    • 接下来的 4 个字节表示 RDB 文件的版本号,RDB 文件的版本历史可以参考:RDB_Version_History

  • 元属性区保存诸如文件创建时间、创建它的 Redis 实例的版本号、文件中键的个数等信息

  • 数据区按照数据库来组织,开头为当前数据库的编号和数据库中的键个数,随后是数据库中各键值对。

查看 RDB 文件内容

  • (1) xxd 命令,如:xxd dump.rdb

  • (2) vim 打开然后在命令模式中输入::%!xxd 开启二进制编辑

xxd 使用十六进制展示,两个十六进制数为一个字节,两个字节显示为一列

1.2 文件头

$ xxd bin/data/dump.rdb  | head -n 1
00000000: 5245 4449 5330 3030 36fe 0002 3772 6564  REDIS0006...7red

1.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