什么是RDB和AOF

62次阅读
没有评论

共计 7095 个字符,预计需要花费 18 分钟才能阅读完成。

这篇文章主要介绍“什么是 RDB 和 AOF”,在日常操作中,相信很多人在什么是 RDB 和 AOF 问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是 RDB 和 AOF”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

Redis 持久化

Redis 提供了不同级别的持久化选项:

RDB 模式, Redis 数据库备份文件 (Redis Database Backup) 持久化方式, 提供周期性基于时间点的数据集快照备份,   比如每小时生成一个快照备份.

AOF 模式, 仅追加到文件 (AppendOnlyFile) 持久化方式, 在每次数据库服务收到写操作时记录日志文件, 当服务重启时,   自动回放该日志来重建原始数据集. 日志中使用 Redis 自己的协议, 并按照统一的格式, 采用只追加的方法记录. 当日志文件太大时,  Redis 可以在后台重写该日志, 生成一个最小化版本的日志文件.

你也可以完全禁用持久化, 比如只要保证服务在运行中有数据或可以自动生成缓存数据即可.

你还可以在同一个 Redis 实例上结合 AOF 和 RDB 两种持久化方式. 请注意: 这种方式在 Redis 重启时, AOF 文件会被用来重建原始数据集, 因为,   相对 RDB 周期快照的方式, AOF 被认为是更完整的数据备份, 比如它可以做到准实时备份(只丢失 1 秒的数据).

接下来, 让我们来对比 RDB 和 AOF 的优缺点:

RDB 优点

RDB 采用一个压缩单文件来表示基于时间点的 Redis 数据, RDB 文件是完美的备份. 例如, 你可以保留过去 24 小时的每小时的快照备份,   并且保存过去 30 天, 每天的快照备份, 当数据遇到丢失时, 你可以很方便的从不同的备份粒度 (版本) 来恢复数据集.

RDB 用来做灾备恢复非常好, 因为紧凑的单文件非常便于在远端数据中心或者亚马逊 S3(对象存储, 可以加密)间传输.

RDB 使 Redis 性能最大化, 因为 Redis 父进程只需要启动一个子进程完成快照备份即可, 父进程不执行由备份引起的磁盘 I /O

与 AOF 模式相比, RDB 在大数据集的情况下, 数据恢复时, 服务重启速度更快.

RDB 缺点

如果你想要在 Redis 意外停止工作时(比如断电), 最小可能的丢失数据, RDB 不是一个好的方案. 你可以在 RDB 生成的地方,   配置不同的保存点(比如每 5 分钟, 对数据集产生至少 100 次写操作时, 创建一个保存点, 你也可以配置多个保存点策略). 然而,   这样你通常会在每 5 分钟甚至更长时间间隔才创建 RDB 快照, 所以当 Redis 异常停止工作时, 你会丢失最后产生快照时间点到现在的数据.

RDB 会调用系统 fork()方法派生一个子进程来完成数据持久化到硬盘. 如果数据集比较大, Fork()方法会非常耗时, 造成 Redis 停止为客户端服务,   停止时间可能是上微秒, 如果数据集非常大并且 CPU 性能不是很好, 停止时间可以达到 1 秒钟或更多. 在持久化时, AOF 也会调用 fork()方法,   但是你可以不带任何协商(trade-off), 调整重写日志的频率.

AOF 优点

使用 AOF 持久化程度更高: 你可以配置不同的 fsync 策略:

不带 fsync

每秒钟一次 fsync

每次查询的时候 fsync

注: fsync(https://man7.org/linux/man-pages/man2/fsync.2.html)是系统方法,   用于将内核态的缓存数据持久化到存储设备, 比如将内存数据写入硬盘

默认使用每秒执行一次 fsync 的策略, 这种场景下, Redis 的写性能也能非常好, 因为 fsync 运行在一个后台线程, 而主线程会尽力完成写操作.   所以你最多丢失 1 秒钟的数据.

AOF 日志是一个只能追加的文件, 所以在断电后, 该文件不会出现查找 (seek) 或损坏的问题. 即使由于磁盘满或其他原因导致日志中存在只写了一半的命令,   也可以使用 redis-check-aof 工具轻松修复.

Redis 会在 AOF 文件太大的时候, 自动在后台重写日志. 重写十分安全, 重写时,  Redis 派生一个子进程将大的 AOF 文件重写为最小可用的数据集日志文件, 此时有写操作时,  Redis 继续追加到旧的 AOF 文件的同时也追加到 AOF 重写缓冲区 aof_rewrite_buf, 重写完成时, 新的小 AOF 文件将合并缓冲区中的新数据,   最后将新的 AOF 文件重命名为老的 AOF 文件完成替换操作, 以后的数据将写入新的 AOF 文件.

AOF 日志文件以一种容易理解和解析的格式依次记录了所有的操作. 导出一个 AOF 文件非常容易.   甚至在失误执行了清除命令 FLUSHALL(https://redis.io/commands/flushall) , 如果这时候重写操作没有被执行,   你仍然可以通过关闭服务, 删除文件最后的错误命令, 重启 Redis 完成数据恢复.

AOF 缺点

对于相同的数据集, AOF 文件一般比 RDB 文件大.

根据具体的 fsync 策略, AOF 可能比 RDB 速度慢. 通常默认的每秒 fsync 策略下, Reids 性能也非常高, 如果禁用 fsync,   即使在高负载的情况下, AOF 的速度应该和 RDB 一样快. 尽管如此, 在巨大写负载的情况下, RDB 提供了更多最大延迟的保证.

在过去,   当执行一些特殊的命令时(比如这里有一个涉及到阻塞的命令 BRPOPLPUSH:https://redis.io/commands/brpoplpush),  Redis 遇到了一些罕见的 BUG, 它会导致 AOF 重建数据时, 数据出现不一致. 这些问题非常罕见, 我们进行了单元测试,   自动创建随机复杂的数据集来执行重建测试, 没有出现这些问题. 但是如果使用 RDB 持久化, 几乎不可能出现这类问题. 为了清楚的说明这一点:  AOF 类似 MySQL 或者 MongoDB, 采用增量更新现有状态的工作机制, 但是 RDB 快照是每次从头开始创建, 从概念上来说, RDB 更具有鲁棒性(健壮).   但是有以下两点值得注意:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

每次 AOF 被 Redis 重写的时候,它会从包含在数据集中的实际数据中从头开始重新创建,使新 AOF 文件对 bug 的抵抗力比不重写的, ,   一直追加的 AOF 文件更强.

在实际使用中, 我们重来没有收到过一个关于 AOF 文件出错的用户报告.

那我该使用哪个?

通常, 如果你想获得像 PostgreSQL 那样的数据安全性, 你应该结合 RDB 和 AOF.

如果你非常关心你的数据, 但是允许丢失几分钟的数据, 你可以只使用 RDB 持久化.

有很多用户只使用 AOF, 但是我们不建议那样做, 因为 RDB 的基于时间点的快照在做数据库备份, 快速重启, 或 AOF 引擎出现问题时, 非常有用.

注意: 基于这些原因, 在将来(长期计划), 我们最终会统一 AOF 和 RDB 为一个持久化模型方案.

下面几节, 我们来举例说明更多, 关于 RDB 和 AOF 的细节.

快照

Redis 默认保存快照到硬盘上的 dump.rdb 文件. 你可以配置, 每 N 分钟, 至少出现了 M 次数据集改变执行一次快照, 或者手动执行保存 SAVE   或后台保存 BGSAVE 命令.

save 60 1000

它是如何工作的?

每当 Redis 需要保存数据集到磁盘, 会执行下面的任务:

Redis forks 派生子进程, 这时候会存在一个父进程和一个子进程.

子进程开始将数据集写到 RDB 临时文件.

当子进程完成新 RDB 文件写入后, 会将原来的旧 RDB 文件替换.

这种方法就是 Redis 的写即拷语义(copy-on-write)

AOF 仅追加文件

快照不是很持久, 如果 Redis 服务异常停止, 掉电停止, 或者意外执行了 kill - 9 杀掉 Redis 服务进程, 最后的数据写入将会丢失.   虽然对于有些应用来说这是个小问题, 但对于要求完全持久化的场景, RDB 不是一个很好的选择.

appendonly yes

从现在开始, 每当 Redis 收到一个改变数据集的命令(比如 SET), 该操作将追加到 AOF 文件, 当你重启 Redis 时,   会基于 AOF 文件重建数据集.

日志重写

AOF 文件大小随着操作的增加而增加. 举个例子, 如果你想递增计数 100 次, 最终数据集中只包含一个键值就是最终的结果,   但是在 AOF 文件中有 100 条记录, 实际上在重建数据集时, 不需要剩余的 99 次记录.

所以 Redis 支持这个有趣的功能: 在不中断 Redis 服务的情况下, 后台进行 AOF 文件重写. 当执行后台重写命令 BGREWRITEAOF 时,  Reids 会将当前内存中的数据集以最短的有序命令集写下来. 如果你使用 Redis2.2, 你需要定时执行  BGREWRITEAOF(https://redis.io/commands/bgrewriteaof) , 从 Redis2.4 开始,   它可以自动触发日志重写(更多信息可以查看 2.4 的配置示例, 不同版本的配置(https://redis.io/topics/config)).

AOF 怎么持久化?

你可以配置时间间隔, Redis 来执行 fsync 到磁盘. 这里有三个策略:

appendfsync always: 每个新的命令追加到 AOF 文件时执行 fsync. 非常慢, 但是非常安全. 注意,   如果追加的命令来自多个客户端或管道的批量命令, 在发送响应之前, 这会被当做一次写操作, 只会执行一次 fsync.

appendfsync everysec: 每秒执行一次 fsync. 速度足够快(在 Redis2.4 版本中, 与 RDB 快照的速度一样快), 如果出现意外,   你最多丢失 1 秒的数据.

appendfsync no: 从不执行 fsync, 只把数据交给操作系统. 这虽然更快, 但是更不安全. 这种配置,   通常 Linux 会每 30 秒刷新一次数据到硬盘, 但实际时间可以通过内核配置调优.

每秒执行一次 fsync 是建议并且是默认的方式. 它既快又安全. appendfsync always 策略在实践中非常慢, 但是支持组提交,   所以可以将多个并行写操作合并, 执行一次 fsync 即可.

如果 AOF 文件被截断了应该怎么做?

在写 AOF 文件时, 服务器出现 crash 或磁盘空间满了, 这时候 AOF 依然包含一致的数据,   代表了给定时间点版本的数据集(默认 fsync 策略可能会丢失 1 秒的数据), 但是最后的命令在 AOF 记录中会被截断,   最新的 Redis 主干版本依然会导入所有的 AOF 文件内容, 但是会忽略最后的不完整的命令, 这时候, 服务器会发出警告日志:

* Reading RDB preamble from AOF file... * Reading the remaining AOF tail... # !!! Warning: short read while loading the AOF file !!! # !!! Truncating the AOF at offset 439 !!! # AOF loaded anyway because aof-load-truncated is enabled

你可以改变默认配置来强制停止这种事情发生, 但是默认配置会忽略最后这个不完整的命令, 为了保证服务重启后可用.

老版本的 Redis 不会自动恢复, 需要做以下步骤来恢复:

对 AOF 文件进行备份.

使用 Redis 提供的工具 redis-check-aof 修复该 AOF 文件:

$ redis-check-aof –fix

可以执行 diff -u 检查两个 AOF 文件的差异, 确认错误被修复.

用修复后的 AOF 文件重启 Redis 服务, 重建数据集.

AOF 文件被损坏了怎么办?

如果 AOF 文件不仅被截断了, 中间还被插入了无效的字节, 事情将变得更加复杂, Redis 在启动的时候会中断并提示:

* Reading the remaining AOF tail... # Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix  filename

最好是用 redis-check-aof 工具修复, 首先不适用 –fix 选项, 找到问题, 跳过该文件的错误位置, 查看是否可以手动修复该文件,  AOF 使用与 Reids 一致的协议格式, 所以非常便于手动修复, 否则就使用工具修复该文件, 这种情况, 从无效的位置到文件结束的数据都可能被丢失,   如果损坏位置发生在开头的位置, 则相当于丢失整个数据集.

它是怎样工作的?

日志重写使用了与快照一致的拷贝即写 (copy-on-write) 的方式, 步骤如下:

Redis 执行 forks 派生, 这样就有一个主进程和一个子进程.

子进程开始写入一个新的 AOF 到零时文件中.

Redis 继续追加到旧的 AOF 文件的同时也追加到 AOF 重写缓冲区 aof_rewrite_buf, 所以即使重新失败, 也是数据安全的.

当子进程完成了 AOF 文件重写, 父进程收到一个完成信号, 将缓存中的数据追加到新的 AOF 文件.

最后将新的 AOF 文件重命名为老的 AOF 文件完成替换操作, 以后的数据将写入新的 AOF 文件.

怎样从 dump.rdb 快照切换到 AOF

在 Redis2.0 和 Redis2.2 用不同的步骤来切换到 AOF, 而且 Redis2.2 切换到 AOF 更简单, 不需要重启.

Redis = 2.2

将最近的 dump.rdb 文件备份.

将备份文件传输到安全的地方.

执行以下两个命令:

鸿蒙官方战略合作共建——HarmonyOS 技术社区

redis-cli config set save #取消 RDB

redis-cli config set appendonly yes #开启 AOF

检查确认数据库中的键个数没有丢失.

检查写操作都正确的追加进了 AOF 文件.

第一个配置命令表示启用 AOF 功能. 这样 Redis 会阻塞来生成初始的备份, 然后打开新文件来写入操作记录,   后面的写操作将会持续追加到该 AOF 文件中.

第二个配置命令用来关闭 RDB 快照持久化. 这是可选的, 如果保留 save 表示同时使用 RDB 和 AOF 持久化.

重要: 记住同时修改 redis.conf 配置文件来打开 AOF, 否则服务重启时将使用原来的配置.

Redis 2.0

将最近的 dump.rdb 文件备份.

将备份文件传输到安全的地方.

停止所有写操作.

执行后台重写 AOF 命令 redis-cli BGREWRITEAOF. 该操作会创建 AOF 文件.

当 AOF 备份完成后, 停止 Redis 服务.

编辑 redis.conf, 启用 AOF 功能.

重启服务

检查确认数据库中的键个数没有丢失.

检查写操作都正确的追加进了 AOF 文件.

在 AOF 和 RDB 之间交互

Redis = 2.4 会保证当 RDB 快照在运行时, 避免触发一个 AOF 重写进程, 或者当 AOF 重写已经运行时, 不允许后台保存快照 BGSAVE.   这可以防止两个后台进程同时产生高负载的磁盘 I /O.

备份 Redis 数据

开始本节内容前, 请确认已经对数据库进行备份, 如果磁盘损坏, 云实例消失等, 没有备份意味着数据面临着巨大风险, 会消失在 黑洞  /dev/null 中.

Redis 对于数据备份非常友好, 即使数据库数据库运行中也允许你对数据进行拷贝备份: RDB 文件产生时就不会被修改, 快照备份期间, 它会生成零时的文件,   当快照最终备份完成后采用重命名替换原来的 RDB 文件.

这意味着服务在运行时, 拷贝 RDB 文件是非常安全的, 下面是我们的建议:

在服务器上, 创建定时任务 CronJob, 每小时执行一次 RDB 快照, 保存到一个目录, 并且在另外一个目录下保存每日快照.

每次定时任务执行时, 确认使用 find 命令查找最旧的快照, 将它们删除, 对于每小时快照, 你可以保留最近 48 小时, 对于每天快照,   你可以保留 1~2 个月. 并确包快照名包含时间信息.

每天至少做一次数据转存, 比如将 RDB 快照转存到其他数据中心, 或者至少从当前 Redis 服务物理机转存到其他地方.

如果你使用 ROF 持久化方式, 仍然可以拷贝 AOF 文件来做备份. 这个 AOF 文件即使丢失最后一小段数据,  Redis 也可以重建它们(请参考上面的截断 AOF 文件处理方式)

灾难恢复

灾难恢复和备份基本是一致的, 加上可以在许多不同的数据中心间转存这些备份数据. 这种情况下, 即使影响到最主要的数据中心,   其他地方的备份也是安全并且可以恢复的.

针对刚起步, 没有太多的资金来做大型备份, 这里也提供了一些不需要太大开销的灾备恢复技术:

AmazonS3 对象存储或其他类似服务是一个实现灾备恢复系统的好方法. 只需将每小时或每日的 RDB 快照加密后传输到 S3 即可, 你可以使用 gpg  -c(使用对称加密模式)对数据加密. 请确认将密码保存到不同的安全的地方(比如拷贝一份交给最重要的人来管理). 建议使用多种存储服务来提高数据安全性.

使用 SCP(SSH 的一部分)命令来将数据转存到其他服务器. 这是一个简单而且安全的方法: 在云端,   获取远离当前 Redis 服务的一个小型虚拟专用服务器 VPS, 在数据端, 安装 ssh, 生成不带密码的 ssh 客户端密钥,   将它添加到 VPS 的 authorized_keys 文件, 这样就可以继续实现自动免密转存备份数据到 VPS, 为了提高数据安全, 可以使用不同运营商,   不同网络区域的 VPS.

这种方式可能会导致文件传输失败, 所以在传输完成后, 至少要增加文件完整性校验, 比如校验文件大小, 如果使用 VPS, 甚至可以使用 SHA1 校验.

你也需要部署独立的监控报警系统, 对备份过程进行监控, 在备份失败时能及时发现并修复.

到此,关于“什么是 RDB 和 AOF”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-27发表,共计7095字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)