RDB(Redis DataBase)快照就是记录某一个瞬间的内存数据,记录的是实际数据(二进制);而 AOF 文件记录的是命令操作(文本)

在 Redis 恢复数据时, RDB 恢复数据的效率会比 AOF 高些,因为直接将 RDB 文件读入内存就可以,不需要像 AOF 那样逐一执行操作命令

快照怎么用?

Redis 提供了两个命令来生成 RDB 文件,分别是 save 和 bgsave,它们的区别在于是否在「主线程」中执行:

  • save:在主线程生成 RDB 文件
  • bgsave:创建一个子进程生成 RDB 文件

RDB 文件的加载是在 Redis 启动时自动执行的

还可以通过配置文件实现每隔一段时间自动执行一次 bgsave 命令,配置:

// redis.conf

// Redis 6.0.16
save 900 1
save 300 10
save 60 10000

// Redis 6.2
save 900 1 300 10 60 10000

// 快照禁用
save ""

别看配置项叫 save,实际上执行的是 bgsave 命令。只要满足条件的任意一个,就会执行:

  • 900 秒内,对数据库进行了至少 1 次修改
  • 300 秒内,对数据库进行了至少 10 次修改
  • 60 秒内,对数据库进行了至少 10000 次修改

RDB 快照是全量快照,就是每次执行快照,都是把内存中的「所有数据」都记录到磁盘中

可以认为,执行快照是一个比较「重」的操作:如果太频繁,可能会对 Redis 性能产生影响;如果频率太低,服务器故障时,丢失的数据会更多

通常可能设置至少 5 分钟才保存一次快照

其他配置:

// redis.conf

dir ./              // 文件保存路径
dbfilename dump.rdb // 文件名称

执行快照时,数据能被修改吗?

执行 bgsave 过程中,Redis 依然可以继续处理操作命令,即数据能被修改,关键技术就在于写时复制技术

bgsave 快照过程中,如果主线程修改了共享数据,发生了写时复制后,RDB 快照保存的还是原本的内存数据,而主线程刚修改的数据,只能==交由下一次的 bgsave 快照==

混合持久化

  • AOF 日志:每次实时记录一个命令,发生故障时,丢失的数据很少
  • RDB 快照:全量快照,执行的频率不能太频繁,发生故障时,丢失的数据会比较多

没有什么方法不仅有 RDB 恢复速度快的优点,又有 AOF 丢失数据少的优点呢?

那就是将 RDB 和 AOF 合体使用,这个方法是在 Redis 4.0 提出的,叫作混合持久化

// redis.conf
aof-use-rdb-preamble yes // 开启混合持久化功能

混合持久化工作在 AOF 日志重写过程

  • 在 AOF 重写日志时,fork 出来的重写子进程会先将与主线程共享的内存数据以 RDB 方式写入到 AOF 文件
  • 主线程在此期间处理的写命令会被记录在重写缓冲区中,重写缓冲区里的增量命令会以 AOF 方式追加写入到 AOF 文件

也就是说,使用混合持久化,AOF 文件的前半部分是 RDB 格式的全量数据,后半部分是 AOF 格式的增量数据

重启 Redis 加载数据时:

  • 前部分是 RDB 内容,加载速度快
  • 后部分是 AOF 内容,是 Redis 后台子进程重写 AOF 期间,主线程处理的写命令,可以使得数据更少的丢失