一杯茶的功夫,上手Redis持久化机制

RDB是Redis Database 的缩写,其作用是在某一个时间点,将Redis存储在内存中的数据生成快照并存储到磁盘等介质上,存在这个磁盘介质上的文件就是RDB文件。“快照”顾名思义就是好像照相一样保存当时的数据,这里的RDB文件是一个二进制的文件,并且是经过压缩的。因为RDB文件是保存在硬盘中的,即使Redis服务器进程退出,甚至运行Redis服务器的计算机宕机,但只要RDB文件仍然存在,Redis服务器就可以用它来还原数据库状态。如图1 所示,可以想象Redis数据库在时间轴上有位于不同时间点的时候都有一个数据库状态,可以把它们想象成一个个切片。图上标注出两个时间点的两个数据库切片,RDB持久化做的事情就是顺着绿色箭头的方向将数据库状态的“切片”以RDB文件的形式保存到磁盘中。

图1 将数据库状态保存为RDB文件

RDB 文件结构

虽然说RDB是一个压缩过的二进制文件,但是它的文件结构也需要有基本的了解,这样有助于我们理解其发挥的作用。如表格1所示,RDB文件由5个部分组成,按照从左到右的顺序依次是:

  • 文件最开头是“REDIS”部分,其长度为5个字节,保存着“REDIS”五个字符。通过这五个字符,程序可以在载入文件时可以判断所载入的文件是否是RDB文件。

  • 接下来是“db_version”长度为4字节,是一个字符串表示的整数,它记录了RDB文件的版本号,例如:”0006″就代表RDB文件的版本为第六版。

  • “databases”中可以包含着零个或任意多个数据库。

  • “EOF”常量的长度为1字节,是 RDB文件正文结束的标识,当载入程序读取到个值的时,就意味着数据库的所有键值对都已经加载完毕了。

  • “check_sum”是一个8字节长的无符号整数,保存着一个校验和。这个校验和是通过对“REDIS”、“db_version”、“databases”、以及“EOF”四个部分的内容进行计算得出的。Redis服务器在载入RDB文件时,会将载入数据所计算出的校验和与check_sum所记录的校验和进行对比,以此来判断RDB文件是否损坏。

REDIS

db_version

databases

EOF

check_sum

表格1 RDB的文件结构

如表格2所示,其表示一个databases部分为空的RDB文件:文件以”REDIS”开头,表示这是一个RDB文件,之后的”0006″表示数据库版本是第六版。因为databases为空所以这里没有数据库的信息,所以版本号之后直接跟着“EOF”常量,最后的6265312314761934562是文件的校验和。

REDIS

“0006”

EOF

6265312314761934562

表格2 RDB文件例子

RDB 触发机制以及流程

在认识了RDB文件的结构以后,再来看看Redis 如何触发RDB持久化操作,以及其具体流程是如何的。这里包括三部分的内容,分别是save同步方式触发、bgsave 异步方式触发以及自动配置化的方式触发。

save同步方式触发RDB持久化

如图2所示,描述了save 同步方式持久化RDB的过程:

  1. Redis Client端通过向Redis Server 发起save命令请求RDB持久化操作。

  2. Redis Server接受到命令以后,将当前数据库快照保存到RDB文件中。

  3. 由于save命令是同步操作,因此如果此时有其他Redis Client也向Redis Server发起save操作,会被阻塞直到第一个Redis Client完成save命令为止。

图2 save同步方式触发RDB持久化

bgsave同步方式触发RDB持久化

如图3所示,异步方式过程如下:

  1. 依旧是Redis Client发起命令,不过命令改成了bgsave(background save有后台运行的意思),照旧请求Redis Server。

  2. Redis Server接受到请求以后会fork出一个Redis子进程。

  3. 这个子进程用来创建RDB文件。由于这个过程是异步的,因此Redis Server在启动子进程以后还可以接受其他请求。

  4. Redis 子进程创建RDB文件以后会把成功的消息返回给Redis Server。

  5. 由于bgsave命令是异步操作,如果此时有其他Redis Client同时请求Redis Server并不会被阻塞。Redis Server会响应请求,同样也会fork出对应的子进程进行RDB文件的创建。

图3 bgsave异步方式触发RDB持久化

自动配置化的方式触发

如图4所示,这种方式可以理解为读取配置文件的方式。看下面的三个步骤:

  1. Redis Server直接读取Redis 配置文件的内容,获取RDB持久化的信息。

  2. 在Redis配置文件中配置了对应的save命令用来代替Redis Client请求的命令。其配置内容包括save命令、秒和修改次数。按照图中的例子来说,“save 500 3” 的意思是,在500秒的时间内如果Redis 数据库有3次修改就进行save请求,也就是请求RDB的持久化操作。

  3. 一旦满足配置文件中的条件,Redis Server就会执行对应的save操作进行持久化。

图4 读取配置文件进行RDB持久化

一般而言Redis的配置信息会放到redis.conf配置文件中进行存储,其包含很多内容,这里我们就RDB持久化的部分给大家做简单介绍。redis.conf文件中找到“SNAPSHOTTING”(快照)的部分。看如下几个配置项:

# 900秒内有1次修改、300秒内有10次修改、60秒内有10000次修改

#满足任何以上条件,触发RDB持久化。

save 900 1

save 300 10

save 60 10000

# 当快照操作bgsave出错时,是否停止持久化?yes 表示“是”,no表示“否”。

stop-writes-on-bgsave-error yes

# 是否压缩?yes表示“是”,no表示“否”,默认选择yes。

rdbcompression yes

# 对rdb数据进行校验, 表示写入文件和读取文件时是否开启 RDB 文件检查。

# yes表示“是”,no表示“否”,默认选择yes。

# 选择yes表示在Redis加载RDB需要检查文件是否损坏,如果存在损坏会停止启动。

rdbchecksum yes

# 设置rdb的文件名

dbfilename dump.rdb

# RDB文件的路径,如果不单独指定,默认是redis的启动路径。

dir ./

关于RDB持久化恢复Redis数据方面也比较简单,将RDB持久化文件 (例如:dump.rdb) 移动到 Redis 安装目录并启动Redis服务就可以了。可以通过 Redis 中的“CONFIG GET dir”命令获取Redis的安装目录。

由于RDB是一个压缩的二进制文件,其代表Redis在某一个时间点上的快照。其适合数据库备份和全量复制的场景。比如定期给数据库进行备份,把RDB文件拷贝到其他的服务器上,以及用于灾备。同样是因为压缩的原因,RDB的加载速度比AOF也要快。