高级篇 02. Redis 持久化 - RDB 原理与演示文档

4 阅读5分钟

在单机版 Redis 中,数据全部存放在内存里,一旦服务器停电或宕机,内存里的数据就会瞬间灰飞烟灭。为了保证数据的高可用和持久化,Redis 提供了两种主流方案,我们要学的第一个就“快照派”的代表:RDB。


📚 高级篇 02. Redis 持久化 - RDB 原理与演示文档

一、 核心认知:什么是 RDB?

RDB (Redis Database Backup file) ,也被叫做 Redis 数据快照

你可以把它想象成给当前时刻的 Redis 内存状态**“拍了一张照片”**。它会把内存中的所有数据,经过极度压缩后,生成一个体积非常小的二进制文件(默认叫 dump.rdb),然后保存在硬盘上。

当 Redis 意外宕机重启时,它会自动读取硬盘上的 dump.rdb 文件,把“照片”里的数据重新加载到内存中,瞬间恢复生机。


二、 RDB 的触发机制与演示

要让 Redis 拍这张“照片”,有手动自动两种方式。

1. 手动触发 (两条命令的生死对决)

在 Redis 客户端中,你可以直接输入命令来生成 RDB 文件。这里有两个极其相似但命运截然不同的命令:

  • save 命令 (绝对禁忌):

    • 执行逻辑: 由 Redis 的主进程亲自去执行快照保存。
    • 致命后果: Redis 是单线程处理命令的。如果你的内存里有几十 GB 的数据,保存可能需要好几秒。在这几秒内,Redis 会被完全阻塞,拒绝所有前端用户的读写请求!如果在生产环境执行 save,基本等于主动制造一次“宕机”。
  • bgsave 命令 (企业标准):

    • 执行逻辑: Background Save。Redis 会在后台异步执行快照保存。
    • 核心优势: 它会开启一个独立的子进程去写磁盘,主进程依然可以不受干扰地处理前端用户的增删改查请求。 (面试重点,底层原理见后文)

2. 自动触发 (修改 redis.conf 配置)

在真实的生产环境中,我们不可能靠人工盯着屏幕敲 bgsave。Redis 允许我们在配置文件 redis.conf 中设置自动触发条件。

打开 redis.conf,找到 SNAPSHOTTING 模块,你会看到类似这样的配置:

Properties

# 格式:save <指定时间间隔/秒> <执行指定次数更新操作>
save 3600 1      # 3600秒 (1小时) 内,至少有 1 个 key 被修改,就执行 bgsave
save 300 100     # 300秒 (5分钟) 内,至少有 100 个 key 被修改,就执行 bgsave
save 60 10000    # 60秒 (1分钟) 内,至少有 10000 个 key 被修改,就执行 bgsave

# 如果你想彻底禁用 RDB,可以写成:
# save ""

# RDB 文件的保存名称
dbfilename dump.rdb  

# RDB 文件保存的目录 (通常配成你的持久化数据盘路径)
dir ./ 

三、 面试终极杀招:bgsave 的底层原理 (Copy-On-Write)

这是高级开发工程师面试中必问的 RDB 核心考点。

🤔 面试官发难: “你刚才说 bgsave 不会阻塞主进程,因为开启了子进程。但是,如果在子进程写磁盘的这几秒钟里,主进程同时接收到了修改数据的请求,子进程正在拍的照片会被弄花吗?

你的满分破局回答:

“不会弄花,因为 Redis 底层利用了操作系统的 fork() 机制Copy-On-Write (写时复制) 技术。

  1. Fork 瞬间: 当执行 bgsave 时,主进程会调用 fork() 创建一个子进程。注意,子进程并没有拷贝主进程的物理内存数据,而是拷贝了主进程的虚拟内存页表。这意味着主进程和子进程此时共享着同一块物理内存。所以 fork() 的速度极快。
  2. 写时复制 (COW) 发力: 子进程开始开心地把共享内存里的数据写到 dump.rdb 文件里。此时,如果主进程只接到了用户的读请求,大家相安无事。
  3. 拦截修改: 如果主进程接到了用户的写请求(比如要把 key 从 A 改成 B),操作系统会进行干预!它会先把要修改的这块内存页拷贝一份副本(Copy)
  4. 各干各的: 主进程在刚刚拷贝出来的副本上完成数据的修改(把 A 改成了 B)。而子进程依然在读取原来那块原始内存中的老数据(A)写入 RDB 文件。

这样,既保证了主进程能实时处理新请求,又保证了子进程拍出的一定是执行 bgsave 那个精确时刻的完美快照,互不干扰!”


四、 RDB 的优缺点总结

了解了底层原理,RDB 的优缺点就非常清晰了:

👍 优点:

  1. 恢复速度极快: dump.rdb 是极其紧凑的二进制压缩文件,重启 Redis 时,直接把文件按字节塞进内存就行,恢复速度远超其他方案。
  2. 适合灾备: 体积小,非常适合每隔几小时备份一次,传到远程服务器上做容灾备份。

👎 缺点:

  1. 数据丢失风险大 (最大痛点): RDB 是定时执行的(比如 5 分钟一次)。如果系统在 4 分 59 秒时突然断电宕机,那么这 5 分钟内新写入的所有数据就永久丢失了!
  2. Fork 阻塞成本: 虽然子进程写磁盘不阻塞,但 fork() 拷贝页表的那个瞬间,主进程是阻塞的。如果 Redis 内存极其巨大(比如 64GB),页表也会很大,fork() 可能会导致几百毫秒的卡顿。

正因为 RDB 有着“两次快照之间的数据容易丢失”这个致命缺陷,对于对数据安全性要求极高(如金融、交易订单)的业务来说,是不可接受的。

为了解决这个问题,Redis 推出了它的另一大法宝,也是我们下一节要攻克的对象。