Redis设计与实现(九)RDB持久化

Redis是一个键值对的服务器,默认16个数据库,每一个数据库都是基于内存的,一旦关机就会数据丢失,为了保证数据可以存在,这边使用了持久化技术RDB和AOF,先讲的是RDB。

RDB可以手动执行也可以根据配置周期性执行,RDB生成的文件是一个二进制的文件而且是经过压缩的。Redis服务器有RDB读取的功能,所以可以通过RDB文件进行恢复。

有两个命令可以对Redis进行RDB持久化,一个是SAVE 一个是BGSAVE。

SAVE方法会直接阻塞服务器的进程,而BGSAVE会创建出一个子进程来对数据库进行持久化,主进程依然可以进行命令的请求。

rdb.c中的rdbServer函数完成RDB文件的创建。两个order的伪代码如下:

 

 和手动执行RDB持久化的方法不同,载入RDB的操作是服务器开启的时候自动进行的。当出现DB loader from disk: xxxxxx这个的时候就开始进行了RDB的载入操作。但是,但是,如果开启的是AOF会先执行AOF的载入,没有AOF再进行RDB。

使用SAVE执行RDB的持久化操作会阻断进程,直到完成之后才会重新接受消息。BGSAVE执行RDB的情况会开一个新的进程,但在执行BGSAVE的时候Redis服务器对于SAVE,BGSAVE以及BGREWRITEAOF三个命令的返回会不同,首先SAVE是被直接拒绝的。如果BGSAVE正在执行 BGREWRITEAOF会被推迟,而BGREWRITEAOF在执行的时候,BGSAVE会被推迟。

在载入RDB的期间也是阻塞的一个状态。通过配置服务器的sava参数,可以让BGSAVE定期执行,例如save 300 1表示进行了300次修改至少进行一次BGSAVE。

而且save条件是通过redisServer中的saveparams来进行的,当输入了save的参数的是,就会改变saveparams中的参数值

 

 当然在redisServer中还有dirty参数和lastsave参数,dirty是提示 距离上次修改期间一共有又修改了多少次,lastsave是最后一次执行持久化的时间。

在redis中有个周期执行的函数serverCron 100毫秒就会去判断一次,是否满足了RDB的持久化。如果满粗了BGSAVE的方法,那么就可以进行RDB持久化。

 

最后的重头戏是RDB的文件结构。

 

 RDB文件中的REDIS是一个标识位目的是让服务器快速的知道这个是redis的RDB文件。因为是二进制文件所以没有像C语言一样的用"/0"进行结尾。

db_version表示了一个字符串的整数,记录的是RDB文件的版本号,例如"0006"

databases表示的是服务器里面各个数据库的键值对,database为0,表示的就是0号数据库的内容

check_num是一个检验的数据,是通过REDIS+db_version+databases+EOF计算出的。

EOF也是标识位读到这个的时候就表示已经完成了载入的工作。

 

分空数据库的文件都可以保存为SELECTDB、db_number、key_value_paris

SELECTDB是一个固定大小常量,表示的是要执行SELECT操作了

然后给db_number表示的就是哪一个数据库,最后的key_value_paris表示的就是要读入的参数了

 

 

key_value_paris 也是通过三部分组成的,TYPE,key,value。

 

 这就是前面redisObject的所有可能的类型了。根据这个TYPE来决定如何进数据进行插入。

带过期时间的key_value_paris会额外携带两个参数,一个是标识位。一个是时间。

 

 然后就看几个分析的案例

 

 

 

 

 

posted @ 2020-12-17 16:13  smartcat994  阅读(112)  评论(0编辑  收藏  举报