Redis 源码简洁剖析 13 - RDB 文件 (2)

采用 String 编码读取整个 zipmap 字符串,hashmap 字符串的格式为:

<zmlen><len>"foo"<len><free>"bar"<len>"hello"<len><free>"world"<zmend>

zmlen: 一个字节,Zipmap 的大小;如果>=254, 意味着 zipmap 的大小无法直接获取到,必须要遍历整个 zipmap 才能得到大小;

len: 字符串长度,1 或 5 个字节长度;如果第一个字节在 0~252 之间,那么长度为第一个字节;如果为 253, 那么接下来的 4 个字节表示长度;254 和 255 是无效值;

free:1 字节,表明 value 空闲的字节数;

zmend:0xff, 表示 Zipmap 的结尾;

Ziplist

采用 String 编码读取整个 ziplist 字符串,字符串的格式为:

<zlbytes><zltail><zllen><entry><entry><zlend>

zlbytes:4 字节无符号整数,表示 ziplist 占用的总字节数;

zltail:4 字节无符号整数 (little endian), 表示尾元素的偏移量;

zllen:2 字节无符号整数 (little endian), 表示 ziplist 中的元素个数,当元素个数大于 65535 时,无法用 2 字节表示,需要遍历列表获取元素个数;

entry:ziplist 中的元素;

zlend: 常量 (0xff), 表示 ziplist 的结尾;

entry 的格式:

<length-prev-entry><encoding><content>

lenth-prev-entry: 如果第一个字节<254, 则用 1bytes 表示长度;否则则用接下来的 4bytes(无符号整数)表示长度;

encoding

"00"开头:字符串,用接下来的 6bit 表示长度;

"01"开头:字符串,用接下来的 14bit 表示长度;

"10"开头:字符串,忽略本字节的 6bit, 用接下来的 32bit 表示长度;

"11000000"开头:整数,内容为接下来的 16bit;

"11010000"开头:整数,内容为接下来的 32bit;

"11100000"开头:整数,内容为接下来的 64bit;

"11110000"开头:整数,内容为接下来的 24bit;

"11111110"开头:整数,内容为接下来的 8bit;

"1111"开头 :整数,内容为接下来的 4bit 的值减去 1;

content
entry 内容,它的长度通过前面的 encoding 确定;

注意:元素长度、内容长度等都是采用 Little Endian 编码;

Intset

Intset 是一个整数组成的二叉树;当 set 的所有元素都是整形的时候,Redis 会采用该编码进行存储;Inset 最大可以支持 64bit 的整数,做为优化,如果整数可以用更少的字节数表示,Redis 可能会用 16~32bit 来表示;注意的是当插入一个长度不一样的整数时,有可能会引起整个存储结构的变化;

由于 Intset 是一个二叉树,因此它的元素都是排序过的;
采用 String 编码读取整个 intset 字符串,字符串的格式为:

<encoding><length-of-contents><contents>

encoding:32bit 的无符号整数;可选值包括 2、4 和 8;表示 inset 中的每个整数占用的字节数;

length-of-contents:32bit 无符号整数,表示 Intset 中包含的整数个数;

contents: 整数数组,长度由 length-of-contents 决定;

Sorted Set in Ziplist Encoding

采用 Ziplist 编码,区别在于用两个 entry 分别表示元素和分值;

Hashmap in Ziplist Encoding

采用 Ziplist 编码,区别在于用两个 entry 分别表示 key 和 value;

实际例子

本篇文章在本地安装并启动 Redis 服务,保存一个 string 类型的字符串,save 之后查看保存的 rdb 文件的二进制。

安装、启动 Redis

下载见:Redis Download

启动 Redis server:

src/redis-server&

Redis 源码简洁剖析 13 - RDB 文件

启动一个 Redis client:

src/redis-cli 保存字符串 127.0.0.1:6379> set name yano OK 保存 RDB 文件 127.0.0.1:6379> save 80277:M 15 Feb 2022 10:51:07.308 * DB saved on disk OK

在刚执行 redis-cli 的目录下,就生成了 rdb 文件,文件名是 dump.rdb。

分析 RDB 文件

使用 hexedit 命令分析 dump.rdb 文件:

hexedit dump.rdb

dump.rdb 文件内容如下:

Redis 源码简洁剖析 13 - RDB 文件

本篇文章只是分析 rdb 文件的基本结构和格式,只保存了一个最基础的 string。(图画了一个小时

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgwgdj.html