Redis 持久性
Redis 提供了不同的持久性选项:
RDB 持久性以指定的时间间隔执行数据集的时间点快照.
AOF 持久性记录服务器接收的每个写入操作, 将在服务器启动时再次播放, 重建原始数据集. 使用与 Redis 协议本身相同的格式以仅追加方式记录命令. 当 Redis 太大时, Redis 能够重写日志背景.
如果您愿意, 只要服务器正在运行, 您就可以根据需要禁用持久性.
可以在同一实例中组合 AOF 和 RDB. 请注意, 在这种情况下, 当 Redis 重新启动时, AOF 文件将用于重建原始数据集, 因为它保证是最完整的.
最重要的是要理解 RDB 和 AOF 持久性之间的不同权衡. 让我们从 RDB 开始:
RDB 的优势
RDB 是 Redis 数据的一个非常紧凑的单文件时间点表示. RDB 文件非常适合备份. 例如, 您可能希望在最近 24 小时内每小时归档您的 RDB 文件, 并且每天保存 RDB 快照 30 天. 这使您可以在发生灾难时轻松恢复数据集的不同版本.
RDB 非常适合灾难恢复, 可以将单个压缩文件传输到远端数据中心, 也可以传输到 Amazon S3(可能是加密的).
RDB 最大限度地提高了 Redis 的性能, 因为 Redis 父进程为了坚持不懈而需要做的唯一工作就是分配一个将完成所有其余工作的孩子. 父实例永远不会执行磁盘 I / O 或类似操作.
与 AOF 相比, RDB 允许使用大数据集更快地重启.
RDB 的缺点
如果您需要在 Redis 停止工作时 (例如断电后) 将数据丢失的可能性降至最低, 则 RDB 并不好. 您可以配置生成 RDB 的不同
保存点(例如, 在对数据集进行至少五分钟和 100 次写入之后, 但您可以有多个保存点). 但是, 您通常每五分钟或更长时间创建一个 RDB 快照, 因此如果 Redis 因任何原因停止工作而没有正确关闭, 您应该准备丢失最新的数据分钟.
RDB 经常需要 fork()才能使用子进程持久存储在磁盘上. 如果数据集很大, Fork()可能会非常耗时, 并且如果数据集非常大且 CPU 性能不佳, 可能会导致 Redis 停止服务客户端几毫秒甚至一秒钟. AOF 也需要 fork(), 但你可以调整你想要重写日志的频率而不需要对耐久性进行任何权衡.
AOF 优势
使用 AOF Redis 更持久: 您可以使用不同的 fsync 策略: 根本没有 fsync, 每秒 fsync, 每次查询都有 fsync. 使用 fsync 的默认策略, 每秒写入性能仍然很好 (使用后台线程执行 fsync, 并且当没有 fsync 正在进行时, 主线程将努力执行写入.) 但是您只能丢失一秒的写入.
AOF 日志是仅附加日志, 因此如果停电, 则没有搜索, 也没有损坏问题. 即使由于某种原因 (磁盘已满或其他原因) 日志以半写命令结束, Redis-check-aof 工具也能够轻松修复它.
当 Redis 太大时, Redis 能够在后台自动重写 AOF. 重写是完全安全的, 因为当 Redis 继续附加到旧文件时, 使用创建当前数据集所需的最小操作集生成一个全新的文件, 并且一旦第二个文件准备就绪, Redis 会切换两个并开始附加到新的那一个.
AOF 以易于理解和解析的格式一个接一个地包含所有操作的日志. 您甚至可以轻松导出 AOF 文件. 例如, 即使您使用 FLUSHALL 命令刷新了所有错误, 如果在此期间未执行重写日志, 您仍然可以保存数据集, 只需停止服务器, 删除最新命令, 然后重新启动 Redis.
AOF 的缺点
AOF 文件通常比同一数据集的等效 RDB 文件大.
根据确切的 fsync 策略, AOF 可能比 RDB 慢. 一般来说, fsync 设置为每秒性能仍然非常高, 并且在 fsync 禁用的情况下, 即使在高负载下也应该与 RDB 一样快. 即使在写入负载很大的情况下, RDB 仍能够提供有关最大延迟的更多保证.
在过去, 我们遇到了特定命令中的罕见错误 (例如, 有一个涉及阻塞命令, 如 BRPOPLPUSH) 导致生成的 AOF 在重新加载时不会重现完全相同的数据集. 这个错误很少见, 我们在测试套件中进行测试, 自动创建随机复杂数据集并重新加载它们以检查一切正常, 但 RDB 持久性几乎不可能出现这种错误. 为了更清楚地说明这一点: Redis AOF 逐步更新现有状态, 如 MySQL 或 MongoDB, 而 RDB 快照一次又一次地创建所有内容, 这在概念上更加健壮. 但是 - 1)应该注意的是, 每次通过 Redis 重写 AOF 时, 都会从数据集中包含的实际数据开始重新创建, 与总是附加的 AOF 文件 (或者重写旧的 AOF 而不是读取内存中的数据) 相比, 对 bug 的抵抗力更强. 2)我们从未向用户提供过关于在现实世界中检测到的 AOF 损坏的单一报告.
好的, 那我该怎么用?
一般的迹象是, 如果您希望一定程度的数据安全性与 PostgreSQL 为您提供的数据安全性相当, 则应使用两种持久性方法.
如果你非常关心你的数据, 但是在发生灾难的情况下仍然会有几分钟的数据丢失, 你可以单独使用 RDB.
有许多用户单独使用 AOF, 但我们不鼓励它, 因为不时有 RDB 快照是进行数据库备份, 更快重启以及 AOF 引擎中出现错误的好主意.
注意: 由于所有这些原因, 我们可能最终将 AOF 和 RDB 统一为未来的单一持久性模型(长期计划).
以下部分将说明有关两种持久性模型的更多详细信息.
快照
默认情况下, Redis 将数据集的快照保存在磁盘上, 名为二进制文件 dump.rdb. 如果数据集中至少有 M 个更改, 则可以将 Redis 配置为每 N 秒保存数据集, 或者您可以手动调用 SAVE https://redis.io/commands/save 或 BGSAVE https://redis.io/commands/bgsave 命令.
例如, 如果至少更改了 1000 个密钥, 则此配置将使 Redis 每 60 秒自动将数据集转储到磁盘:
save 60 1000
此策略称为快照.
这个怎么运作
每当 Redis 需要将数据集转储到磁盘时, 就会发生以下情况:
Redis 叉子 http://linux.die.net/man/2/fork . 我们现在有一个子进程和一个父进程.
孩子开始将数据集写入临时 RDB 文件.
当孩子完成编写新的 RDB 文件后, 它将替换旧文件.
此方法允许 Redis 受益于写时复制语义.
仅附加文件
快照不是很耐用. 如果运行 Redis 的计算机停止运行, 电源线发生故障, 或者您 kill -9 的实例意外, 则 Redis 上写入的最新数据将丢失. 虽然这对某些应用程序来说可能不是什么大问题, 但是有完整持久性的用例, 在这些情况下, Redis 不是一个可行的选择.
该只追加文件是 Redis 的选择, 完全耐用的策略. 它在 1.1 版中可用.
您可以在配置文件中打开 AOF:
appendonly yes
从现在开始, 每次 Redis 收到更改数据集的命令 (例如 SET https://redis.io/commands/set ) 时, 它都会将其附加到 AOF. 重新启动 Redis 时, 它将重新播放 AOF 以重建状态.
记录重写
你可以猜到, 随着执行写操作, AOF 变得越来越大. 例如, 如果您将计数器递增 100 次, 则最终会在数据集中包含一个包含最终值的单个键, 但在 AOF 中会有 100 个条目. 重建当前状态不需要其中 99 个条目.
所以 Redis 支持一个有趣的功能: 它能够在后台重建 AOF 而不会中断对客户端的服务. 每当您发出 BGREWRITEAOF 时, https://redis.io/commands/bgrewriteaof Redis 都会编写在内存中重建当前数据集所需的最短命令序列. 如果您在 Redis 2.2 中使用 AOF, 则需要不时运行 BGREWRITEAOF https://redis.io/commands/bgrewriteaof .Redis 2.4 能够自动触发日志重写(有关详细信息, 请参阅 2.4 示例配置文件).
仅附加文件的持久性如何?
您可以配置 Redis http://linux.die.net/man/2/fsync 在磁盘上的数据次数. 有三种选择:
appendfsync always:fsync 每次将新命令附加到 AOF. 非常非常慢, 非常安全.
appendfsync everysec:fsync 每秒. 足够快(2.4 可能与快照一样快), 如果发生灾难, 您可能会丢失 1 秒的数据.
appendfsync no: 从不 fsync, 只需将数据放在操作系统的手中. 更快, 更不安全的方法. 通常情况下, Linux 将使用此配置每 30 秒刷新一次数据, 但这取决于内核的精确调整.
建议 (和默认) 策略是 fsync 每秒. 它非常快速且非常安全. 该 always 策略在实践中非常慢, 但它支持组提交, 因此如果有多个并行写入, Redis 将尝试执行单个 fsync 操作.
如果我的 AOF 被截断, 我该怎么办?
服务器可能在写入 AOF 文件时崩溃, 或者存储 AOF 文件的卷存储已满. 发生这种情况时, AOF 仍然包含表示数据集的给定时间点版本的一致数据(使用默认的 AOF fsync 策略可能会持续一秒钟), 但 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 在此类情况下停止, 但无论文件中的最后一个命令格式不正确, 都要继续默认配置, 以确保重新启动后可用.
旧版本的 Redis 可能无法恢复, 可能需要执行以下步骤:
制作 AOF 文件的备份副本.
使用 Redis-check-aofRedis 附带的工具修复原始文件:
$ Redis-check-aof --fix
可以选择 diff -u 用于检查两个文件之间的区别.
使用固定文件重新启动服务器.
如果我的 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 使用相同的格式 Redis 协议, 手动修复非常简单. 否则可以让实用程序为我们修复文件, 但是在这种情况下, 从无效部分到文件末尾的所有 AOF 部分都可能被丢弃, 如果发生损坏, 会导致大量数据丢失在文件的初始部分.
这个怎么运作
日志重写使用已用于快照的相同的写时复制技巧. 这是它的工作原理:
Redis 分叉 http://linux.die.net/man/2/fork , 所以现在我们有了一个子进程和一个父进程.
孩子开始在临时文件中写入新的 AOF.
父级会在内存缓冲区中累积所有新更改(但同时它会将旧更改写入旧的仅附加文件中, 因此如果重写失败, 我们就是安全的).
当子进程重写文件时, 父进程会获得一个信号, 并在子进程生成的文件末尾附加内存缓冲区.
利润! 现在, Redis 以原子方式将旧文件重命名为新文件, 并开始将新数据附加到新文件中.
如果我当前正在使用 dump.rdb 快照, 如何切换到 AOF?
在 Redis 2.0 和 Redis 2.2 中执行此操作有不同的过程, 因为您可以猜测它在 Redis 2.2 中更简单, 并且根本不需要重新启动.
Redis> = 2.2
备份最新的 dump.rdb 文件.
将此备份转移到安全的地方.
发出以下两个命令:
- Redis-cli config set appendonly yes
- Redis-cli config set save""
确保您的数据库包含相同数量的密钥.
确保写入正确附加到仅附加文件.
第一个 CONFIG 命令启用仅附加文件. 为了做到这一点, Redis 将阻止生成初始转储, 然后将打开文件进行写入, 并将开始附加所有下一个写入查询.
第二个 CONFIG 命令用于关闭快照持久性. 如果您希望可以同时启用持久性方法, 则这是可选的.
重要提示: 请记住编辑 Redis.conf 以打开 AOF, 否则当您重新启动服务器时, 配置更改将丢失, 服务器将使用旧配置重新启动.
Redis 2.0
备份最新的 dump.rdb 文件.
将此备份转移到安全的地方.
停止对数据库的所有写入!
发布 Redis-cli bgrewriteaof. 这将创建仅附加文件.
Redis 完成生成 AOF 转储后停止服务器.
编辑 Redis.conf end enable 仅附加文件持久性.
重启服务器.
确保您的数据库包含相同数量的密钥.
确保写入正确附加到仅附加文件.
AOF 和 RDB 持久性之间的相互作用
Redis> = 2.4 确保在 RDB 快照操作正在进行时避免触发 AOF 重写, 或者在 AOF 重写正在进行时允许 BGSAVE. 这可以防止两个 Redis 后台进程同时执行大量磁盘 I / O.
当快照正在进行且用户使用 BGREWRITEAOF 明确请求日志重写操作时, 服务器将回复一个 OK 状态代码, 告诉用户操作已安排, 并且一旦快照完成, 重写将开始.
在启用 AOF 和 RDB 持久性并且 Redis 重新启动的情况下, AOF 文件将用于重建原始数据集, 因为它保证是最完整的.
备份 Redis 数据
在开始本节之前, 请务必阅读以下句子: 确保备份您的数据库. 磁盘中断, 云中的实例消失, 等等: 没有备份意味着数据消失在 / dev / null 中的巨大风险.
Redis 非常适合数据备份, 因为您可以在数据库运行时复制 RDB 文件: RDB 一旦生成就永远不会被修改, 并且在生成它时会使用临时名称并仅使用 rename(2)以原子方式重命名为其最终目标新快照完成时.
这意味着在服务器运行时复制 RDB 文件是完全安全的. 这就是我们的建议:
在服务器中创建一个 cron 作业, 在一个目录中创建 RDB 文件的每小时快照, 在另一个目录中创建每日快照.
每次运行 cron 脚本时, 请务必调用该 find 命令以确保删除过旧的快照: 例如, 您可以获取最近 48 小时的每小时快照, 以及一到两个月的每日快照. 确保使用数据和时间信息命名快照.
每天至少有一次确保在数据中心外部
或至少在运行 Redis 实例的物理机器外部传输 RDB 快照.
如果运行仅启用 AOF 持久性的 Redis 实例, 则仍可以复制 AOF 以创建备份. 该文件可能缺少最后一部分, 但 Redis 仍然可以加载它(请参阅前面有关截断的 AOF 文件的部分).
灾难恢复
Redis 环境中的灾难恢复基本上与备份相同, 并且能够在许多不同的外部数据中心中传输这些备份. 这样, 即使在某些灾难性事件影响 Redis 正在运行并生成其快照的主数据中心的情况下, 数据也是安全的.
由于许多 Redis 用户都处于启动阶段, 因此没有足够的资金支出, 我们将审查最有趣的灾难恢复技术, 这些技术的成本不会太高.
Amazon S3 和其他类似服务是实施灾难恢复系统的好方法. 只需以加密形式将每日或每小时 RDB 快照传输到 S3 即可. 您可以使用 gpg -c(在对称加密模式下)加密数据. 确保将密码存储在许多不同的安全位置(例如, 将副本提供给组织中最重要的人员). 建议使用多个存储服务以提高数据安全性.
使用 SCP(SSH 的一部分)将快照传输到远程服务器. 这是一个相当简单和安全的途径: 在离你很远的地方获得一个小 VPS, 在那里安装 SSH, 并生成一个没有密码短语的 SSH 客户端密钥, 然后将其添加 authorized_keys 到你的小 VPS 文件中. 您已准备好以自动方式传输备份. 在两个不同的提供商中获得至少两个 VPS 以获得最佳结果.
重要的是要理解, 如果没有以正确的方式实施, 该系统很容易失败. 至少要确保在传输完成后您能够验证文件大小 (应该与您复制的文件相匹配) 以及可能的 SHA1 摘要(如果您使用的是 VPS).
如果由于某种原因传输新备份不起作用, 您还需要某种独立的警报系统.
参考: https://redis.io/topics/persistence
来源: http://www.bubuko.com/infodetail-3098836.html