Redis 持久化机制深度解析:RDB 与 AOF 的原理、优缺点与企业级选型实践(advanced-java 高并发专题)

Redis 持久化机制深度解析:RDB 与 AOF 的原理、优缺点与企业级选型实践(advanced-java 高并发专题) Redis 持久化机制深度解析RDB 与 AOF 的原理、优缺点与企业级选型实践advanced-java 高并发专题【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/gh_mirrors/ad/advanced-java本专题源自 advanced-java 项目 高并发架构 缓存板块的核心面试问题Redis 的持久化有哪几种方式不同的持久化机制都有什么优缺点持久化机制具体底层是如何实现的本文将围绕 《Redis 的持久化》 展开结合仓库中主从复制、哨兵高可用、缓存雪崩、生产环境部署等章节把 RDB 与 AOF 的底层原理、优缺点、配置权衡和企业级组合方案讲透。读完你将能回答Redis 宕机后数据如何恢复为什么 AOF 数据更完整生产环境该怎样搭配 RDB 与 AOF以及持久化在主从、哨兵架构中扮演什么角色。1. 面试题与考点Redis 挂了内存里的数据怎么办1.1 面试题Redis 的持久化有哪几种方式不同的持久化机制都有什么优缺点持久化机制具体底层是如何实现的1.2 面试官心理分析Redis 如果仅仅只是将数据缓存在内存里面一旦 Redis 宕机再重启内存里的数据就全部丢失了。你必须使用 Redis 的持久化机制在将数据写入内存的同时异步地、缓慢地将数据写入磁盘文件进行持久化。这样当 Redis 宕机重启时就可以自动从磁盘上加载之前持久化的数据也许会丢失少许数据但至少不会把全部数据都弄丢。面试官考察这个问题针对的正是Redis 生产环境的高可用问题——Redis 挂了再重启内存里的数据会不会全丢能不能在重启的时候把数据恢复出来这决定了你的系统能不能扛住缓存层面的故障。2. 为什么要持久化灾难恢复与高可用的第一道防线2.1 持久化的本质灾难恢复与数据恢复持久化主要是做两件事灾难恢复和数据恢复在架构层面可以归类到高可用的一个环节。设想这样的场景Redis 整个挂了、对外不可用你要做的事情是让 Redis 尽快恢复可用。重启 Redis 让它尽快对外提供服务——但如果没做数据备份Redis 即使启动了也不可用因为数据都没了。此时大量请求过来缓存全部无法命中在 Redis 里根本找不到数据系统就死定了。2.2 不做持久化的后果缓存雪崩一旦缓存全部失效所有请求在 Redis 中无法命中就会全部打到 MySQL 这种数据源头上去瞬间出现缓存雪崩Cache AvalancheMySQL 一下子承接了远超其能力的高并发请求直接挂掉。这正是仓库中 《了解什么是 Redis 的雪崩、穿透和击穿》 里描述的缓存机器全盘宕机后、1 秒 5000 个请求全部落库、数据库必然扛不住的现象。而雪崩的事后解决方案恰恰就是持久化Redis 持久化一旦重启自动从磁盘上加载数据快速恢复缓存数据。所以如果你把 Redis 持久化做好把备份和恢复方案做到企业级的程度那么即使 Redis 故障了也可以通过备份数据快速恢复一旦恢复立即对外提供服务从而避免缓存雪崩。2.3 持久化在企业级备份中的位置通过 RDB 或 AOF都可以把 Redis 内存中的数据持久化到磁盘上然后把这些数据文件备份到别的地方去例如阿里云等云服务。即使 Redis 所在的服务器内存和磁盘数据同时丢失也能从云服务上拷贝回之前的数据放到指定目录重新启动 Redis——Redis 会自动根据持久化数据文件恢复内存中的数据继续对外提供服务。3. Redis 持久化的两种方式RDB 与 AOF3.1 RDB周期性快照RDBRedis DataBase持久化机制是对 Redis 中的数据执行周期性的持久化。它按时间间隔把某一时刻内存中的全量数据生成一份数据快照文件每次生成的快照文件都代表某一个时刻的 Redis 数据。3.2 AOFappend-only 写命令日志AOFAppend Only File机制则是对每条写入命令以日志的形式、用append-only只追加的模式写入一个日志文件中。Redis 重启的时候通过回放AOF 日志中的写入指令重新构建整个数据集。两种方式的本质区别在于维度RDBAOF记录内容周期性全量数据快照逐条写入命令日志恢复方式直接加载快照文件回放日志中的写入指令数据时效周期性可能落后较久最高可做到只丢 1 秒内数据3.3 数据备份与异地容灾通过 RDB 或 AOF 持久化到本地磁盘后还需要做异地备份可以把数据文件备份到云服务上例如 Amazon 的 S3 云服务或者国内的阿里云 ODPS 分布式存储按预定好的备份策略定期备份。当本机磁盘损坏、数据彻底丢失时从云端取回备份文件即可恢复。3.4 同时开启时以 AOF 为准如果同时使用 RDB 和 AOF 两种持久化机制那么在 Redis 重启的时候会使用 AOF 来重新构建数据因为 AOF 中的数据更加完整——AOF 记录的是每一条写入命令理论上可以还原到最近一秒的状态而 RDB 只是某个时间点的快照。4. RDB 持久化机制详解4.1 工作原理主进程 fork 子进程执行磁盘 IORDB 的核心设计是主进程与磁盘 IO 分离Redis 主进程只需要fork一个子进程让子进程去执行磁盘 IO 操作来完成 RDB 快照文件的生成主进程自身不参与磁盘写入从而几乎不影响对外提供的读写服务。典型的触发方式是周期性执行快照例如每隔几分钟或更长时间生成一次快照文件常见的 RDB 触发策略形如save 900 1表示 900 秒内至少有 1 次写操作即触发一次快照save 300 10、save 60 10000依此类推时间窗越短、写入量越大则触发越频繁具体数值以实际生产配置为准。4.2 优点非常适合做冷备RDB 会生成多个数据文件每个数据文件代表某一个时刻 Redis 的数据。这种多数据文件的方式可以把完整的数据文件发送到远程安全存储如 Amazon S3、阿里云 ODPS上以预定备份策略定期备份。对读写服务影响极小可保持高性能Redis 主进程只需 fork 一个子进程由子进程执行磁盘 IO 完成 RDB 持久化。恢复速度快相对于 AOF 持久化机制直接基于 RDB 数据文件重启和恢复 Redis 进程更加快速——加载一份完整快照远比回放大量命令日志快。4.3 缺点与注意点数据丢失窗口大如果想要在 Redis 故障时尽可能少地丢失数据RDB 不如 AOF。一般来说RDB 数据快照文件每隔 5 分钟或更长时间才生成一次这意味着一旦 Redis 进程宕机会丢失最近 5 分钟甚至更长时间的数据。fork 可能造成服务暂停RDB 每次 fork 子进程执行快照生成时如果数据文件特别大可能会导致对客户端提供的服务暂停数毫秒甚至数秒。这与生产环境中 Redis 内存规模直接相关——仓库 《生产环境中的 Redis 是怎么部署的》 明确指出一般线上生产环境Redis 的内存尽量不要超过 10g超过 10g 可能会有问题其中一个重要原因正是数据量过大时fork 带来的开销和暂停时间会被放大。4.4 与主从复制全量同步的联动RDB 不仅在持久化中发挥作用它还是 Redis 主从复制全量同步的载体。仓库 《Redis 主从架构》 描述了这样的流程如果这是 slave node 初次连接到 master node那么会触发一次full resynchronization全量复制。此时 master 会启动一个后台线程开始生成一份RDB 快照文件同时还会将从客户端新收到的所有写命令缓存在内存中。RDB 文件生成完毕后master 会将这个 RDB 发送给 slaveslave 会先写入本地磁盘然后再从本地磁盘加载到内存中。从这一点可以看出 RDB 机制的复用价值一份 RDB 快照既可以用于本机崩溃恢复也可以直接用于搭建从节点时的数据初始化。反过来主从架构对持久化也有强制要求——该文档特别强调如果采用了主从架构那么建议必须开启 master node 的持久化不建议用 slave node 作为 master node 的数据热备因为如果你关掉 master 的持久化master 宕机重启时数据可能是空的一旦经过复制slave node 的数据也丢了。5. AOF 持久化机制详解5.1 工作原理append-only 写入 fsync 落盘AOF 将每一条写命令以append-only模式追加写入日志文件。为了保证命令写入文件缓冲区与真正落盘之间的数据安全AOF 通过fsync操作把缓冲区的数据刷到磁盘。从实现角度看AOF 的 fsync 有三种常见策略appendfsync配置always每次写入都同步刷盘最安全但性能最低、everysec每秒通过后台线程执行一次 fsync最多丢失 1 秒数据性能与安全的平衡点、no由操作系统决定何时刷盘性能最高但数据丢失风险最大。对应到本文档的表述就是一般 AOF 会每隔 1 秒通过一个后台线程执行一次fsync操作最多丢失 1 秒钟的数据。如果实时写入即 always 策略那么 QPS 会大降Redis 性能会大大降低。5.2 rewrite 重写机制压缩日志、最小化恢复成本AOF 日志文件即使过大的时候会出现后台重写rewrite操作它不会影响客户端的读写原因是在 rewrite 时会对其中的指令进行压缩创建出一份恢复数据所需的最小日志新日志基于当时内存中的数据重新构建指令而不是简单地对旧命令日志做 merge这样避免了旧日志中反复写改同一 key 带来的冗余。在创建新日志文件期间老的日志文件还是照常写入。当新的合并后的日志文件 ready 时交换新老日志文件即可整个切换过程对客户端读写透明。这也是仓库 《Redis 主从架构》 中slave node 接收到 rdb 之后如果开启了 AOF那么会立即执行 BGREWRITEAOF重写 AOF所提到的BGREWRITEAOF命令的用途——通过后台重写让 AOF 文件保持精简。5.3 flushall 误删除的紧急恢复AOF 日志文件中的命令可读性较强这个特性非常适合做灾难性的误删除紧急恢复比如某人不小心用flushall命令清空了所有数据只要这个时候后台rewrite还没有发生那么就可以立即拷贝 AOF 文件将最后一条flushall命令删掉然后再把该 AOF 文件放回去就可以通过恢复机制自动恢复所有数据。这个操作的本质是AOF 记录了完整的写入指令序列回放时去掉那条清空指令数据集就完整还原了。这是 RDB 快照做不到的——快照文件本身已经包含了清空后的状态。5.4 优点更好地保护数据不丢失一般 AOF 每隔 1 秒通过后台线程执行一次 fsync最多丢失 1 秒钟的数据。写入性能高、文件不易破损AOF 日志文件以 append-only 模式写入没有任何磁盘寻址的开销写入性能非常高文件不容易破损即使文件尾部破损也很容易修复Redis 会自动截断尾部不完整的记录。重写不影响读写rewrite 期间老日志照常写入新日志 ready 后再交换客户端读写无感知。适合误删除紧急恢复命令可读性强可人工编辑日志如删除 flushall 指令后回放恢复。5.5 缺点与历史 bug文件更大对于同一份数据AOF 日志文件通常比 RDB 数据快照文件更大。写 QPS 略低AOF 开启后支持的写 QPS 会比 RDB 支持的写 QPS 低因为 AOF 一般配置为每秒 fsync 一次日志文件当然每秒一次 fsync 性能依然很高若采用实时写入则 QPS 会大幅下降。机制更复杂、历史上出过 bug以前 AOF 曾发生过 bug——通过 AOF 记录的日志进行数据恢复时没有恢复出一模一样的数据。类似 AOF 这种基于命令日志 merge/回放的方式比 RDB 每次持久化一份完整数据快照的方式更加脆弱容易出 bug。不过 AOF 为了避免 rewrite 过程导致的 bug每次 rewrite 并不是基于旧的指令日志进行 merge而是基于当时内存中的数据进行指令的重新构建这样健壮性会好很多。6. RDB 与 AOF 对比一览对比维度RDBAOF数据完整度周期性快照一般丢 5 分钟以上数据每秒 fsync最多丢 1 秒数据恢复速度直接加载快照恢复快回放命令日志恢复较慢冷备能力多数据文件非常适合冷备文件大冷备恢复不如 RDB 快写入性能主进程 fork 子进程写盘对读写影响极小append-only 无寻址开销但 fsync 使写 QPS 略低文件大小相对较小通常比 RDB 大健壮性每次持久化完整快照简单健壮基于命令日志回放历史上出过恢复不一致的 bug误删恢复无法恢复快照已含删除后状态可删除最后一条 flushall 指令后回放恢复特殊风险大文件 fork 时可能暂停服务数毫秒至数秒实时 fsync 时性能大幅下降7. RDB 与 AOF 该如何选择企业级组合方案7.1 不要仅仅使用 RDB仅用 RDB 会导致丢失很多数据——快照周期内的所有写入都会在宕机时丢失一旦发生缓存雪崩级别的事故损失难以接受。7.2 不要仅仅使用 AOF仅用 AOF 有两个问题冷备恢复慢通过 AOF 做冷备没有 RDB 做冷备的恢复速度快——回放海量命令日志比加载一份完整快照慢得多健壮性风险RDB 每次简单粗暴地生成数据快照更加健壮可以避免 AOF 这种复杂的备份和恢复机制可能存在的 bug。7.3 综合使用AOF 保数据 RDB 做冷备Redis 支持同时开启两种持久化方式企业级实践是综合使用 AOF 和 RDB用 AOF 保证数据不丢失作为数据恢复的第一选择重启时优先用 AOF 重建数据集因为其数据更完整用 RDB 做不同程度的冷备在 AOF 文件全部丢失或损坏不可用的时候还可以使用 RDB 进行快速的数据恢复。7.4 主从架构下必须开启 master 持久化持久化的选型不能脱离部署架构单独决策。仓库 《Redis 主从架构》 给出了两个关键约束必须开启 master node 的持久化如果关掉 master 持久化master 宕机重启时数据为空经过主从复制后 slave 的数据也会被清空master 的各种备份方案也要做即使采用了哨兵高可用机制slave 可自动接管 master也可能出现 sentinel 还没检测到 master failure 而 master 已自动重启的情况此时若 master 无备份数据依然会导致所有 slave 数据被清空。7.5 在高可用架构中的定位在 《Redis 哨兵集群实现高可用》 中哨兵 主从架构不保证数据零丢失——主备切换时异步复制未同步的部分数据、脑裂期间写入旧 master 的数据都可能丢失。持久化尤其是 AOF 的每秒 fsync配合min-slaves-to-write、min-slaves-max-lag等配置可以把数据丢失控制在一个可控范围内。也就是说持久化解决进程重启后数据还在的问题哨兵解决master 挂了有人接管的问题两者叠加才能构成完整的高可用保障而雪崩的事后防线正是Redis 持久化一旦重启自动从磁盘加载数据快速恢复缓存数据。8. 总结一条线串起 Redis 面试考点至此Redis 持久化这条线的完整知识图谱已经清晰为什么持久化Redis 宕机重启数据全丢 → 需要磁盘持久化做灾难恢复 → 不做则可能引发缓存雪崩、打垮 MySQL两种机制RDB周期性全量快照fork 子进程写盘与 AOFappend-only 写命令日志每秒 fsync可回放重建数据集支持 rewrite 压缩怎么选不要只开一个——AOF 保证数据不丢失并作为恢复第一选择RDB 做冷备与快速恢复兜底同时开启时重启以 AOF 为准与周边架构联动主从全量复制依赖 RDB 快照、主从架构必须开启 master 持久化、哨兵高可用只能保证可用性不保证零丢失、雪崩的事后恢复依赖持久化。在 advanced-java 项目中这个话题位于 高并发架构 的缓存板块与 Redis 主从架构、Redis 哨兵集群实现高可用、缓存雪崩与穿透、Redis 集群模式、生产环境部署 等章节共同构成一套完整的Redis 高并发高可用面试知识体系。把持久化这一环吃透你就掌握了 Redis 故障恢复的底层逻辑也能在面试中把数据安全这条线讲得完整而扎实。【免费下载链接】advanced-java Core Interview Questions Answers For Experienced Java(Backend) Developers | 互联网 Java 工程师进阶知识完全扫盲涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识项目地址: https://gitcode.com/gh_mirrors/ad/advanced-java创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考