通过服务端输出的日志,可以发现Redis 在服务端进程(PID为6266)会为 BGSAVE 命令单独创建(fork)一个子进程(PID为6283),并由子进程在后台完成 RDB 的保存过程,在操作完成之后通知父进程然后退出 。在整个过程中,服务器进程只会消耗少量时间在创建子进程和处理子进程信号量上面,其余时间都是待命状态 。
BGSAVE 是触发 RDB 持久化的主流方式,下面给出 BGSAVE 命令生成快照的流程:
文章插图
- 客户端发起 BGSAVE 命令,Redis 主进程判断当前是否存在正在执行备份的子进程,如果存在则直接返回
- 父进程 fork 一个子进程 (fork 的过程中会造成阻塞的情况),这个过程可以使用 info stats 命令查看 latest_fork_usec 选项,查看最近一次 fork 操作消耗的时间,单位是微秒
- 父进程 fork 完成之后,则会返回 Background saving started 的信息提示,此时 fork 阻塞解除
- fork 创建的子进程开始根据父进程的内存数据生成临时的快照文件,然后替换原文件
- 子进程备份完毕后向父进程发送完成信息,父进程更新统计信息
命令SAVEBGSAVEIO类型同步异步是否阻塞全程阻塞fork时发生阻塞复杂度O(n)O(n)优点不会消耗额外的内存不阻塞客户端缺点阻塞客户端fork子进程消耗内存
2.1.2. 自动触发保存
因为 BGSAVE 命令可以在不阻塞服务器进程的情况下执行,所以 Redis 的配置文件 redis.conf 提供了一个 save 选项,让服务器每隔一段时间自动执行一次 BGSAVE 命令 。用户可以通过 save 选项设置多个保存条件,只要其中任意一个条件被满足,服务器就会执行 BGSAVE 命令 。Redis 配置文件 redis.conf 默认配置了以下 3 个保存条件:
save 900 1save 300 10 save 60 10000复制代码那么只要满足以下 3 个条件中的任意一个,BGSAVE 命令就会被自动执行:
- 服务器在 900 秒之内,对数据库进行了至少 1 次修改 。
- 服务器在 300 秒之内,对数据库进行了至少 10 次修改 。
- 服务器在 60 秒之内,对数据库进行了至少 10000 次修改 。
2.1.3. 启动自动载入
和使用 SAVE 和 BGSAVE 命令创建 RDB 文件不同,Redis 没有专门提供用于载入 RDB 文件的命令,RDB 文件的载入过程是在 Redis 服务器启动时自动完成的 。启动时只要在指定目录检测到 RDB 文件的存在,Redis 就会通过 rdbLoad 函数自动载入 RDB 文件 。
下面是 Redis 服务器启动时打印的日志,倒数第 2 条日志是在成功载入 RDB 文件后打印的 。
$ redis-server /usr/local/etc/redis.conf6266:C 15 Sep 2019 08:30:41.830 # Redis version=5.0.5, bits=64, commit=00000000, modified=0, pid=6266, just started6266:C 15 Sep 2019 08:30:41.830 # Configuration loaded6266:M 15 Sep 2019 08:30:41.831 * Increased maximum number of open files to 10032 (it was originally set to 256).6266:M 15 Sep 2019 08:30:41.832 # Server initialized6266:M 15 Sep 2019 08:30:41.833 * DB loaded from disk: 0.001 seconds6266:M 15 Sep 2019 08:30:41.833 * Ready to accept connections复制代码由于 AOF 文件属于增量的写入命令备份,RDB 文件属于全量的数据备份,所以更新频率比 RDB 文件的更新频率高 。所以如果 Redis 服务器开启了 AOF 持久化功能,那么服务器会优先使用 AOF 文件来还原数据库状态;只有在 AOF 的持久化功能处于关闭状态时,服务器才会使用优先使用 RDB 文件还原数据库状态 。
文章插图
2.2. RDB的文件结构
RDB 文件是经过压缩的二进制文件,下面介绍关于RDB文件的一些细节 。
2.2.1. 存储路径
SAVE 命令和 BGSAVE 命令都只会备份当前数据库,备份文件名默认为 dump.rdb,可通过配置文件修改备份文件名 dbfilename xxx.rdb 。可以通过以下命令查看备份文件目录和 RDB 文件名称:
$ redis-cli -h 127.0.0.1 -p 6379127.0.0.1:6379> CONFIG GET dir1) "dir"2) "/usr/local/var/db/redis"127.0.0.1:6379> CONFIG GET dbfilename1) "dbfilename"2) "dump.rdb"复制代码RDB 文件的存储路径既可以在启动前配置,也可以通过命令动态设定 。
- 配置项:通过 dir 配置指定目录,dbfilename 指定文件名
- 动态指定:Redis 启动后也可以动态修改 RDB 存储路径,在磁盘损害或空间不足时非常有用,执行命令为:
推荐阅读
- 一文学会如何查询鉴别真假百度蜘蛛,遏止恶意IP抓取
- dfs,bfs 一文搞懂深度优先搜索、广度优先搜索
- 一文看懂Oracle数据库的三大索引类型
- 天津,揭开普洱神秘面纱 搭建专业品鉴平台
- 汽车轮胎规格参数的含义,一文教你认清楚
- 台鹿谷农会盼与永福台农创业园优势深度合作
- 一文搞懂高并发性能指标:QPS、TPS、RT、吞吐量
- 一文看懂IP地址:含义、分类、子网划分、查与改、路由器与IP地址
- 图解汽车的构造与原理,一文看懂
- 马桶应该坐哪一层,上马桶要揭开几层盖