一. 概述
Redis 是内存数据库, 一旦服务器进程退出, 服务器中的数据库内存数据状态也会消失. 为了解决这个问题, Redis 提供了 RDB 持久化功能, 这个功能可以将 Redis 在内存中的数据库状态保存到磁盘中, 避免数据意外丢失.
RDB 持久化可以手动执行, 也可以根据服务器配置选项定期执行, 是在指定的时间间隔, 对你的数据进行快照存储. 该 RDB 文件快照是一个经过压缩的二进制文件. 文件名为 dump.rdb, 该文件保存在 Redis 目录下, 当 Redis 服务器停机后, 只要 RDB 文件存在, 下次重启 Redis 服务时就会自动还原数据库数据状态.
1.1 RDB 文件的创建
通过 Redis 两个命令来生成 RDB 文件, 一是 SAVE, 另一个是 BGSAVE.SAVE 命令是会阻塞 Redis 服务器进程, 直到 RDB 文件创建完毕为止, 在阻塞期间, 服务器不能处理任何命令请求.
127.0.0.1:6379> save -- 等待 RDB 文件创建完毕
OK
与 SAVE 不同, BGSAVE 命令会派生出一个子进程, 然后由子进程负责创建 RDB 文件, 服务器进程 (父进程) 继续处理命令请求. 当 BGSAVE 命令在执行期间, 客户端再发送 BGSAVE 命令会被服务器拒绝, 因为同时执行两个 GBSAVE 命令也会产生竞争条件. 最后 BGREWRITEAOF 和 GBSAVE 两个命令也不能同时执行.
127.0.0.1:6379> bgsave -- 派生子进程, 并由子进程创建 RDB 文件
Background saving started
1.2 RDB 文件载入
和创建文件不同, RDB 文件的载入是在服务器启动时自动执行的, 并没有用于载入 RDB 文件的命令, 只要 Redis 服务器在启动时检测到 RDB 文件的存在, 它就会自动载入 RDB 文件. 能过启动时日志记录可以查看. 需要注意的是, 如果打开了 AOF 持久化, 那么服务器会优先使用 AOF 文件来还原数据库状态.
1.3 自动间隔性保存
文件的创建除了 SAVE 和 GBSAVE 保存 RDB 文件, 还可以通过配置 SAVE 选项, 让服务器每隔一段时间自动执行一次 BGSAVE 命令. 可以配置 SAVE 选项设置多个保存条件, 只要任意一个条件被满足, 服务器就会执行 BGSAVE 命令.
-- 默认配置的 SAVE 选项, 保存方式有三种条件, 满足任意一种就可以, 如下:
- 127.0.0.1:6379> config get save
- 1) "save"
- 2) "900 1 300 10 60 10000"
(1) 服务器在 900 秒之内, 对数据库进行了至少 1 次修改.
(2) 服务器在 300 秒之内, 对数据库进行了至少 10 次修改.
(3) 服务器在 60 秒之内, 对数据库进行了至少 10000 次修改.
1.4 检查保存条件是否满足
Redis 的服务器周期性操作默认每隔 100 毫秒就会检查执行一次, 用于对正在运行的服务器进行维护, 其中一项工作是检查 save 选项所设置的保存条件是否已经满足, 如果满足就调用 BGSAVE 命令.
1.5 RDB 工作方式
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
(1)Redis 调用 forks. 同时拥有父进程和子进程.
(2)子进程将数据集写入到一个临时 RDB 文件中.
(3)当子进程完成对新 RDB 文件的写入时, Redis 用新 RDB 文件替换原来的 RDB 文件, 并删除旧的 RDB 文件.
1.6 RDB 文件结构
下面简单了解一下 RDB 文件结构, 这里不再深入了解. 下面脚本显示了本机 dump.rdb 文件的位置. 该 rdb 文件结构中各部分 如下图表格所示:
- [root@xuegod64 Redis]# pwd
- /usr/local/Redis
- [root@xuegod64 Redis]# ls -l
-rwxrwxrwx 1 root root 1687 11 月 22 10:03 dump.rdb
文件结构各部份 | 描述 |
redis | RDB 文件最开头是 REDIS 部分,保存五个字符,程序在载入文件时,快速检查所载入的文件是否是 RDB 文件 |
Db_version | 一个字符串表示的整数,4 个字节,记录了 RDB 文件的版本号 |
databases | 该部份包含着 0 个或任意多个数据库,以及各数据库中的键值对数据 |
Eof | 占 1 个字节,标志着 RDB 文件正文内容的结束,当程序遇到这个值的时候,就知道所有数据库的所有键值对都已经载入完毕了 |
Check_sum | 占 8 字节的无符号整数,保存一个校验和,通过前四部分内容进行计算得出。用来检查 RDB 文件是否出错或者损坏 |
下面通过 Linux 的 od 命令来查看 Redis 服务器产生的 RDB 文件, 并指定 - c 参数可以以 ASCII 编码方式打印信息. 信息中能直接看到的信息是: 第一部分是 Redis, Db_version 部分是 0008, Eof 部分是 372 .
1.7 RDB 优势
(1) RDB 是一个非常紧凑的文件, 它保存了某个时间点得数据集, 非常适用于数据集的备份, 比如你可以在每个小时报保存一下过去 24 小时内的数据, 同时每天保存过去 30 天的数据, 这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
(2)RDB 是一个紧凑的单一文件, 很方便传送到另一个远端数据中心, 非常适用于灾难恢复.
(3)RDB 在保存 RDB 文件时父进程唯一需要做的就是 fork 出一个子进程, 接下来的工作全部由子进程来做, 父进程不需要再做其他 IO 操作, 所以 RDB 持久化方式可以最大化 Redis 的性能.
(4)与 AOF 相比, 在恢复大的数据集的时候, RDB 方式会更快一些.
1.8 RDB 缺点
(1)如果数据不允许任何丢失, 那么 RDB 不适合(虽然可以配置不同的 save 时间点).
(2)经常 fork 子进程来保存数据集到硬盘上, 当数据集比较大的时候, fork 的过程是非常耗时的, 可能会导致 Redis 在一些毫秒级内不能响应客户端的请求.
二. RDB 持久化测试
(1) 首先关闭 Redis 服务. 当关闭服务时报错, 首先检查一下是否是权限的问题, 因为在 shutdown 命令的时候, 会进行 save 操作, 而 save 需要操作 dump.rdb 文件, 如果没有权限则会报这个错.
- [root@xuegod64 Redis]# Redis-cli shutdown
- (error) ERR Errors trying to SHUTDOWN. Check logs
-- 需要放开对 dump.rdb 文件的写入权限, 服务关闭成功
- [root@xuegod64 Redis]# Redis-cli shutdown
- [root@xuegod64 Redis]# Redis-cli
(2) 服务启动, 首先 set 写入一条数据, 然后关闭服务进程.
- [hsr@xuegod64 Redis]$ Redis-serverredis.conf
- 127.0.0.1:6379> set name "test"
- OK
- 127.0.0.1:6379> get name
- "test"
- 127.0.0.1:6379> exit
- [hsr@xuegod64 Redis]$ Redis-cli shutdown
(3)重次重启服务, 查看持久化
查看刚才的键值对, 发现键值对已存在, 说明数据持久化保存到了磁盘中, 原理是在关闭服务时, 会先调用 save 操作, 保存到 dump.rdb 文件中, 在重启服务后, 加载 dump.rdb 文件.
- [hsr@xuegod64 Redis]$ Redis-serverredis.conf
- [hsr@xuegod64 Redis]$ Redis-cli
- 127.0.0.1:6379> get name
- "test"
总结: 作为 RDB 快照持久化, 如果是正常关闭 Redis 服务, 再重启后数据是不会丢失的, 但如果系统崩溃或者强杀, 用户将会丢失最近一次生成快照之后更改的所有数据.
来源: https://www.cnblogs.com/MrHSR/p/9999957.html