709 字
4 分钟
Redis 的 RDB 快照如何生成?为什么会有写时复制?
  1. 1Redis 系列导读:知识地图、必会主线与复习顺序
  2. 2Redis 中常见的数据类型有哪些?
  3. 3Redis 通常应用于哪些场景?
  4. 4Redis为什么这么快?
  5. 5Redis 常用的过期时间、删除 Key 命令有哪些?
  6. 6Redis 的过期 Key 是如何被删除的?
  7. 7Redis 内存满了怎么办?有哪些淘汰策略?
  8. 8缓存穿透、击穿、雪崩的区别与解决方案
  9. 9Redis 如何保证缓存与数据库的数据一致性?
  10. 10Redis 的持久化机制有哪些?
  11. 11Redis 主从复制的完整流程是什么?
  12. 12Redis 的哨兵机制是什么?
  13. 13Redis Cluster 模式与 Sentinel 模式的区别是什么?
  14. 14Redis 支持事务吗?如何实现?
  15. 15Redis 中如何实现分布式锁?
  16. 16Redis 的 Lua 脚本功能是什么?如何使用?
  17. 17如何解决 Redis 中的热点 Key 问题?
  18. 18Redis BigKey 有什么危害?如何发现和治理?
  19. 19为什么 Redis 设计为单线程?6.0 版本为何引入多线程?
  20. 20Redis 的 LRU 和 LFU 有什么区别?
  21. 21Redis 数据类型和底层编码有什么区别?
  22. 22Redis 中跳表的实现原理是什么?
  23. 23Redis 的 ZSet 为什么使用跳表,而不是平衡树?
  24. 24Redis 的 RDB 快照如何生成?为什么会有写时复制?本文
  25. 25Redis 的 AOF 刷盘和重写有什么区别?
  26. 26Redis 断线后如何通过 PSYNC 部分重同步?
  27. 27Redis 主从切换为什么会丢数据?WAIT 能解决吗?
  28. 28Redis 集群会出现脑裂问题吗?
  29. 29Redisson 看门狗(watch dog)机制了解吗?
  30. 30Redis Cluster:哈希槽、Gossip 与故障转移
  31. 31Redis Pipeline 为什么能提高吞吐?能保证原子性吗?
  32. 32Redis 的 SCAN 和 KEYS 有什么区别?
  33. 33Redis 变慢时如何排查?SLOWLOG 能看到所有耗时吗?
  34. 34Redis 和 MySQL 有什么区别?
  35. 35Redis 为什么使用 SDS,而不是 C 字符串?
  36. 36Redis 的哈希表如何处理冲突和渐进式 rehash?
  37. 37Redis Cluster 的 MOVED 和 ASK 重定向有什么区别?
  38. 38Redis Cluster 为什么会报 CROSSSLOT?Hash Tag 怎么用?
  39. 39Redis 如何实现限流?固定窗口和滑动窗口怎么选?
  40. 40Redis Stream 如何保证消息消费?ACK 和 PEL 是什么?
  41. 41Redis 删除数据后为什么内存不下降?如何理解内存碎片?

RDB 将某一时刻的数据集保存为快照。SAVE 在主线程执行保存,会阻塞命令处理;BGSAVE 在常见 Unix 部署中通过 fork 创建子进程,由子进程生成快照,主进程继续服务。后台保存减少长时间的文件写入阻塞,但不等于整个过程毫无延迟。

fork 为什么不会立刻复制整个数据集?#

fork 后父子进程最初共享物理页,并拥有各自的地址空间映射。操作系统采用写时复制:主进程之后修改共享页时,为写入方分配新页,子进程仍看到快照时刻的旧内容。因此子进程可以保存一致的旧视图,而父进程接收新写入。

举例:开始快照时 stock=100,主进程随后把它改成 99。子进程保存的是快照视图中的 100,后续 AOF 或复制增量负责记录新的修改。不能把 BGSAVE 想成子进程不断读取父进程随时变化的“最新内存”。

fork 自身需要复制页表等内核工作,数据集越大,其耗时越值得关注。快照期间若写入密集,大量页触发 COW,额外内存可能显著增长;一个很小的字段修改也可能使其所在内存页复制。磁盘慢会延长子进程存活时间,从而扩大 COW 累计窗口。

RDB 的优势与风险#

RDB 文件较紧凑,适合备份和相对快速的数据集恢复。代价是两次成功快照之间的修改可能丢失,具体损失量与快照周期和故障时刻有关。备份应复制完整且生成成功的快照,并验证恢复过程,不能只看目录里有一个文件。

常见追问#

BGSAVE 会阻塞多久?#

主要关注 fork 阶段的暂停,以及后续资源竞争对延迟的影响;后台写文件不是全程阻塞主线程。实际耗时应查看 INFO persistence 与延迟指标。

快照时内存会直接翻倍吗?#

不会必然立刻翻倍。增长由被修改的共享页、页表和进程开销决定,写密集时则可能接近很高的额外需求。容量规划要按峰值留余量。

无盘复制就没有 COW 开销了吗?#

不一定。无盘复制减少中间磁盘文件步骤,但生成快照的后台过程仍可能使用 fork 与 COW;它主要改变快照输出路径。

把 RDB 周期缩短就能做到零丢失吗?#

不能。快照之间仍有窗口,频繁生成快照还增加资源消耗。需要结合 AOF、复制和业务持久化设计确定可接受的恢复点。

Redis 的 RDB 快照如何生成?为什么会有写时复制?
https://blog.xqcherry.top/posts/interview/redis/redis-rdb-and-copy-on-write/
作者
xqcherry
发布于
2026-10-12
许可协议
CC BY-NC-SA 4.0