什么是持久化?
将数据从掉电易丢失的内存存放到能够永久存储的设备上。
作为缓存服务器,数据服务器,队列服务器都需要持久化吗?
因为redis服务器将数据存储在内存中,而一旦服务器被关闭、或者运行服务器的主机本身被关闭,存储在内存中的数据就会消失不见。
如果我们仅仅将redis用作缓存的话,那么这种数据丢失带来的问题并不是非常大,我们需要重新启动机器,然后再次将数据放到缓存中就可以了,但如果我们将redis用作数据库的话,那么这种数据丢失就不能接受了。
为了在redis服务器关闭时,仍然保留数据库中的数据,redis提供了RDB(redis DB)和AOF(AppendOnlyFile)两种持久化功能,这两种功能可以将存储在内存中的数据以文件形式保存到硬盘里面,这样的话,及时服务器关闭,已经保存到硬盘里面的数据也不会丢失。
除此之外,服务器也可以在重启的时候,通过载入持久化文件来还原服务器在关闭之前的数据键数据。或者使用持久化文件来进行数据备份、数据迁移等工作。
1.RDB
RDB持久化功能可以将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘里面。
通过服务器启动时载入RDB文件,服务器可根据RDB的内容,还原服务器原有的数据库数据。
在redis服务器创建RDB文件的情况中,有三种最常见:
1.服务器执行客户端发送的save命令;
2.服务器执行客户端发送的bgsave命令(background后台);
3.使用save配置选项设置的自动保存条件被满足,服务器自动执行bgsave。
这三种创建RDB文件的情况中,前两种需要用户手动执行,第三种情况则是由redis服务器自动执行。
1.手动创建RDB文件
也就是手动发送save命令或者bgsave命令
通过使用客户端向服务器发送save命令,可以命令服务器去创建一个新的RDB文件:
redis>save
在执行save命令的过程中(也即是创建RDB文件的过程中),redis服务器将被阻塞,无法处理客户端发送的命令请求,只有在save命令执行完毕后(也即RDB文件创建完毕后),服务器才会重新开始处理客户端发送的命令请求。
如果RDB文件已经存在,那么服务器将自动使用新的RDB文件去代替旧的RDB文件。
执行bgsave命令同样可以创建一个新的RDB文件,这个命令和save命令的区别在于,bgsave不会造成redis服务器阻塞,在执行bgsave命令的过程中,redis服务器仍然可以正常的处理其他客户端发送的命令请求。
bgsave命令不会造成服务器阻塞的原因在于:
1.当redis服务器接收到bgsave命令的时候,它不会自动来创建RDB文件,而是通过fork()来生成一个子进程,然后由子进程负责创建RDB文件,而自己继续处理客户端的命令请求;
2.当子进程创建好RDB文件并退出是,它会想父进程(也即是负责处理命令请求的redis服务器)发送一个信号,告知它RDB文件已经创建完毕;
3.最后redis服务器(父进程)接手子进程创建RDB文件bgsave执行完毕。
打开redis配置文件
vim /etc/redis/6379.conf
默认的持久化文件为dump.rdb,默认的存放路径是在/var/lib/redis/6379目录下。
进入到目录查看持久化文件
持久化时间为05:28,手动执行save操作再次查看,时间变更为08:02
如果使用bgsave操作,会启动一个后台进程
查看操作日志,查看具体的操作时间
由于创建子进程会消耗额外的内存,所以save创建RDB文件的速度会比bgsave快,可以集中资源来创建RDB文件,save和bgsave没有孰好孰坏之分,要考虑的就是哪个更适合。比如数据库正在上线当中,当然是用bgsave,如果要维护,在凌晨,那最好是用save。比如维护需要停机一段时间,那就可以使用save命令,这是系统被阻塞了也没有关系。
2.自动创建RDB文件
在配置文件中设置
save 300 10
表示如果距离上一次创建RDB文件已经过去了300秒,并且服务器的所有数据库总共已经发生了不少于10次修改,那么执行bgsave命令
save 60 10000
表示如果距离上一次创建RDB文件已经过去了60秒,并且服务器的所有数据库总共已经发生了不少于10000次修改,那么执行bgsave命令
用户还可以通过多个save选项设置多个自动保存的条件,当任意一个条件被满足时,服务器就会自动执行bgsave命令。
每次创建RDB文件之后,服务器为实现自动持久化而设置的时间计数器和次数计数器就会被清零。并重新开始计数,所以多保存条件的效果不会叠加。
2.AOF
1.RDB缺点
RDB持久化有一个缺点,那就是因为创建RDB文件需要将服务器所有的数据库的数据都保存起来,这是一个非常耗费资源和时间的操作所以服务器需要每隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件的操作不能执行的过于频繁,否则就会严重影响服务器的性能。
为了解决RDB持久化的缺点,AOF持久化有一个巨大的优势,用户可根据自己的需要对AOF持久化进行调整,让redis在遭遇停机是不丢失任何数据,或者只丢失一秒钟的数据。
2.安全性问题
虽然服务器执行一个修改数据库的命令,就会被执行的命令写入到AOF文件中,但这并不意味着AOF文件持久化不会丢失任何数据。
在操作系统中,执行系统调用write函数,将一些内容写入到某个文件里面时,为了提高效率,系统通常不会直接将内容写入硬盘里面,而是先将内容放入一个内存缓冲区(buffer)里面,等到缓冲区被填满,或者用户执行fsync调用和fdatasync调用时才将存储在缓冲区里面的内容真正写入到硬盘里面。
为了控制redis服务器在遇到意外停机时数据的丢失,redis为AOF持久化提供了appendfsync选项,这个选项的值可以是always、everysec或者no。
always:服务器每写入一个命令,就调用一次fdatasync,将缓冲区里面的命令写入到键盘里面,在这种模式下,服务器即使遭遇意外停机,也不会丢失任何自己已经成功执行的命令数据。
everysec:服务器每一秒重调用一次fdatasync,将缓冲区里面的命令写入到硬盘里面,在这种模式下,服务器即使遭遇意外停机时,最多只丢失一秒钟内的执行的命令数据。
no:服务器不主动调用fdatasync,由操作系统决定任何将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器遭遇意外停机,丢失命令的数据量是不确定的。
运行速度:always的速度慢,everysec和no速度快
默认值:everysec