redis rdb mysql_Redis RDB 文件存储实现

2. 主从同步 (开启主从后,需要首先把master上的历史数据同步到slave,这时slave就会拉取master的rdb文件,然后解析加载rdb文件到内存)

rdb 保存了真实的redis数据,相当于mysql的innodb引擎的作用,可见其重要性非同一般。rdb也可以用来离线分析redis中数据分布情况。对于如此重要的文件,其中的数据存储格式我们当然要了如指掌,这样才能运筹帷幄,让可用性达到 4个9 (99.99%), 5个9(99.999%)

到目前为止,主要的rdb 版本是 v6  v7,从redis v3.2 版本开始使用 rdb v7,之前的redis v2.8 v3.0 使用的rdb版本都是rdb v6,文件的大致格式如下:

rdb v6

A 9 bytes magic "REDIS0006"  (9字节的redis标记,其中末四位是rdb版本信息)

key-value pairs (redis 真实的数据,以key value 成对存储)

An EOF opcode (代表结束的标记)

CRC64 checksum (用于对整个文件完整性校验的字符串)

rdb v7

A 9 bytes magic "REDIS0007" (9字节的redis标记,其中末四位是rdb版本信息)

Info field 1 (整个rdb文件中为了保存一些额外扩展信息而设计)

Info field 2

...

Info field N

Info field end-of-fields

key-value pairs (redis真实数据,以key value 成对存储)

An EOF opcode (代表结束的标记)

CRC64 checksum (用于对整个文件完整性校验的字符串)

先来看看其中真实数据是如何存储的,也就是上面的 key-value pairs ,使用过json 的同学都知道这个保存非常简单,比如:

{

"key1":"value1",

"key2":"value2",

"key3":"value3"

}

但这里并不是这样的结构,是一个连续的按字节存储的序列。如果连续存储,其中没有其他标记,如何区分 key 与 value的边界呢?换句话也就是如何知道key这个字串哪里结束,value从哪里开始呢?redis使用了提前记录字节长度的方式实现,也就是 key-len key value-len value 这种的形式,然后按对应长度读取字符。问题又来了,redis的key的最大长度是多少呢,value的最大长度是多少呢,好像也没有明确的限制,如果你不建议性能损失的话。

redis 使用了多字节的方式保存长度(1字节、2字节、5字节、9字节 ),根据不同长度使用不同的字节,但是这里面又会出现边界问题,当从rdb文件中读取2字节,如何区分这是1字节长度值+1字节key值,还是2字节的长度值呢?到了这里似乎更加迷茫,好像陷入了一个死循环,好像无解。

如果了解UTF8编码实现原理,你一定会有可行的解决方案。是的,我们先来看看一段redis源码,因为对一个系统最好的理解就是代码+注释,更何况redis中的注释也是相当的详细,基本一看就懂。

/* The current RDB version. When the format changes in a way that is no longer

* backward compatible this number gets incremented. */

#define RDB_VERSION 8

/* Defines related to the dump file format. To store 32 bits lengths for short

* keys requires a lot of space, so we check the most significant 2 bits of

* the first byte to interpreter the length:

*

* 00|XXXXXX => if the two MSB are 00 the len is the 6 bits of this byte

* 01|XXXXXX XXXXXXXX => 01, the len is 14 byes, 6 bits + 8 bits of next byte

* 10|000000 [32 bit integer] => A full 32 bit len in net byte order will follow

* 10|000001 [64 bit integer] => A full 64 bit len in net byte order will follow

* 11|OBKIND this means: specially encoded object will follow. The six bits

* number specify the kind of object that follows.

* See the RDB_ENC_* defines.

*

* Lengths up to 63 are stored using a single byte, most DB keys, and may

* values, will fit inside. */

#define RDB_6BITLEN 0

#define RDB_14BITLEN 1

#define RDB_32BITLEN 0x80

#define RDB_64BITLEN 0x81

#define RDB_ENCVAL 3

#define RDB_LENERR UINT64_MAX

/* When a length of a string object stored on disk has the first two bits

* set, the remaining six bits specify a special encoding for the object

* accordingly to the following defines: */

#define RDB_ENC_INT8 0 /* 8 bit signed integer */

#define RDB_ENC_INT16 1 /* 16 bit signed integer */

#define RDB_ENC_INT32 2 /* 32 bit signed integer */

#define RDB_ENC_LZF 3 /* string compressed with FASTLZ */

在上面的注释中有原作者的介绍,我在这里在按我自己的理解解释下:

1.

2.

3.

4.

未完待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值