Redis 持久化(RDB/AOF)与内存淘汰

共 20 题
📑 题目列表 20 题
#
★★★

1. RDB 与 AOF 的混合模式(Redis 4.0+)?

请说明 Redis 4.0+ 的 RDB 与 AOF 混合持久化模式?

  • 混合持久化的原理
  • 快速重启与低丢失
  • 配置与使用

Redis 4.0 引入混合持久化:AOF 重写时,先以 RDB 格式写入当前数据快照,再在 RDB 之后追加重写期间的增量命令(AOF 格式)。重启加载时,先快速加载 RDB 快照(比纯 AOF 快),再重放增量命令,兼顾快速重启与低丢失。混合模式通过 aof-use-rdb-preamble yes 开启。相比纯 RDB(丢失重写后增量)与纯 AOF(加载慢),混合模式内存占用接近 RDB、加载快、丢失窗口小。

混合模式把 RDB 的"加载快"与 AOF 的"丢失少"结合:RDB 打底 + 增量 AOF 收尾,是快速重启与低丢失的折中。

#
★★★

2. RDB(Redis Database)持久化,快照机制?

请说明 Redis 的 RDB(Redis Database)持久化快照机制?

  • RDB 快照的触发方式
  • fork + COW 生成快照
  • RDB 的优缺点

RDB 是 Redis 的二进制快照持久化,将内存数据以紧凑二进制格式写入 .rdb 文件。触发方式:手动 SAVE/BGSAVE、满足 save 条件(如 save 900 1 表示 900 秒内至少 1 次写则触发)、重启时。BGSAVE 通过 fork 子进程 + COW 生成快照,不阻塞主线程。优点:文件紧凑、加载快、适合备份与主从初始同步;缺点:快照间隔内可能丢失数据(若未开 AOF)、fork 大内存实例有开销。

RDB 是"周期性快照",以丢失窗口换取加载速度与文件紧凑。适合对丢失容忍度不高、重视备份与加载速度的场景。

#
★★★

3. Streams 与 Pub/Sub 的差异,持久化 vs 实时广播?

请说明 Streams 与 Pub/Sub 在持久化与实时广播上的差异?

  • Streams 的持久化与消费确认
  • Pub/Sub 的实时广播、不持久化
  • 差异与适用场景

Pub/Sub 是实时广播模型:发布者把消息发给所有订阅者,消息不持久化,订阅者不在线则消息丢失,无消费确认与重投。Streams 是持久化日志模型:消息存于内存(可持久化到 AOF/RDB),支持消费组、ACK 确认、PEL 重投,订阅者离线后可补读。差异本质:Pub/Sub 是"实时广播、即发即弃",Streams 是"持久化、可靠投递"。适用场景:Pub/Sub 适合实时通知、事件广播(如缓存失效);Streams 适合需要可靠消费、可重投的消息队列场景。

持久化与可靠投递是两者的核心差异。Pub/Sub 简单实时但不可靠,Streams 可靠但更重。选择取决于是否需要"离线补读 + 确认重投"。

#
★★★

4. AOF 的三种 fsync 策略(always/everysec/no)对数据安全与吞吐的影响,如何按业务选择?

请说明 AOF 的三种 fsync 策略(always/everysec/no)对数据安全与吞吐的影响,以及如何按业务选择?

  • 三种策略的含义
  • 数据安全与吞吐的权衡
  • 选型建议

AOF 三种 appendfsync 策略:always:每次写命令都 fsync 到磁盘,最安全但性能最低(每次写都要 fsync);everysec:每秒 fsync 一次,最多丢失 1 秒数据,性能与安全兼顾(默认);no:由操作系统决定 fsync 时机,性能最高但可能丢失较多数据(崩溃时)。选择:数据安全要求极高(如资金)用 always;一般业务用 everysec(性能与安全平衡);可容忍较多丢失、追求吞吐用 no。生产常用 everysec。

fsync 策略是"性能与安全"的滑动条:always 丢最少但最慢,everysec 折中,no 最快但丢最多。业务数据重要性决定 fsync 频率。

#
★★★

5. Redis 持久化对延迟的影响(fork 与 COW 页复制、AOF fsync)与优化(no-appendfsync-on-rewrite)

请说明 Redis 持久化对延迟的影响(fork 与 COW 页复制、AOF fsync),以及优化手段(no-appendfsync-on-rewrite)?

  • fork 与 COW 对延迟的影响
  • AOF fsync 对延迟的影响
  • no-appendfsync-on-rewrite 优化

持久化对延迟的影响:fork 生成 RDB/AOF 子进程时复制页表,大内存实例 fork 耗时会导致主线程阻塞;COW 下主线程写操作触发页复制,增加内存与 CPU;AOF 的 fsync 在磁盘慢时可能阻塞主线程(everysec 下 fsync 未完成会阻塞写)。优化:no-appendfsync-on-rewrite yes 在 AOF 重写期间暂时不 fsync(为避免重写与 fsync 冲突阻塞),减少延迟抖动;其他优化包括控制实例内存、错峰触发持久化、用 faster 磁盘。

持久化的延迟开销来自 fork 阻塞、COW 页复制与 fsync 阻塞。no-appendfsync-on-rewrite 通过重写期间延迟 fsync 消除阻塞,但可能增加少量丢失风险,需权衡。

#
★★★

6. 内存淘汰策略如何选型,volatile-lru、allkeys-lru、volatile-ttl 各适用什么场景?为什么纯缓存场景常用 allkeys-lru?

请说明内存淘汰策略的选型,volatile-lru、allkeys-lru、volatile-ttl 各适用什么场景,以及为什么纯缓存场景常用 allkeys-lru?

  • 各淘汰策略的适用场景
  • allkeys-lru 在纯缓存场景的优势
  • 选型依据

volatile-lru:只淘汰设置了过期时间的 key 中最近最少使用的,适合混合数据(有持久化/需保留的数据不设 TTL,可淘汰的数据设 TTL)。allkeys-lru:从所有 key 中淘汰 LRU,适合纯缓存场景,充分利用内存、可淘汰任意 key。volatile-ttl:淘汰剩余 TTL 最短的 key,适合优先淘汰即将过期的数据。纯缓存场景常用 allkeys-lru,因为缓存数据都是可丢弃的,allkeys 让所有 key 都参与淘汰,避免"无 TTL 的 key 占满内存"导致无法淘汰,最大化缓存利用率。

淘汰策略的核心是"哪些 key 可被丢弃"。纯缓存场景所有数据都可弃,allkeys-lru 让可用内存最大化、无需为每个 key 设 TTL;混合场景用 volatile-* 保护无 TTL 的核心数据。

#
★★★

7. 主从全量同步为什么基于 RDB?主库 fork 生成 RDB 对内存与延迟的影响,与持久化配置(save 策略)如何协同?

请说明主从全量同步为什么基于 RDB,以及主库 fork 生成 RDB 对内存与延迟的影响,与持久化配置(save 策略)如何协同?

  • 全量同步用 RDB 的原因
  • fork 生成 RDB 的影响
  • 与 save 策略协同

主从全量同步基于 RDB,因为 RDB 是紧凑的二进制快照,能快速传输、加载,且一次生成可覆盖整个数据集,适合初始同步。主库 fork 生成 RDB 的影响:fork 复制页表占用内存、COW 增加内存与 CPU 开销、大内存实例 fork 可能短暂阻塞主线程。与持久化配置协同:主从同步触发 RDB 生成与 bgsave 类似,若同时命中 save 策略会并发,需注意实例内存余量;可通过 repl-diskless-sync 让主库流式发送 RDB 减少磁盘 IO,并合理规划 save 触发与同步时机。

RDB 是全量同步的高效载体,但 fork 生成有内存与延迟代价。协同的关键是控制实例内存、规划同步与 bgsave 时机,避免 fork 叠加放大。

#
★★

8. AOF 重写(Rewrite)的原理与触发,bgrewriteaof?

请说明 AOF 重写(Rewrite)的原理与触发方式,包括 bgrewriteaof?

  • AOF 重写的原理(合并命令)
  • 触发方式(自动 + 手动)
  • bgrewriteaof 命令

AOF 会不断追加写命令,文件越来越大。AOF 重写是基于当前内存数据重新生成最小 AOF 文件(用命令表示当前数据集),合并重复写、去除被覆盖的旧命令,从而缩小文件。触发方式:手动 BGREWRITEAOF 命令;自动按 auto-aof-rewrite-percentage(文件增长百分比)与 auto-aof-rewrite-min-size(最小尺寸)触发。重写通过 fork 子进程 + COW 完成,期间主线程继续处理命令,重写期间的新增命令被记录并在重写后追加。

AOF 重写解决"文件无限膨胀"问题,用当前数据集重新生成最小命令集,且在后台(fork)执行不阻塞主线程。

#
★★

9. 持久化的配置,save、appendfsync、auto-aof-rewrite-percentage?

请说明 Redis 持久化的关键配置,即 save、appendfsync、auto-aof-rewrite-percentage?

  • save 策略(RDB 触发条件)
  • appendfsync(AOF 刷盘策略)
  • auto-aof-rewrite-percentage(AOF 重写触发)

save:RDB 持久化触发条件,如 save 900 1 表示 900 秒内至少 1 次写则 bgsave,可配置多个条件;save "" 关闭 RDB。appendfsync:AOF 刷盘策略,always/everysec/no 决定 fsync 频率,影响数据安全与吞吐。auto-aof-rewrite-percentage:AOF 重写触发,当文件大小相对上次重写增长了该百分比(且达到 auto-aof-rewrite-min-size)时自动触发重写,防止 AOF 无限膨胀。这些配置协同决定持久化的安全性与性能。

三个配置分别控制 RDB 触发、AOF 刷盘、AOF 重写,是持久化的核心参数。按数据安全与性能需求组合配置。

#
★★

10. Redis 内存碎片与内存淘汰(LRU/LFU/随机)的工程取舍?

请说明 Redis 内存碎片与内存淘汰(LRU/LFU/随机)的工程取舍?

  • 内存碎片的成因与治理
  • 各种淘汰策略的取舍
  • 工程权衡

内存碎片率(mem_fragmentation_ratio)反映物理内存与逻辑内存的偏差,过高源于频繁增删 key、内存分配器粒度。治理:activedefrag 后台整理、合理 maxmemory、避免频繁分配。内存淘汰策略的取舍:LRU 淘汰最近最少使用,适合时间维度冷热;LFU 淘汰访问频率最低,更能反映长期热度;随机淘汰实现简单但可能淘汰热点。工程取舍:缓存场景用 LRU/LFU 优化命中率,LFU 对长期热点更友好,random 简单但劣质;碎片治理与淘汰都影响内存效率,需结合业务访问模式与内存压力选择。

碎片与淘汰都关乎"内存效率":碎片治理回收浪费的内存,淘汰策略决定内存满时保留哪些数据。选择取决于业务访问模式与数据可弃性。

#
★★

11. Redis 混合持久化的原理,RDB 快照 + AOF 增量如何做到快速重启与低丢失?

请说明 Redis 混合持久化的原理,即 RDB 快照 + AOF 增量如何做到快速重启与低丢失?

  • 混合持久化结构
  • RDB 打底 + AOF 增量
  • 快速重启与低丢失

混合持久化在 AOF 重写时,先以 RDB 二进制格式写入当前数据快照,再在之后追加重写期间的增量命令(AOF 格式)。重启加载时,先加载 RDB 快照(快速恢复大部分数据),再重放增量 AOF 命令(补齐重写后的变化),从而在快速重启的同时丢失窗口小(仅丢失重写后到崩溃前的增量)。相比纯 RDB(丢弃重写后增量)与纯 AOF(全量重放慢),混合模式兼顾加载速度与低丢失。

混合模式把"RDB 的加载快"与"AOF 的增量保真"结合:RDB 快速恢复基线,AOF 补齐增量,实现快速重启与有限丢失。

#
★★

12. 内存淘汰(maxmemory-policy)与过期删除(惰性+定期)的协同机制,近似 LRU/LFU 的采样实现?

请说明内存淘汰(maxmemory-policy)与过期删除(惰性 + 定期)的协同机制,以及近似 LRU/LFU 的采样实现?

  • 淘汰与过期删除的协同
  • 近似 LRU/LFU 的采样
  • 淘汰采样实现

内存淘汰与过期删除协同:当内存达到 maxmemory 时,按 maxmemory-policy 淘汰 key;过期删除(惰性 + 定期)负责清理已过期 key。两者独立但都回收内存,淘汰是"内存满时被动回收",过期删除是"key 到期主动/被动清理"。近似 LRU/LFU 采用采样实现:不维护全量访问顺序,而是随机采样 maxmemory-samples(默认 5)个 key,从中淘汰最符合策略(LRU/LFU/随机)的 key,牺牲精度换取 O(1) 淘汰开销。LFU 用计数器 + 衰减近似访问频率。

近似采样是"内存换性能"的取舍:全量 LRU 需维护访问顺序表(开销大),采样近似以少量误差换取淘汰的常数复杂度。

#
★★

13. Redis 7 的 AOF 多部分(multi-part AOF)架构,manifest 管理、多槽并行与重写/加载流程的变化?

请说明 Redis 7 的 AOF 多部分(multi-part AOF)架构,包括 manifest 管理、多槽并行与重写/加载流程的变化?

  • multi-part AOF 结构
  • manifest 文件管理
  • 重写与加载流程变化

Redis 7 引入多部分 AOF(multi-part AOF):把 AOF 拆分为多个文件,由 manifest 文件管理各 AOF 文件的元数据(版本、顺序、包含哪些 AOF 文件)。相比单个 AOF 文件的 append-only 追加,multi-part 支持:重写时生成新 AOF 文件而不阻塞追加(更平滑)、加载时按 manifest 顺序加载、更利于并发与恢复。重写流程:生成新 AOF 文件并更新 manifest,旧文件删除;加载流程:读 manifest 按序加载各文件。此架构提升了 AOF 重写与加载的健壮性。

multi-part AOF 用 manifest 解耦文件管理,解决了单文件 AOF 重写时的文件替换与追加冲突问题,提升重写与恢复的可靠性。

#
★★

14. Redis 内存监控与容量规划,used_memory、mem_fragmentation_ratio 与 evicted_keys 的解读

请说明 Redis 内存监控与容量规划,包括 used_memory、mem_fragmentation_ratio 与 evicted_keys 的解读?

  • 各内存指标的含义
  • 内存监控与异常判断
  • 容量规划

used_memory:Redis 逻辑内存占用(数据本身);mem_fragmentation_ratio:物理内存 / 逻辑内存,过高说明碎片严重,过低可能说明有内存共享或交换;evicted_keys:因达到 maxmemory 被淘汰的 key 数量,持续增长说明内存压力大。解读:used_memory 接近 maxmemory 且 evicted_keys 增长 → 容量不足,需扩容或优化;mem_fragmentation_ratio > 1.5 需碎片整理;ratio 过低(<1)可能因内存交换或稀疏。容量规划依据 used_memory 峰值、峰值增长、碎片率预留内存(一般预留给峰值 1.5-2 倍)。监控配合 INFO 内存部分与告警。

内存监控是容量规划的依据:used_memory 看用量、evicted_keys 看压力、碎片率看实际物理需求。规划需预留峰值缓冲与碎片空间。

#
★★

15. Redis 8 的持久化(AOF 多线程/多槽)与阻塞操作治理?

请说明 Redis 8 的持久化(AOF 多线程/多槽)与阻塞操作治理?

  • AOF 多线程/多槽
  • 阻塞操作治理
  • 与 Redis 7 的对比

Redis 8 在持久化上进一步演进,AOF 支持多线程/多槽(多文件并发写入),减少 fsync 与写入阻塞,提升持久化吞吐与稳定性。阻塞操作治理:Redis 8 持续优化后台任务(AOF 重写、RDB 生成、大 key 删除用 UNLINK 异步化),降低主线程阻塞;配合多线程 IO 减少网络阻塞。整体目标是在高写入下减少持久化与后台任务对主线程的延迟影响。Redis 8 保留 multi-part AOF 与混合持久化,并增强并发与恢复能力。

Redis 8 的持久化演进出"多线程/多槽"与异步化,核心是减少持久化对主线程的阻塞,提升稳定性与吞吐。

#
★★

16. 大 Key 与持久化/主从同步的相互影响,如何用 Scan/拆分治理?

请说明大 Key 与持久化/主从同步的相互影响,以及如何用 Scan/拆分治理?

  • 大 Key 对持久化的影响
  • 大 Key 对主从同步的影响
  • Scan 识别与拆分治理

大 Key 对持久化的影响:RDB/AOF 生成与重写涉及大 key 时,fork + COW 复制大页、序列化耗时,可能阻塞或增加延迟;对主从同步的影响:全量同步传输大 key 增加带宽与加载时间,增量复制大 key 的修改也可能放大同步延迟。治理:用 SCAN 遍历识别大 key(配合 MEMORY USAGE 精确测量),再用拆分(把大 Hash/List 按时间/业务分片)、压缩、惰性删除(UNLINK)治理。识别后拆分可显著降低持久化与同步的开销。

大 Key 是"持久化与同步的放大器",会放大 COW、传输与加载开销。Scan 识别 + 拆分 + 惰性删除是治理主路径。

#
★★

17. 过期 key 在 RDB 与 AOF 中如何记录?主从节点的过期删除策略差异如何避免读到已过期数据?

请说明过期 key 在 RDB 与 AOF 中如何记录,以及主从节点的过期删除策略差异如何避免读到已过期数据?

  • 过期 key 在 RDB/AOF 的记录
  • 主从过期删除差异
  • 避免读到过期数据

RDB 保存时不会保存已过期 key(快照时过滤);AOF 重写时也不保留过期 key,但 AOF 正常追加会记录造成过期 key 的写命令,并在过期时追加 DEL 命令(AOF 中记录删除)。主从过期删除差异:主库主动删除过期 key(惰性 + 定期),从库不主动删除,而是等待主库的 DEL 命令(同步)或读取时判断过期。为避免读到过期数据,从库在读取时若发现 key 已逻辑过期则返回空并删除(逻辑过期判断),同时主库删除会通过复制同步到从库。设计上从库不主动删除可避免与主库不一致,靠主库删除同步 + 逻辑过期兜底。

主从过期处理是"主库主动、从库被动":主库删除并同步 DEL,从库不主动避免双删,靠逻辑过期判断兜底读保护。RDB/AOF 都不持久化已过期 key。

#

18. Redis 只读缓存场景的持久化取舍,什么时候可以关闭 AOF(appendonly no)?与数据库缓存一致性方案如何配合?

请说明 Redis 只读缓存场景的持久化取舍,什么时候可以关闭 AOF(appendonly no),以及如何与数据库缓存一致性方案配合?

  • 只读缓存场景的持久化需求
  • 关闭 AOF 的时机
  • 与缓存一致性方案配合

Redis 作为纯缓存时,数据可随时从数据库重建,丢失可接受,因此可关闭 AOF(appendonly no)甚至关闭持久化,换取更高性能与减少 fork/fsync 开销。关闭 AOF 的时机:缓存数据全部可重建、缓存丢失不造成业务问题、通常只读缓存(写少读多)。与缓存一致性方案配合:缓存数据源是数据库,通过 Cache-Aside + 删除缓存/过期机制保证与 DB 一致,Redis 丢失后由 DB 重建,无需持久化。若缓存中有不可重建的数据(如计数器、会话),则需保留 AOF。

持久化取舍取决于"缓存数据是否可重建"。纯缓存可重建则关闭 AOF 提升性能;有不可重建数据则需持久化。与一致性方案配合即"缓存重建 + 失效机制"。

#

19. Redis AOF 文件截断(aof-load-truncated)与异常启动的处理

请说明 Redis AOF 文件截断(aof-load-truncated)与异常启动的处理?

  • AOF 文件截断的原因
  • aof-load-truncated 配置
  • 异常启动的处理

AOF 文件截断指 AOF 文件因崩溃、磁盘满等原因被截断(末尾不完整)。aof-load-truncated 配置控制 Redis 加载截断 AOF 时的行为:yes(默认)加载截断前的数据并继续运行(忽略截断部分),no 则报错拒绝启动,需人工修复。异常启动处理:若 aof-load-truncated no 且 AOF 损坏,需用 redis-check-aof 工具修复 AOF 文件,或丢弃损坏 AOF 从 RDB/备份恢复。工程上运营抖动时可用 yes 尽量恢复更多数据。

AOF 截断是崩溃/磁盘异常的常见问题。aof-load-truncated 决定"容忍截断"还是"严格拒绝",配合 redis-check-aof 修复保证可启动。

#

20. 持久化状态如何监控,rdb_bgsave_in_progress、aof_rewrite_in_progress 等指标如何用于延迟排查与容量规划?

请说明持久化状态如何监控,即 rdb_bgsave_in_progress、aof_rewrite_in_progress 等指标如何用于延迟排查与容量规划?

  • 持久化状态指标的含义
  • 延迟排查应用
  • 容量规划应用

持久化状态指标(INFO persistence):rdb_bgsave_in_progress:是否正在 bgsave;rdb_last_bgsave_status:最近一次 bgsave 是否成功;aof_rewrite_in_progress:是否正在 AOF 重写;aof_rewrite_scheduled:是否有待调度的重写。延迟排查:若高延迟期间 bgsave/rewrite 正在进行,说明 fork + COW 或 fsync 可能是延迟来源,可错峰或调整持久化配置。容量规划:根据 bgsave/rewrite 的内存峰值(COW 额外内存)评估实例内存余量,预留足够的物理内存避免 OOM,并规划实例大小与持久化时机。

持久化状态指标把"延迟抖动"与"后台持久化任务"关联起来,用于定位延迟来源;同时 COW 峰值是容量规划的内存余量依据。