介绍

RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发和自动触发。

RDB 文件是一个二进制文件。

image.png

触发机制

  • 手动触发
    • SAVE(同步)
    • BGSAVE(异步)
  • 自动触发

SAVE

SAVE 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。

image.png

特点:

  • 文件策略:如存在旧的 RDB 文件,新替换旧版;
  • 时间复杂度:O(n)

BGSAVE

BGSAVE 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时**间很短**。几乎(fork 很快)不会阻塞客户端命令。

fork 子进程会消耗额外的内存

image.png
流程说明:
**

  1. 执行 bgsave 命令,Redis 父进程判断当前是否存在正在执行的子进程,如 RDB/AOF 子进程,如果存在bgsave 命令直接返回。
  2. 父进程执行 fork 操作创建子进程,fork 操作过程中父进程会阻塞,通过 info stats 命令查看 latest_fork_usec 选项,可以获取最近一个 fork 操作的耗时,单位为微秒。
  3. 父进程 fork 完成后,bgsave 命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行 lastsave 命令可以获取最后一次生成 RDB 的 时间,对应 info 统计的 rdb_last_save_time 选项。
  5. 进程发送信号给父进程表示完成,父进程更新统计信息,具体见 info Persistence下的 rdb_* 相关选项。


特点:**

  • 文件策略:如存在旧的 RDB 文件,新替换旧版
  • 时间复杂度:O(n)

自动触发

save 方式

因为 BGSAVE 命令可以在不阻塞服务器进程的情况下执行,所以 Redis 允许用户通过设置服务器配置的 save 选项,让服务器每隔一段时间自动执行一次 BGSAVE 命令。

用户可以通过使用 save 相关配置,如“save m n”。表示 m 秒内数据集存在 n 次修改时,自动触发 bgsave

save 选项可设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行 BGSAVE 命令。

举个例子,如果我们向服务器提供以下配置:

  1. save 900 1
  2. save 300 10
  3. save 60 10000
  4. # 以上为 redis.conf 默认配置

那么只要满足以下三个条件中的任意一个,BGSAVE 命令就会被执行:

  • 服务器在 900 秒之内,对数据库进行了至少 1 次修改
  • 服务器在 300 秒之内,对数据库进行了至少 10 次修改
  • 服务器在 60 秒之内,对数据库进行了至少 10000 次修改

其他方式

  • 如果从节点执行全量复制操作,主节点自动执行bgsave生成 RDB 文件并发送给从节点。
  • 执行debug reload命令重新加载 Redis 时,也会自动触发save操作。
    • debug reload 命令说明:save 当前的 RDB 文件,并清空当前数据库,重新加载 RDB。
  • 默认情况下执行shutdown命令时,如果没有开启 AOF 持久化功能则自动执行 bgsave

配置、文件、运维

redis.conf 配置

配置 默认值 推荐配置 说明
dir ./ /data
选大硬盘路径
Redis 工作目录(如:数据库持久化文件存储路径)
强调:该路径为目录
dbfilename dump.rdb dump-${port}.rdb
使用端口号
Redis 持久化文件名;存储到 dir 目录下
save 900 1
save 300 10
save 60 10000
- 建议关闭
关闭方式:删除即可
自动触发 bgsave 为 RDB 配置

| | stop-writes-on-bgsave-error | yes | yes | 开关:是否当 bgsave 出现错误的时候,停止写入 RDB 文件 | | rdbcompression | yes | yes | RDB 文件是否才用压缩格式 | | rdbchecksum | yes | yes | 是否对 RDB 文件进行校验 |

RDB 文件处理

RDB 文件保存在 dir 配置指定的目录下,文件名通过 dbfilename 配置指定。可以通过执行 config set dir{newDir}config set dbfilename{newFileName} 运行期动态执行,当下次运行时RDB文件会保存到新目录。

运维经验

当遇到坏盘或磁盘写满等情况时,可以通过 config set dir{newDir} 在线修改文件路径到可用的磁盘路径,之后执行 bgsave 进行磁盘切换,同样适用于 AOF 持久化文件。

压缩:Redis默认采用 LZF 算法对生成的 RDB 文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数 config set rdbcompression{yes|no} 动态修改。


虽然压缩 RDB 会消耗 CPU,但可大幅降低文件的体积,方便保存到硬盘或通过网络发送给从节点,因此线上建议开启。

校验:如果Redis加载损坏的RDB文件时拒绝启动,并打印如下日志:

# Short read or OOM loading DB. Unrecoverable error, aborting now.

这时可以使用Redis提供的 redis-check-dump 工具检测 RDB 文件并获取对应的错误报告。检测示例如下:

redis-check-rdb dump.rdb

# 输出结果(正常情况)
[offset 0] Checking RDB file dump.rdb
[offset 26] AUX FIELD redis-ver = '6.0.6'
[offset 40] AUX FIELD redis-bits = '64'
[offset 52] AUX FIELD ctime = '1599236420'
[offset 67] AUX FIELD used-mem = '881136'
[offset 83] AUX FIELD aof-preamble = '0'
[offset 85] Selecting DB ID 1
[offset 118] Checksum OK
[offset 118] \o/ RDB looks OK! \o/
[info] 1 keys read
[info] 0 expires
[info] 0 already expired

RDB 的优缺点

优点

  • RDB 是一个紧凑压缩的二进制文件,代表 Redis 某个时间点的数据快照
  • RDB 使用备份、全量复制等场景。
    • 建议线上可考虑使用从机进行备份,避免造成主机性能干扰。
    • 比如可每 6 小时 bgsave 一次,并备份到远程机器或文件系统,用于灾难恢复。
  • RDB 的加载恢复速度远远高于 AOF 方式

缺点

  • RDB 方式,无法做到实时的持久化或秒级持久化
    • 原因:因为 bgsave 是 fork 一个子进程进行操作,属重量级操作;频繁执行性能成本过高。
  • RDB 的二进制文件存储存在历史版本不兼容情况
  • 因无法做到实时持久化,所以存在丢部分数据的情况

扩展阅读