付诸实践,RDB 方式持久化的开启与配置

举报
我们都是云专家 发表于 2019/09/06 16:35:38 2019/09/06
【摘要】 将redis进程kill,哪些数据会被保存?

RDB 方式持久化的开启与配置

Redis 默认的持久化方式是 RDB ,并且默认是打开的。RDB 的保存有方式分为主动保存与被动保存。主动保存可以在 redis-cli 中输入 save 即可;被动保存需要满足配置文件中设定的触发条件,目前官方默认的触发条件可以在 redis.conf 中看到:

save 900 1 save 300 10 save 60 10000 复制代码

其含义为:

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

满足触发条件后,数据就会被保存为快照,正是因为这样才说 RDB 的数据完整性是比不上 AOF 的。

触发保存条件后,会在指定的目录生成一个名为 dump.rdb 的文件,等到下一次启动 Redis 时,Redis 会去读取该目录下的 dump.rdb 文件,将里面的数据恢复到 Redis。

这个目录在哪里呢?

我们可以在客户端中输入命令config get dir查看:


gannicus@$ src/redis-cli 127.0.0.1:6379> config get dir 1) "dir" 2) "/home/gannicus/Documents/redis-5.0.0" 127.0.0.1:6379>  复制代码

返回结果中的"/home/gannicus/Documents/redis-5.0.0"就是存放 dump.rdb 的目录。

Redis 版本说明

在测试之前,说明一下前提。redis 是直接从官网下载的压缩包,解压后得到的 redis-x.x.x 文件夹,比如我的是 redis-5.0.0,然后进入文件夹,在 redis-5.0.0 项目根目录使用make命令安装。


RDB 被动触发保存测试

刚才提到它分为主动保存与被动触发,现在我们来测试一下被动触发。首先启动 redis-server,然后再打开客户端 redis-cli ,先增添几条记录:

127.0.0.1:6379> set lca 1 OK 127.0.0.1:6379> set lcb 1 OK 127.0.0.1:6379> set lcc 1 OK 127.0.0.1:6379> set lcd 1 OK 127.0.0.1:6379> set lce 1 OK 127.0.0.1:6379> set lcf 1 OK 127.0.0.1:6379> set lcg 1 OK 127.0.0.1:6379> set lch 1 OK 127.0.0.1:6379> set lci 1 OK 127.0.0.1:6379> set lcj 1 OK 127.0.0.1:6379> set lck 1 OK 127.0.0.1:6379> set lcl 1 OK 127.0.0.1:6379> set lcm 1 OK 复制代码

可以看到,总共添加了 13 条记录:

127.0.0.1:6379> keys *  1) "lca"  2) "lcd"  3) "lcg"  4) "lce"  5) "lcb"  6) "lcm"  7) "lcf"  8) "lci"  9) "lcl" 10) "lcc" 11) "lck" 12) "lcj" 13) "lch" 127.0.0.1:6379>  复制代码

然后发现redis-server端的日志窗口中出现了如下的提示:

21971:M 21 Oct 2018 16:52:44.062 * 10 changes in 300 seconds. Saving... 21971:M 21 Oct 2018 16:52:44.063 * Background saving started by pid 22552 22552:C 21 Oct 2018 16:52:44.066 * DB saved on disk 21971:M 21 Oct 2018 16:52:44.165 * Background saving terminated with success 复制代码

从英文提示中可以大概读懂这些内容,它检测到 300 秒内有 10 条记录被改动,刚才我们添加了 13 条数据记录,满足 redis.conf 中对于 RDB 数据保存的条件,所以这里执行数据保存操作,并且提示开辟了一个 22552 的进程出来执行保存操作,最后提示保存成功。

并且在目录内看到有 dump.rdb 文件生成。

现在将redis进程kill,哪些数据会被保存?

通过命令 kill -9 pid ( pid 是进程编号)模拟 Redis 异常关闭,然后再启动 Redis ,我们来看一看,到底是只保存了 10 条记录还是 13 条全都保存下来了?

127.0.0.1:6379> keys *  1) "lcb"  2) "lcj"  3) "lcd"  4) "lch"  5) "lci"  6) "lcc"  7) "lcf"  8) "lce"  9) "lca" 10) "lcg" 127.0.0.1:6379>  复制代码

重启后查看记录,发现 13 条记录中只有 10 条记录会被保存,这也印证了之前所说,RDB 方式的数据完整性是不可靠的,除非断掉的那一刻正好是满足触发条件的条数。

关闭 RDB

刚才提到了,它是默认启用的,如果你不需要它可以在配置文件中将这 3 个配置注释掉,并新增 save ""即可:

  save "" # save 900 1 # save 300 10 # save 60 10000 复制代码

20190906ly00016.PNG

保存配置文件后需要重新启动 Redis 服务才会生效,然后继续添加十几条记录:


127.0.0.1:6379> keys *  1) "lcb" ... 23) "lca" 24) "lcg" 127.0.0.1:6379>  复制代码

在之前已有 10 条的基础上我再增加了 14 条记录,这次同样要通过kill来模拟 Redis 异常关闭,再启动服务看一看,数据是否还被保存:

127.0.0.1:6379> keys *  1) "lcb"  2) "lcj"  3) "lcd"  4) "lch"  5) "lci"  6) "lcc"  7) "lcf"  8) "lce"  9) "lca" 10) "lcg" 127.0.0.1:6379>  复制代码

发现后面添加的 14 条记录并没有被保存,恢复数据的时候仅仅只是恢复了之前的 10 条。并且观察 Redis 服务端窗口日志,并未发现像之前一样的触发保存的提示,证明 RDB 方式已经被关闭。

RDB 主动保存测试

通过配置文件关闭被动触发,那么主动关闭是否还会生效呢?

在 Redis 客户端( redis-cli )通过del命令删除几条记录,然后输入save命令执行保存操作:

20190906ly00017.PNG

127.0.0.1:6379> keys *  1) "lcc"  2) "lch"  3) "lcb"  4) "lci"  5) "lce"  6) "lcj"  7) "lcg"  8) "lca"  9) "lcd" 10) "lcf" 127.0.0.1:6379> del lca lcb lcc (integer) 3 127.0.0.1:6379> save OK 127.0.0.1:6379>  复制代码

可以看到redis-server的日志有新的提示:22598:M 21 Oct 2018 17:22:31.365 * DB saved on disk,它告诉我们数据已经保存。

那么继续模拟异常关闭,再打开服务,看一看是否真的保存了这些操作:

127.0.0.1:6379> keys * 1) "lci" 2) "lcj" 3) "lcd" 4) "lcg" 5) "lcf" 6) "lce" 7) "lch" 127.0.0.1:6379>  复制代码


果不其然,这几个删除操作都被保存了下来,恢复过来的数据中已经没有那 3 条记录了,证明主动关闭不受 配置文件的影响。


除了save还有其他的保存方式么?

save 和 bgsave 保存

有的,Redis 提供了savebgsave这两种不同的保存方式,并且这两个方式在执行的时候都会调用rdbSave函数,但它们调用的方式各有不同:

  • save 直接调用 rdbSave方法 ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。

  • bgsave 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为 rdbSave 在子进程被调用,所以 Redis 服务器在 bgsave 执行期间仍然可以继续处理客户端的请求。

save 是同步操作,bgsave 是异步操作。

bgsave命令的使用方法和save命令的使用方法是一样的:


127.0.0.1:6379> keys * 1) "lci" 2) "lcj" 3) "lcd" 4) "lcg" 5) "lcf" 6) "lce" 7) "lch" 127.0.0.1:6379> del lci lcj  (integer) 2 127.0.0.1:6379> bgsave Background saving started 127.0.0.1:6379> keys * 1) "lcd" 2) "lcg" 3) "lcf" 4) "lce" 5) "lch" 127.0.0.1:6379>  复制代码

shutdown 保存

事实上,shutdown命令也是可以保存数据的,惊不惊喜。它会在关闭前将数据保存下来,意不意外?

127.0.0.1:6379> set app 1 OK 127.0.0.1:6379> set apps 1 OK 127.0.0.1:6379> keys * 1) "apps" 2) "lcd" 3) "lcg" 4) "lcf" 5) "app" 6) "lce" 7) "lch" 127.0.0.1:6379> shutdown not connected> quit gannicus@$  复制代码

然后 Redis 服务就被关闭掉了。我们需要重新启动 Redis 服务,到客户端中看一看是否生效:

gannicus@$ src/redis-cli 127.0.0.1:6379> keys * 1) "lce" 2) "lcf" 3) "lcd" 4) "lch" 5) "lcg" 复制代码

竟然没有生效,刺不刺激?这是为什么呢?明明官方文档之shutdown就说会保存了才退出的,你骗人~

注意到,文档中有一句

20190906ly00018.PNG

恍然大悟,原来是要在持久化被打开的情况下,通过shutdown命令关闭才不会丢失数据,那么就到配置文件中将那几个save的配置项打开吧:

#   save "" save 900 1 save 300 10 save 60 10000 复制代码

然后再开启 Redis 服务,再尝试一遍(过程为:添加 -> shutdown -> 重启服务 -> 查看):

127.0.0.1:6379> set app 1 OK 127.0.0.1:6379> set apps 1 OK 127.0.0.1:6379> shutdown not connected> quit gannicus@$ src/redis-cli 127.0.0.1:6379> keys * 1) "lce" 2) "lch" 3) "app" 4) "lcf" 5) "apps" 6) "lcd" 7) "lcg" 127.0.0.1:6379>  复制代码


这下终于弄明白了。

20190906ly00019.PNG

作者:云享专家韦世东
链接:https://juejin.im/post/5bcab6f46fb9a05d3c802ea6
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。