因为Redis服务器将数据存储在内存里面,而一旦服务器被关闭或者运行服务器的主机本身被关闭的话,存储在内存里面的数据就会消失不见;
如果我们仅仅是将redis用作缓存的话,那么这种数据丢失带来的问题并不是非常大,我们只需要重启机器,然后再次将数据放到缓存里面就可以了;
但如果我们将redis用作数据库的话,那么这种数据丢失就不能接受了。
一、RDB持久化原理
将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘里面。
通过在服务器启动时载入RDB文件,服务器可以根据RDB文件的内容,还原服务器原有的数据库数据。
二、创建RDB文件
Redis服务器在什么时候创建RDB文件?
1) 服务器执行客户端发送的SAVE命令;(手动执行)
2) 服务器执行客户端发送的BGSAVE命令;(手动执行)
3) 使用save配置选项设置的自动保存条件被满足,服务器自动执行BGSAVE命令;(自动执行)
2.1 手动创建RDB文件之SAVE命令
通过使用客户端向服务器发送SAVE命令,可以命令服务器去创建一个新的RDB文件;
redis> SAVE
OK
在执行SAVE命令时过程中(也就是创建RDB文件的过程中),redis服务器将被阻塞,无法处理客户端发送的命令请求,只有在SAVE命令执行完毕后(也就是RDB文件创建完毕之后),服务器才会重新开始处理客户端发送的命令请求;如果RDB文件已经存在,那么服务器将使用新的RDB文件去替代旧的RDB文件。
SAVE命令的复杂度为O(N),N为服务器中所有数据库包含的键值对数量总和。
2.2手动创建RDB文件之BGSAVE命令
BGSAVE命令同样可以创建一个新的RDB文件,这个命令和SAVE命令的区别在于:BGSAVE不会造成redis服务器阻塞,在执行BGSAVE命令的过程中,redis服务器 仍然可以正常地处理其他客户端发送的命令请求。
BGSAVE是一个异步命令,发送命令的客户端立即得到回复,而实际的操作是在回复之后才开始;
redis> BGSAVE
Background saving started
BGSAVE命令的复杂度和SAVE一样,都是O(N),N为服务器中所有数据库包含的键值对数量总和。
BGSAVE不会造成阻塞的原因:
1) 当redis服务器 接收到BGSAVE命令时,它不会自己来创建RDB文件,而是通过fork()来生成一个子进程,然后由子进程负责创建RDB文件,而自己则继续处理客户端的命令请求;
2) 当子进程创建好RDB文件并退出时,它会向父进程(也就是负责处理命令请求的redis服务器)发送一个信号,告知它RDB文件已经创建完毕;
3) 最后redis服务器(父进程)接收到子进程创建的RDB文件,BGSAVE执行完毕;
BGSAVE执行过程:
SAVE和BGSAVE对比
注意:两者并没有谁好谁坏之分,各自适用于不同的场景。
2.3 自动创建RDB文件
以上介绍的SAVE和BGSAVE均需要手工介入。Redis服务器提供了自动进行RDB持久化操作,redis提供了save配置选项,通过这个选项,用户可以设置任意多个保存条件,每当保存条件中的任意一个被满足时,服务器就会自动执行BGSAVE命令。
save选项的格式:
save <seconds> <changes>
描述:如果距离上一次创建RDB文件已经过去seconds秒,并且服务器的所有数据库总共已经发生了不少于changes次修改(添加/删除/更新),那么执行BGSAVE。
示例:
save 300 10
表示距离上一次创建RDB文件已经过去了300秒,并且服务器的所有数据库总共发生了不少于10次修改,那么执行BGSAVE命令;
save 60 10000
表示距离上一次创建RDB文件已经过去了60秒,并且服务器的所有数据库总共发生了不少于10000次修改,那么执行BGSAVE命令;
save 900 1 save 300 10 save 60 10000
主要三个条件中的任意一个满足时,redis服务器就自动执行BGSAVE命令。
每次创建RDB文件之后,服务器为实现自动持久化而设置的时间计数器和次数计数器就会被清零,并重新开始计数,所以所个保存条件的效果是不会叠加的。