付诸实践,RDB 方式持久化的开启与配置
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 复制代码
保存配置文件后需要重新启动 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
命令执行保存操作:
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 提供了save
和bgsave
这两种不同的保存方式,并且这两个方式在执行的时候都会调用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就说会保存了才退出的,你骗人~
注意到,文档中有一句
恍然大悟,原来是要在持久化被打开的情况下,通过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> 复制代码
这下终于弄明白了。
作者:云享专家韦世东
链接:https://juejin.im/post/5bcab6f46fb9a05d3c802ea6
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
- 点赞
- 收藏
- 关注作者
评论(0)