快照的使用
RDB快照和AOF的不同在于,AOF记录的是写命令,恢复数据时还需要执行操作命令,而RDB记录的是实际数据(二进制数据),可以直接读入内存,恢复速度快
可以通过配置文件设置每隔一段时间就执行一次bgsave命令进程RDB持久化
#900 秒之内,对数据库进行了至少 1 次修改
save 900 1
#300 秒之内,对数据库进行了至少 10 次修改
save 300 10
#60 秒之内,对数据库进行了至少 10000 次修改
save 60 10000
虽然是save命令,但是其实和bgsave是一样的都会创建子进程来生成RDB快照文件
-
由于RDB是全量快照,也就是每次持久化时会将内存中的所有数据记录到磁盘,一般需要5分钟的时间。这就导致不能频繁地执行快照,会使得Redis的性能下降,而频率过低,又会导致丢失许多数据。而AOF是可以以秒级别进行持久化操作的,丢失的数据就比较少
-
值得注意的是,子进程执行RDB快照的过程中,如果父进程对和子进程共享的数据(已经存在的键值对)进行了修改,由于写时复制技术(具体可以参见AOF持久化),父进程修改的物理内存会被复制一份出来给子进程,然后父进程再修改它的那份数据,而这时和AOF持久化不同的地方来了,父进程修改的键值对在子进程中,还是原来的数据,RDB持久化的时候,RDB文件中记录的还是旧的数据。如果要记录这些旧的数据,就得等下一次RDB持久化了。可是倘若在RDB持久化之后Redis奔溃,就会丢失在RDB持久化期间主进程修改的数据。
-
写时复制还有个极端的情况,就是如果子进程执行快照期间,如果主进程修改了所有数据,那么所有的共享数据在内存中就会被复制一份,也就是内存变为原来的两倍。因此在子进程执行快照的过程中,需要留意内存的变化,防止内存被占满
混合持久化
RDB恢复速度快,但是执行频率太高会降低性能;AOF则可以比较频繁地进行持久化,因此数据不容易丢失。
Redis4.0之后,通过配置项aof-use-rdb-preamble yes
可以实现混合持久化
混合持久化中,在AOF重写时,主进程fork处理的子进程会先将与父进程共享的内存数据以RDB的方式写入AOF文件,然后主进程的写操作命令会被记录在重写缓冲区,重写结束后子进程通知主进程将重写缓冲区中的写指令写入新的AOF文件,然后用新的AOF文件替换旧的AOF文件
这样,AOF文件中不仅有RDB格式的全量数据,还有AOF格式的增量数据,这样一来,使用AOF文件进行恢复操作的速度就大大加快了。
同时,子进程执行AOF重写过程中主进程的修改操作也可以被保存,数据丢失更少