城里有个叫阿雷的账房先生,记性极好,全城的账目都装在他脑子里。老板查账,他张口就来,速度无人能及。可这本事有个致命隐患:每次他打盹摔下凳子(宕机),或者遇上停电(重启),脑子里那些账目就会乱成一团,甚至全部清零。老板吓坏了,勒令他必须找到“防失忆”的办法。阿雷冥思苦想,掏出两样家当:一台照相机和一册流水账本。照相机每隔一段时间就把全部账目拍成一张全景照片——这就是 Redis 的 RDB 快照;流水账本则把每一笔交易当场记上一行,只许往后添、不许改旧账——这就是 AOF 日志。照片恢复起来一翻就完事,但会漏掉拍照之后新发生的账目;流水账几乎一条不落,可本子越来越厚,恢复时要从头念到尾。后来阿雷干脆把两者合体:先拍一张照片垫底,后面再补新账,既快又不丢。Redis 的持久化,讲的就是这套“防失忆”的学问。读完这篇,你就能给任何业务挑出最合适的记账方式。
学会 RDB 与 AOF 的选型,是掌握 Redis 高可用与数据安全的必修课。对运维与后端工程师而言,这决定了宕机时少丢多少数据、恢复时少花多少时间,直接关系事故级别与 SLA 达标率。
可视化演示
展示RDB快照bgsave fork机制与COW原理、AOF追加日志与自动重写策略、RDB与AOF性能恢复对比。切换模式理解Redis持久化选型核心。
本节配有交互动效(进入视口后自动加载,约 3KB)。
RDB快照与bgsave fork机制 bgsave通过fork子进程异步创建快照,利用COW写时复制保证主进程不受阻塞 RDB文件紧凑体积小,恢复速度快,但可能丢失最后一次快照后的数据 bgsave → fork → COW → dump.rdb RDB适合备份和灾难恢复
持久化为何重要
阿雷最风光的时候,老板夸他“活账本”。可老板不知道,这个“活账本”最怕的就是停电——记忆存在脑子里,电一断,一切归零。Redis 就像是这个“活账本”,它的数据全部存放在内存(RAM)中,内存速度快到百万级读写每秒,但代价是“断电即失”。如果机器崩溃、机房停电、进程被杀,还没来得及落盘的数据就会全部消失,这在生产环境里往往是事故级别的问题。
持久化的本质,就是把“脑子里的账目”定期誊写到“纸面上”——也就是磁盘。这样无论机器怎么重启,Redis 都能把纸面上的账目重新念进脑子里,恢复营业。Redis 为此提供了两种“防失忆”工具:RDB(Redis DataBase)快照,相当于每隔一段时间给全部账目拍一张全景照片;AOF(Append Only File)日志,相当于把每一笔交易当场记进一册只许追加的流水账本。
这两种工具的取舍,归根结底是在衡量“丢了多少钱”和“多久能恢复营业”这两个指标。任何持久化方案都无法同时做到绝对不丢数据和瞬间恢复,我们需要的是一把尺子来衡量优劣。
所以全文的主角不是两个神秘的算法,而是两种“记账习惯”:RDB 习惯隔一阵子拍一次照,AOF 习惯每笔都落笔。接下来我们分别看看,照片是怎么拍的,流水账是怎么记的。
- 丢失量 L宕机时未能写入磁盘的数据量,单位与写入速率一致,可以是“条数”或“字节数”。
- 写入速率 R业务每秒产生的写命令数量,代表账本上新发生的变动速度,业务越繁忙这个值越大。
- 落盘间隔 T两次真正把内存数据写进磁盘之间的时间差。间隔越大,空窗期越长,新账目就越危险。
- 乘积含义把“每秒新账”乘以“空窗秒数”,得到的就是这段空窗期内累积的、没有被保护起来的数据总量。理解它,就握住了持久化选型的总钥匙。
RDB快照原理
阿雷的照相机有个独特设计:拍照时并不需要他停下手中的活。他请来一位“分身”(子进程),让分身端着相机站在一边,对着账本咔嚓一下,而他自己继续记账、收钱、拨算盘。这位分身拍到的,必须是“咔嚓那一瞬间”账本的样子——哪怕主人在拍照的同一秒又改了几页账,也不能影响照片内容。
这个“分身拍照”的机制在 Redis 里叫 bgsave(后台保存)。Redis 调用操作系统的 fork 系统调用,生成一个子进程;子进程继承父进程此刻的全部内存数据,把数据序列化后写入 RDB 文件;父进程则继续服务所有读写请求,全程不阻塞业务。生成的 RDB 文件是一个紧凑的二进制文件,恢复时直接加载进内存即可。
这里的关键技术叫“写时复制”(Copy On Write,COW)。fork 之后,父子进程其实共享同一份物理内存页,并没有立刻复制整个内存——那会既慢又吃内存。只有当父进程要修改某个内存页时,操作系统才会先把这一页复制一份给子进程用,父进程改自己的那份。这样一来,子进程眼里永远是 fork 时刻的数据视图,而父进程的写操作也几乎不受影响。触发 bgsave 的时机包括:满足 save 配置的变更条件、手动执行 BGSAVE、正常关闭 Redis、以及主从复制时的全量同步。
照片方案的优点很突出:文件小、加载快,恢复时“翻开照片一对照”就完成了,几 GB 的数据也只需秒级到分钟级。缺点也同样藏在照片本身——它只记录按快门那一刻的账目,一旦在两次拍照之间发生宕机,这期间的每一笔新账都找不回来。换句话说,RDB 的丢失窗口不是一个点,而是整个快照间隔。
save m n 的语义:在 m 秒内如果发生了至少 n 次写操作,就触发一次后台快照。两个条件必须同时满足,避免空拍浪费资源。- 时间窗口 Δt自上次快照以来经过的时间,单位是秒,对应配置里的 m。例如
save 900 1中 m=900。 - 变更次数 Δc窗口内累计发生的写命令条数,对应配置里的 n。例如 15 分钟内至少有 1 次写。
- 双条件触发
且表示两个条件同时成立才拍照。如果 15 分钟内一单生意都没有(0 次写),就不必白拍一张照片。
AOF日志原理
阿雷后来觉得光拍照片不踏实,于是又添了一册流水账本。规矩很简单:每一笔交易发生,他立刻在本子上记一行,比如“10 点 03 分,张三存入 100 两”。这册账本有个铁律——只许往末尾追加新行,绝不许回头改动任何旧行。这样哪怕摔了脑子,只要把流水账从第一行念到最后一行的“重放”一遍,账目就原封不动地回来了。
这就是 AOF(Append Only File)的核心思想。Redis 把每一条写命令(SET、LPUSH、DEL 等)按照自己的通信协议格式,追加写入到一个日志文件的末尾。追加写入是顺序 IO,磁盘对顺序写的速度非常友好,所以单条命令的日志开销比随机写小得多。恢复时,Redis 启动后从头到尾读取这个文件,把每行命令重新执行一遍,数据就在内存中重建了。
AOF 有一个精妙的细节:命令先写入内存中的缓冲区,并不会立刻落到磁盘。真正决定“什么时候掉到磁盘上”的是 appendfsync 配置,它有三个档位:always 表示每执行一条写命令就同步一次磁盘,最安全但最慢;everysec 表示每秒把缓冲区内容同步一次,这是默认值,性能与安全兼顾;no 表示完全交给操作系统决定何时刷盘,性能最好但丢失窗口不可控。此外,日志无限追加会越来越臃肿,所以 Redis 提供 bgrewriteaof 重写机制:把当前内存数据重新整理成最小命令集,生成一份精简的新日志替换旧日志。
流水账方案几乎滴水不漏,代价是“念账”太慢:恢复时要把全部命令从第一条重放到最后一条,日志越大恢复越久。而且文本文件的体积通常是二进制快照的数倍。所以 AOF 需要定期“誊写乱账”——也就是重写机制——来控制体积。这就引出了下一个问题:照片和流水账,到底哪个更划算?
everysec 策略把落盘间隔压缩到了 1 秒以内,所以最多丢 1 秒的写入。这是 RDB 望尘莫及的精度。- fsync 间隔 T
everysec意味着每秒强制刷一次盘,因此空窗期不超过 1 秒。 - 写入速率 R业务每秒产生的写命令数量,与 RDB 公式中的含义完全相同。
- 上限估算把速率和 1 秒相乘,就是最坏情况下的丢失量。例如每秒写入 1 万条命令,最多丢 1 万条,而不是几分钟的数据。
性能与数据安全对比
老板给阿雷出了道考题:假设现在账房起火,你只能带一样备份逃命,带照片还是带流水账?阿雷犯了难。带照片,逃出去之后一翻照片就能立刻开张,但最近几天的新账全没了;带流水账,账目分毫不差,可要重新念几百页的旧账,念完才能重新营业。横竖都是损失,只是损失的东西不同。
这正是 RDB 与 AOF 的本质差异。恢复速度上,RDB 直接加载二进制快照,一步到位;AOF 需要逐条重放命令,恢复时间是 RDB 的数倍到数十倍。数据安全上,RDB 的丢失窗口等于整个快照间隔(分钟级甚至小时级),而 AOF 在 everysec 下最多丢 1 秒。写入性能上,RDB 平时几乎零开销,只有拍照瞬间有一次集中写盘;AOF 每一条命令都要追加写日志,always 模式下更是每条都 fsync,延迟和 IO 压力显著上升。文件体积上,RDB 是压缩过的二进制格式,紧凑;AOF 是文本协议,通常要膨胀数倍。
既然两边各有短板,阿雷灵机一动:能不能把照片和流水账合在一本里用?这正是下一节要讲的混合持久化——先用照片垫底,再在照片后面补记新账,恢复时先翻照片秒级还原,再快速补念几行增量日志,两头的好处都占到。
- RDB 丢失窗口等于两次快照之间的时间跨度,比如配置
save 900 1时窗口可达 15 分钟。 - AOF 丢失窗口在默认每秒刷盘策略下不超过 1 秒,这是两者最悬殊的差距。
- 恢复时间对比远小于符号表示 RDB 与 AOF 的恢复耗时不在一个量级,差几十倍很正常。
混合持久化解析
阿雷最终想出的妙招是:每天清晨开门前,先给账本拍一张全家福,把照片贴在流水账本的第一页;之后的一整天,新交易仍然逐行记在照片后面的空白页上。万一中途出事,恢复流程变成两步:先看照片,瞬间还原到清晨的状态;再念照片后面那几页新账,补上今天的变动。既不用从头念几百页旧账,又一条账都不丢。
Redis 4.0 起提供了这个“合体方案”,开关是配置项 aof-use-rdb-preamble,默认开启。它的工作机制是:每当执行 AOF 重写(bgrewriteaof)时,Redis 不再生成纯文本日志,而是先在文件头部写一段当前数据的 RDB 快照,再在后面追加重写之后的新命令日志。这样生成的 AOF 文件,格式上仍然是一个 .aof 文件,内部却包含“RDB 前缀 + 增量 AOF 后缀”两部分。
恢复时,Redis 会先识别文件头部的 RDB 段,直接加载这些二进制数据(速度接近纯 RDB),然后从 RDB 段的末尾继续重放增量日志。因为增量日志只包含“拍照之后”的命令,量通常很小,重放也就一瞬间。对比来看,混合文件比纯 AOF 小得多——纯 AOF 要记录全部历史命令,而混合文件只需一张快照加少量增量。这也让混合模式成为 4.0 之后生产环境的默认推荐。
混合持久化就像“照片打底 + 流水补账”,在恢复速度与数据安全之间找到了黄金分割点。不过要让它跑得稳,还得学会配置参数。下一节我们看看,阿雷是怎么给账房立规矩的。
- 打底体积 V_RDBRDB 段是一份压缩的二进制快照,体量等于任一时刻全部数据压缩后的大小。
- 增量体积 V_增量只记录重写之后发生的新命令,通常只是快照体积的极小一部分。
- 远小于纯 AOF纯 AOF 记录的是全部历史命令,可能积累几天甚至几周的操作,自然膨胀数倍。
配置参数实践
光有工具还不够,阿雷给账房定下了三条规定:第一,账目变动达到什么规模才拍照;第二,流水账多久往抽屉里锁一次(刷盘);第三,流水账厚到什么程度必须重新誊写一遍。这三条规定在 Redis 里就是一组配置参数,把它们设对,持久化就成功了一大半。
第一条规矩对应 RDB 的触发策略:save 900 1、save 300 10、save 60 10000 可以同时配置多条,满足任意一条就会触发 bgsave。第二条规矩对应 AOF 的刷盘策略:appendfsync everysec 是默认推荐,always 给最较真的场景,no 则适合对丢失不敏感的大批量写入场景。第三条规矩对应 AOF 自动重写的两个阈值:auto-aof-rewrite-percentage 100 表示当前日志比基础日志大一倍时触发重写;auto-aof-rewrite-min-size 64mb 则防止日志还很小的时候就频繁重写。
一个典型的配置文件片段长这样:先开启 appendonly yes,再设置 appendfsync everysec,用 save 定义快照节奏,最后配上自动重写阈值。理解这些参数背后的公式比死记默认值更重要——重写触发条件本质上是一个比值判断。
配置不是玄学,而是把前面所有原理翻译成数字。先想清楚业务能接受多少丢失、希望多快恢复,再回头设置这些参数,才不会被一堆默认值牵着鼻子走。最后一节,我们把所有的公式和工具放回真实业务场景里,给出最终的选型答案。
- 当前大小 S_当前此刻 AOF 文件的体积,随着新命令追加而不断增长。
- 基础大小 S_基础上次重写完成后 AOF 文件的体积,是衡量的基准线。
- 百分比阈值 p默认 100,表示当前体积达到基准的两倍就触发重写;配合最小体积 64MB,防止过早重写。
选型场景与建议
面馆和银行是两种截然不同的“账房”。面馆门口的排队队伍(缓存)丢了,大不了让客人重新排队;可银行的金库流水(交易记录)要是少了一笔,那是要出大事的。阿雷给两类老板的建议完全不同:面馆老板用照片方案就够——数据丢了可以重建,重要的是翻照片快,队伍能立刻排起来;银行老板必须用流水账——哪怕恢复慢一点,账目也必须分毫不差。
在技术语境里,这个判断标准叫做“数据可重建性”。排行榜、热点新闻、推荐结果这类缓存数据,底层有数据库或离线任务兜底,丢了随时能重建,优先选 RDB,享受快速的恢复时间。购物车、订单状态、支付凭证、用户会话这类强一致数据,一旦丢失就是真金白银的损失,必须选 AOF,甚至 appendfsync always。而绝大多数生产系统里两类数据并存,这时混合持久化就是最稳的均衡解。
生产环境的最佳实践可以浓缩成几条铁律:开混合持久化(RDB 打底 + AOF 增量)作为默认;定期把 RDB 文件备份到异地,防止磁盘故障把快照和日志一起带走;监控快照触发频率与 AOF 重写是否正常,避免日志无限膨胀;大实例执行 bgsave 时留意 fork 的毫秒级停顿,错峰执行手动备份;最后,持久化永远替代不了主从复制,两者搭配才叫高可用。
所以,“RDB 和 AOF 怎么选”没有标准答案,只有针对业务的答案。可重建的数据用照片,分毫必争的数据用流水账,拿不准就上混合方案——这既是阿雷的生意经,也是 Redis 持久化最实用的决策树。
- 恢复权重 α业务对停机时间的敏感度。每多停一秒就少赚一秒的钱时,α 就很大,比如在线支付网关。
- 丢失权重 β业务对数据损失的敏感度。少一笔订单都无法接受时,β 就很大,比如金融核心交易。
- 代价最小化把所有候选方案(纯 RDB / 纯 AOF / 混合)的代价分别算出,取最小值对应的方案。
AI 应用场景
电商订单状态与购物车容灾
阶段:数据基础设施容灾设计
解决的问题:传统方案只开 RDB 时,大促峰值一旦宕机,会丢失几分钟内的购物车与订单状态,用户侧表现为“购物车空了、订单状态回退”。改用 AOF everysec 加混合持久化后,重启最多丢 1 秒的数据,配合主从切换,用户几乎无感知。
具体案例:某电商平台大促期间,用户加购与下单状态全部存储在 Redis。一次缓存节点硬件故障,运维团队依靠混合持久化的快速恢复能力,在 1 分钟内完成故障转移与数据恢复,订单数据零丢失,客服投诉量当天为零。
热点排行榜与推荐缓存重建
阶段:模型服务缓存管理
解决的问题:排行榜和推荐结果本质是可重建数据,底层由离线任务重新计算,不需要逐条操作日志。用 RDB 恢复最快,发布或扩容时能显著缩短实例空窗期,降低对在线服务的影响。
具体案例:某内容平台的推荐服务把 Top N 结果写入 Redis 缓存,缓存重建由每小时的离线任务完成。采用 RDB 后,一次版本发布重启,3 秒内加载完 2GB 快照文件,服务立刻恢复,推荐接口可用性保持在 99.99%。
在线推理特征缓存与模型版本配置
阶段:在线推理数据缓存
解决的问题:AI 特征服务需要重启后秒级恢复缓存,同时模型版本配置这类数据又要求强一致,不能丢更新。单一方案无法两全,混合持久化的“RDB 打底 + 增量补全”恰好同时满足两个硬性要求。
具体案例:某风控系统的特征缓存达 8GB,模型每周发布新版本。开启混合持久化后,一次例行重启 2 秒完成 RDB 前缀加载,随后重放最近 1 秒的增量日志,特征完整、模型命中率不降,发布流程从 10 分钟缩短到 1 分钟。
Python 演示
# -*- coding: utf-8 -*-# MiniRedis: 用"照片"和"流水账"演示 RDB 与 AOF 的恢复差异import copy class MiniRedis: def __init__(self): self.data = {} self.snapshot = None self.aof_log = [] self.snapshot_log_len = 0 def set(self, key, val): self.data[key] = val self.aof_log.append('SET %s %s' % (key, val)) def rdb_save(self): # 拍快照: 把当前数据完整拷贝一份, 并记下日志水位 self.snapshot = copy.deepcopy(self.data) self.snapshot_log_len = len(self.aof_log) def recover(self, use_rdb, use_aof): # 选择用哪本"备份"来恢复: 照片(rdb) 和/或 流水账(aof) if use_rdb: self.data = copy.deepcopy(self.snapshot) start = self.snapshot_log_len else: self.data = {} start = 0 if use_aof: for line in self.aof_log[start:]: _, key, val = line.split() self.data[key] = val def main(): db = MiniRedis() db.set('balance', '100') db.rdb_save() # 打烊前拍了一张全家福快照 db.set('balance', '80') db.set('vip', 'alice') # 快照之后又来了两笔新账 rdb_only = copy.deepcopy(db) rdb_only.recover(use_rdb=True, use_aof=False) aof_only = copy.deepcopy(db) aof_only.recover(use_rdb=False, use_aof=True) hybrid = copy.deepcopy(db) hybrid.recover(use_rdb=True, use_aof=True) print('RDB photo :', sorted(rdb_only.data.items())) print('AOF log :', sorted(aof_only.data.items())) print('hybrid :', sorted(hybrid.data.items())) print('aof lines :', len(db.aof_log)) if __name__ == '__main__': main()
self.snapshot = copy.deepcopy(self.data)拍快照的本质就是完整拷贝一份当前数据,对应 RDB 子进程生成二进制文件。self.snapshot_log_len = len(self.aof_log)记下“拍照时流水账写到第几行”,相当于 RDB 快照的时刻水位,混合恢复时从这里继续。if use_rdb:选择用照片恢复:直接把快照拷回来,速度快但只还原到拍照那一刻。start = self.snapshot_log_len混合恢复的关键:只重放拍照之后的新日志,不用从头念整本账。for line in self.aof_log[start:]:重放流水账:从水位之后逐条执行命令,模拟 AOF 的恢复过程。_, key, val = line.split()解析日志行,把SET key val还原成内存中的键值对。
常见误区
误区我一直以为 bgsave 就是 fork 一个子进程,然后把整个内存数据复制一份给子进程写文件,所以保存期间内存占用会翻倍,8GB 的实例要 16GB 内存才敢开 RDB。
正解fork 之后父子进程共享同一份物理内存页,并不复制数据。只有父进程修改了某个内存页,操作系统才把那一页复制一份给子进程,这就是写时复制(COW)。10GB 实例做 bgsave,内存可能只增加几十 MB 到几百 MB,远不是翻倍。真正要注意的是 fork 本身需要复制页表,大实例会有毫秒级短暂停顿。
为何常见:把“快照”联想成“拍照复制一份”,自然认为内存要翻倍,忽略了操作系统层面的共享页与写时复制机制。
误区AOF 不是叫“追加文件”吗?那肯定每条命令一来就写到磁盘文件里了,所以 AOF 模式应该天然最安全、最慢。
正解写命令先进入 Redis 的内存缓冲区,真正落到磁盘的时机由 appendfsync 决定。everysec 模式下缓冲区最多攒 1 秒才刷一次盘;always 才是一条命令一次 fsync。而且即使进程把数据写给了操作系统,断电时操作系统页缓存里的数据同样可能丢失,所以没有绝对零丢失。
为何常见:看到“追加写入”就以为和磁盘同步是一回事,混淆了“写入系统缓冲区”和“刷到磁盘”两个阶段。
误区AOF 是文本日志,把每条命令都记下来,RDB 是压缩二进制,那 AOF 肯定永远比 RDB 大好几倍,选 RDB 一定更省磁盘。
正解没重写过的 AOF 确实容易膨胀数倍,但 AOF 有自动重写机制,重写后会把全部历史命令压缩成“当前数据的最小命令集”,体积可以变得很小。更优的是混合持久化,RDB 打底加增量日志,通常比纯 AOF 小、比纯 RDB 也大不了多少。比大小之前,先确认日志是否重写过。
为何常见:拿“运行了很久没重写的 AOF”和“刚生成的 RDB”做对比,忽视了重写机制这个关键变量。
误区我把 RDB 和 AOF 都打开了,那重启时 Redis 应该先加载 RDB 快照,再读 AOF 日志补充,两边数据合并,恢复得最全。
正解默认配置下,只要 AOF 开启,Redis 重启时只加载 AOF 文件,不会再去读 RDB。在 4.0 之后,混合持久化的 AOF 文件本身就包含 RDB 前缀,所以加载 AOF 既快又全,并不需要再叠加一个独立 RDB 文件。
为何常见:把“两种持久化可以同时开启”理解成“恢复时两个文件都要用”,忽略了 Redis 明确的优先级规则。
面试题
Q1. 关于 Redis 的 RDB 持久化,下列说法正确的是?
- A.由主进程直接遍历内存生成快照文件
- B.通过 fork 子进程生成快照文件← 正确答案
- C.快照文件必须使用 AOF 格式保存
- D.RDB 持久化完全不会阻塞任何服务
答案:B。RDB 通过 fork 出一个子进程,由子进程负责把内存数据写成快照文件,父进程继续服务,这就是 bgsave。A 错在主进程不直接做;C 错在 RDB 和 AOF 是两种独立格式;D 错在 fork 瞬间父进程仍有毫秒级停顿。好比照片是请“分身”拍的,主人不用停下手里的活,但请分身本身也要花一瞬。
Q2. Redis AOF 采用默认的 appendfsync everysec 策略时,最多可能丢失多久的数据?
- A.最多丢失约 1 秒内的数据← 正确答案
- B.最多丢失约 10 秒内的数据
- C.最多丢失约 1 分钟内的数据
- D.任何情况下都不丢失数据
答案:A。everysec 表示缓冲区每秒刷一次磁盘,因此宕机时最多丢最后一次刷盘后的数据,即约 1 秒。这相当于流水账本每秒钟往抽屉里锁一次,最多漏掉锁上之前那一瞬间还没誊写的一两行。always 才接近“不丢”,但性能开销大。
Q3. 关于 Redis 的 fork 与写时复制(COW)机制,说法正确的是?
- A.fork 后父子共享内存页,修改时才复制该页← 正确答案
- B.fork 会立刻复制全部内存导致内存翻倍
- C.fork 过程中 Redis 完全停止直到完成
- D.子进程负责接收新的写请求
答案:A。fork 后父子进程共享物理内存页,父进程首次修改某一页时才复制该页给子进程,这就是“写时复制”,所以内存不会翻倍,父进程也不停止服务。拍照时主人继续记账,只有被改动的账页才复印一份给拿相机的分身。子进程不接收请求,只负责写快照。
Q4. 下列哪些情况会触发 Redis 生成 RDB 快照?
- A.满足 save 配置的变更次数和时间条件← 正确答案
- B.手动执行 BGSAVE 命令← 正确答案
- C.主从复制时全量同步需要生成快照← 正确答案
- D.手动执行 BGREWRITEAOF 命令
答案:ABC。满足 save m n 条件、手动 BGSAVE、主从全量同步都会触发 RDB 快照;正常关闭时若配置允许也会保存。而 BGREWRITEAOF 触发的是 AOF 日志重写,与 RDB 快照无关。好比“拍照”和“誊写流水账”是两件不同的事,别把工具拿混了。
Q5. Redis 4.0 混合持久化开启后,AOF 文件内部的结构是什么样的?
- A.开头一段 RDB 快照再加增量命令日志← 正确答案
- B.从头到尾都是纯文本的写命令日志
- C.由 RDB 与 AOF 两个独立文件组成
- D.快照数据只保存在内存中不落盘
答案:A。混合持久化下,执行 AOF 重写时会在文件头部写入当前数据的 RDB 快照,后面续接重写之后的增量命令日志。恢复时先直接加载 RDB 段,再重放少量增量日志。就像照片贴在流水账本第一页,后面才是新账,而不是分成两个本子。
Q6. AOF 自动重写(bgrewriteaof) 的作用包括哪些?
- A.压缩日志体积去除中间重复命令← 正确答案
- B.加快重启时数据恢复的速度← 正确答案
- C.减少日志对磁盘空间的占用← 正确答案
- D.提高单条写命令的执行速度
答案:ABC。重写把整本历史流水账精简成“当前状态最小命令集”,体积变小、磁盘占用减少,恢复时重放的命令条数也变少,速度自然提升。但重写并不改变单条命令的执行路径,写命令的性能不受它影响。好比把记了一年的旧账誊成一张余额表,省纸又省念。
Q7. 与纯 RDB 相比,纯 AOF 持久化的主要劣势是什么?
- A.恢复速度慢且文件体积通常更大← 正确答案
- B.数据丢失量比 RDB 更大
- C.完全无法保证任何数据安全
- D.与主从复制机制不兼容
答案:A。AOF 恢复要逐条重放命令,速度比直接加载二进制快照慢得多;文本格式的体积通常也更大。但 AOF 的丢失窗口远小于 RDB,数据更安全,也完全兼容主从复制。流水账全但不耐念,照片好翻但会漏账。
Q8. 生产环境中,Redis 官方推荐的持久化方案是哪种?
- A.开启混合持久化 RDB+AOF← 正确答案
- B.只开启 RDB 快照持久化
- C.只开启 AOF 日志持久化
- D.关闭持久化仅依赖主从
答案:A。4.0 之后官方推荐 aof-use-rdb-preamble 的混合持久化:RDB 打底保证恢复快,AOF 增量保证丢得少,兼顾两者优点。只开一种都有明显短板,完全关闭持久化则把数据安全全部押在内存上,风险极高。
Q9. 下列关于 Redis 重启数据恢复的说法,正确的有哪些?
- A.开启 AOF 时默认优先用 AOF 恢复← 正确答案
- B.RDB 恢复速度通常快于 AOF 方式← 正确答案
- C.混合 AOF 文件内含 RDB 前缀← 正确答案
- D.混合模式需要加载两个独立文件
答案:ABC。默认配置下只要 AOF 开启,重启就只加载 AOF;混合持久化的 “AOF“ 文件本身带 RDB 前缀,所以加载它既快又全,并不需要额外加载第二个独立文件。D 错在”两个独立文件”,实际是一个文件里分两段。
Q10. 一个 10GB 内存的 Redis 实例执行 BGSAVE,关于 fork 阶段对父进程的影响,说法正确的是?
- A.阻塞时长与内存和 CPU 相关,通常毫秒级← 正确答案
- B.阻塞时长与磁盘写入速度成正比
- C.子进程生成期间父进程完全不处理请求
- D.子进程生成期间父进程等待其全部完成
答案:A。fork 的耗时主要取决于内存大小(页表复制量)和 CPU 速度,通常在毫秒到几十毫秒级,与磁盘写入速度无关,因为写文件由子进程异步完成。父进程只是瞬间停顿,随即继续服务。请分身只需要一眨眼,分身拍照的过程不耽误主人干活。