AOF与RDB

130 阅读6分钟

RDB(Redis Database) 快照持久化

Redis Server在多有db 中存储的key-value可以理解为Redis的一个状态。当发生写操作时,Redis就会从一个状态切换到另外一个状态。基于全量的持久化就是在某个时刻,将Redis的所有数据持久化到硬盘中,形成一个快照。当Redis 重启时,通过加载最近一个快照数据,可以将Redis 恢复至最近一次持久化状态上。

特点

RDB(Redis Database)是Redis默认的持久化方式,它具有以下几个主要特点:

  • 快照持久化
    • RDB是对Redis中数据的一次完整备份。Redis会 Fork 出一个子进程,将当前内存中的所有数据以二进制文件形式保存到磁盘上,这个文件就是 RDB 文件。
  • 按照配置定期自动触发
    • Redis可以配置自动触发 RDB 的频率,如 1分钟保存一次,从而避免数据过多时只依赖AOF造成的恢复速度过慢问题。
  • 只保存数据集,不保存操作日志
    • RDB 只记录当前 Redis 的数据快照,不记录数据变化的操作日志。所以使用 RDB 如果发生故障,将丢失最后一次创建 RDB 文件后发生的数据变化。
  • 恢复速度快
    • Redis重启或恢复时,只需要加载 RDB 文件即可快速恢复数据,而不需要重新执行所有命令。
  • 可用于冷备份
    • RDB文件可进行冷备份,如复制到其他服务器上。

总体来说,RDB持久化方式通过快照保存数据,恢复速度快,且可以实现冷备份,但可能会丢失部分数据。需要配合AOF日志持久化来提供完整和高效的持久化方案。

写入流程

Redis的全量写入包含2种方式:save 和 bgsave,两者的处理逻辑如下:

  • save 可以由客户端显示触发的,也可以在redis shutdown 时触发。Save本身是单线程串行化的方式执行的,因此当数据量大时,有肯能会发生Redis Server的长时间卡顿。但是其备份期间不会有其他命令执行,因此备份在这一时刻是一致性的。
  • bgsave 也可以由客户端显示触发、可以通过配置定时任务触发也可以在master-slave的分布式结构下由slave节点触发。bgsave命令在执行的时候,会fork一个子进程。子进程提交完成之后,会立即给客户端返回响应,备份操作在后台异步执行,在此期间不会影响Redis的正常响应。 image.png

对于bgsave来说,当父进程Fork完子进程之后,异步任务会将当前的内存状态作为一个版本进行复制。在复制过程中产生的变更,不会反映在这次备份当中。在Redis的默认配置当中,当满足下面任一条件时,会自动触发bgsave 的执行。

配置secondschanges
save9001
save30010
save6010000

bgsave相对于Save来说,其优势是异步执行,不影响后续的命令执行。但是Fork子进程时,涉及父进程的内存复制,此时会增加服务器的内存开销。当内存开销高到使用虚拟内存时,bgsave的Fork子进程会阻塞运行,可能会造成秒级的不可用。因此使用bgsave需要保证服务器空闲内存足够。

命令savebgsave
IO类型同步异步
是否阻塞阻塞非阻塞(在fork是阻塞)
复杂度0(n)O(n)
优点不会消耗额外内存不阻塞客户端命令
缺点阻塞客户端命令需要Fork子进程,内存开销大

恢复流程

当Redis重新启动时,会从本地磁盘加载之前持久化的文件。当恢复完成之后,再受理后续的请求操作。

AOF(Append Only File) 日志持久化

RDB记录的是每个状态的全量数据,而AOF(append-only-file)记录的则是每条写命令的记录,通过所有写命令的执行,最后恢复出最终的数据状态。

特点

AOF(Append Only File)是Redis的另一种持久化方式,主要具有以下特点:

  • 命令日志持久化
    • AOF会记录执行过的所有写命令,并在Redis重启时重新执行这些命令来恢复数据状态。
  • 引起文件膨胀
    • AOF文件会变得越来越大,需要定期重写(rewrite)来删除或合并不必要的命令。
  • 恢复完整性更好
    • 使用AOF持久化可以最大程度保证数据不丢失,只要日志文件没有损坏,服务器就可以从日志文件中恢复出所有的数据。
  • 恢复速度较慢
    • AOF重启恢复需要重新执行所有命令,速度较RDB恢复慢,特别是数据集很大时。
  • 只允许追加
    • AOF文件只能追加内容,不能删除或修改已有内容。
  • 支持数据压缩
    • 支持命令合并,使文件体积不至于过大。

总体来说,AOF通过命令日志记录数据库状态变化,最大限度保证数据不丢失,但可能导致文件过大和恢复速度变慢。建议与RDB一起使用,发挥各自的优势。

写入流程

Redis的AOF 包含3 种同步策略:

  • always:每一次的刷新缓冲区,都会同步触发同步操作。因为每次的写操作都会触发同步,所以该策略会降低Redis的吞吐量,但是这种模式会拥有最高的容错能力。
  • every second:每秒异步的触发同步操作,这种是Redis的默认配置。
  • no:由操作系统决定何时同步,这种方式Redis无法决定何时落地,因此不可控。

image.png

命令alwayseverysecno
优点不丢失数据每秒1次fsync,丢1秒数据无需设置
缺点IO开销大,一般的STAT盘只有几百TPS丢1秒数据不可控

恢复流程

AOF的回放时机也是在机器启动时,一旦存在AOF,Redis会选择增量回放。因为增量的持久化持续的写入磁盘,相比全量持久化,数据更加完整。回放的过程就是将AOF中存放的命令,重新执行一遍。完成之后再继续接受客户端的新命令。

AOF重写

随着Redis 持续的运行,会有大量的增量数据append 到AOF 文件中。为了减小硬盘存储和加快恢复速度,Redis 通过rewrite 机制合并历史AOF 记录。如下所示:

image.png

整个流程描述如下:

  • 历史AOF:以快照的方式保存。
  • 快照写入期间的增量:待快照写入完成之后append 到快照文件中。
  • 后续的增量:写入新的AOF。