介绍
RDB 持久化是把当前进程数据生成快照保存到硬盘的过程,触发 RDB 持久化过程分为手动触发和自动触发。
RDB 文件是一个二进制文件。
触发机制
- 手动触发
- SAVE(同步)
- BGSAVE(异步)
- 自动触发
SAVE
SAVE 命令:阻塞当前 Redis 服务器,直到 RDB 过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。
特点:
- 文件策略:如存在旧的 RDB 文件,新替换旧版;
- 时间复杂度:O(n)
BGSAVE
BGSAVE 命令:Redis 进程执行 fork 操作创建子进程,RDB 持久化过程由子进程负责,完成后自动结束。阻塞只发生在 fork 阶段,一般时**间很短**。几乎(fork 很快)不会阻塞客户端命令。
fork 子进程会消耗额外的内存
流程说明:
**
- 执行
bgsave
命令,Redis 父进程判断当前是否存在正在执行的子进程,如 RDB/AOF 子进程,如果存在bgsave 命令直接返回。 - 父进程执行 fork 操作创建子进程,fork 操作过程中父进程会阻塞,通过 info stats 命令查看
latest_fork_usec
选项,可以获取最近一个 fork 操作的耗时,单位为微秒。 - 父进程 fork 完成后,
bgsave
命令返回“Background saving started”信息并不再阻塞父进程,可以继续响应其他命令。 - 子进程创建 RDB 文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行
lastsave
命令可以获取最后一次生成 RDB 的 时间,对应info
统计的rdb_last_save_time
选项。 - 进程发送信号给父进程表示完成,父进程更新统计信息,具体见
info Persistence
下的rdb_*
相关选项。
特点:**
- 文件策略:如存在旧的 RDB 文件,新替换旧版
- 时间复杂度:O(n)
自动触发
save 方式
因为 BGSAVE
命令可以在不阻塞服务器进程的情况下执行,所以 Redis 允许用户通过设置服务器配置的 save 选项,让服务器每隔一段时间自动执行一次 BGSAVE
命令。
用户可以通过使用 save
相关配置,如“save m n
”。表示 m 秒内数据集存在 n 次修改时,自动触发 bgsave
。
save 选项可设置多个保存条件,但只要其中任意一个条件被满足,服务器就会执行 BGSAVE 命令。
举个例子,如果我们向服务器提供以下配置:
save 900 1
save 300 10
save 60 10000
# 以上为 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 的二进制文件存储存在历史版本不兼容情况
- 因无法做到实时持久化,所以存在丢部分数据的情况
扩展阅读
- Redis RDB 持久化方式:https://www.jianshu.com/p/c0e2c54b6519