接上文AOF持久化。记录了Redis所有的操作命令。故障恢复时,需要把所有的操作命令重新执行一遍,恢复速度很慢。有没有安全可靠能快速恢复数据的方法呢?Redis还提供了RDB内存快照机制。
RDB保存的是全量数据,他是把Redis内存数据以二进制文件的形式进行保存。头一个我们要考虑的问题是拷贝阶段会阻塞主进程吗?
这里RDB提供了两种方式 save bgsave
- save:在主线程中执行,会导致阻塞;
- bgsave:创建一个子进程,专门用于写入 RDB 文件,避免了主线程的阻塞,这也是 Redis RDB 文件生成的默认配置。
同样的bgsave的子进程使用的COW写时复制技术,如图:
第二个我们要关心的问题是多久进行一次RDB拷贝。 Redis配置中 save 来动态指定频率
这里摘抄redis.conf注释来解答一下 表示
15分钟内修改1-10个key 备份一次
5分钟内修改10-10000个key 备份一次
1分钟10000个key以上 备份一次
save 900 1
save 300 10
save 60 10000
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
虽然bgsave并不阻塞主线程但是也会和主线程争抢CPU資源,因此频率并非最短越好。另外快照备份如果太频繁还会对磁盘造成压力,导致连锁反应,越来越慢。
可以明确的是全量快照开销较大,所以在一次全量快照后,后续会执行增量快照,也就是在两次快照之间记录修改了哪些数据,根据这个执行。但是这也增加了额外的空间开销,于是乎对于Redis这种内存宝贵的系统而言就需要在空间开销和时间开销之间做选择。
有没有两全其美的方法呢?有的有的。Redis4.0提出了混合使用AOF和RDB的方法。还是以一定频率执行快照,在快照之间使用AOF来记录所有命令操作,等下一次快照时,把AOF清空。这样既享受了RDB文件的快速恢复功能,有享受了AOF只记录操作命令的简单。