Redis篇3——Redis深度剖析:内存数据的“不死之身”——RDB、AOF与混合持久化

在上一篇中,我们探讨了 Redis 的分布式锁。今天,我们回归 Redis 的本质——内存数据库

既然是“内存”数据库,大家最担心的就是一个问题:断电了怎么办? 如果服务器宕机,内存里的数据就会瞬间蒸发,这对业务来说是灾难性的。

为了解决这个问题,Redis 提供了强大的持久化机制,将内存数据写入磁盘。本文将深入扒开 RDB、AOF 以及 Redis 4.0 引入的混合持久化的底层细节。


一、 RDB:给内存拍张“照片”

RDB (Redis Database Backup file),又被称为数据快照。

它的原理非常直观:在指定的时间间隔内,将内存中的所有数据集快照写入磁盘。 恢复时,直接将快照文件读入内存。

1. 触发机制

redis.conf 中,我们可以配置触发规则:

Bash

save 900 1      # 900秒内,至少1个key被修改,则触发
save 300 10     # 300秒内,至少10个key被修改,则触发
save 60 10000   # 60秒内,至少10000个key被修改,则触发

除了自动触发,我们还可以手动执行命令:

  • save:由主进程执行。注意! 因为 Redis 是单线程的,主进程去写磁盘,会直接阻塞所有客户端请求,生产环境绝对禁止使用。

  • bgsaveBackground Save。Redis 会在后台异步进行快照操作,不阻塞主进程。

2. 原理深度剖析:bgsave 与 它的底层实现:Copy-On-Write (写时复制)

写时复制的意思其实就是主线程在进行写操作的时候,先复制备份一份,在备份的这个文件上去进行写操作,这样子进程读操作就可以保证一直读的是之前的那个旧版本。

问题场景:Redis 一边在“拍照”(持久化),一边还在“干活”(处理用户写请求)。如果数据一直在变,照片怎么拍?比如拍照要 1 分钟,这 1 分钟内数据变了怎么办?

为了解决这个问题,Redis 引入了 Fork 和 COW (Copy-On-Write) 机制。

第一步:Fork 子进程

当执行 bgsave 时,主进程会调用操作系统的 fork() 系统调用,创建一个子进程

  • 关键点fork 不会复制原本的 10GB 内存数据(否则内存瞬间爆炸且耗时极长)。

  • 它只复制主进程的页表(Page Table)。页表可以理解为内存数据的“目录”。

  • 结果:子进程诞生的一瞬间,它手里的“目录”和主进程一模一样,指向同一块物理内存。这个过程极快,只阻塞主进程几毫秒。

第二步:写时复制 (Copy-On-Write)

fork 结束后,主进程继续响应客户端请求,子进程负责写文件。

此时,主子进程共享同一份物理内存。

  • 如果主进程是读数据:大家相安无事。

  • 如果主进程要写数据(比如修改 Key A)

    1. 操作系统发现这块内存被共享且标记为“只读”,触发中断。

    2. 操作系统将 Key A 所在的**那一页内存(4KB)**复制一份副本。

    3. 主进程副本上修改 Key A。

    4. 子进程继续读取原件

结论:

通过 COW 机制,子进程拿到的永远是 fork 那一瞬间的“时间冻结”数据。无论主进程怎么改,生成的 RDB 文件都是绝对纯净、一致的快照。

3. RDB 优缺点

  • 优点:恢复速度极快(解压二进制文件即可);文件体积小。

  • 缺点数据安全性低。RDB 是间隔执行的,如果每 5 分钟拍一次,Redis 在第 4 分钟宕机,你就会丢失这 4 分钟的所有数据。


二、 AOF:记账员的“流水账”

简单来说RDB是拍照AOF就是记录所有的命令。

AOF (Append Only File),意思是追加文件。

它的逻辑与 RDB 完全不同:Redis 每执行一条写命令,就把它以文本协议的格式追加到日志文件的末尾。

恢复时,Redis 就像重播电影一样,把日志里的命令从头到尾执行一遍。

1. 刷盘策略 (fsync)

AOF 解决了 RDB 丢数据的问题,但“写文件”也是有磁盘 IO 开销的。Redis 提供了三种策略:

  • Always同步刷盘。每执行一条写命令,立马强制写入磁盘。

    • 优点:数据绝对安全。

    • 缺点:性能极差,吞吐量低。

  • Everysec (默认)每秒刷盘。先把命令写到缓冲区,每隔 1 秒将缓冲区写入磁盘。

    • 优点:性能与安全的平衡点,最多丢失 1 秒数据。

  • No:操作系统看着办。性能最好,但不可控。

2. AOF 重写 (Rewrite)

随着时间推移,AOF 文件会越来越大。

比如你对 count 执行了 100 次 INCR,最终 count=100。AOF 文件里存了 100 条命令,但恢复数据时,其实只需要一条 SET count 100 就够了。

为了给日志“瘦身”,Redis 提供了 bgrewriteaof 命令:

  • Redis 会创建一个子进程。

  • 子进程读取当前的内存状态。

  • 最少的命令构建一个新的 AOF 文件,替换掉旧的大文件。

3. AOF 优缺点

  • 优点数据安全。使用 everysec 策略,顶多丢失 1 秒数据。

  • 缺点恢复速度慢(要重新执行所有命令);文件体积通常比 RDB 大。


三、 混合持久化(升级版”的 AOF 重写(瘦身)方式)

简单来说就是先把当前现有的存为RDB格式,然后新增的用AOF格式追加在后面。

在 Redis 4.0 之前,我们经常陷入纠结:用 RDB 怕丢数据,用 AOF 怕恢复太慢。

Redis 4.0 推出了 RDB-AOF 混合持久化,作为默认配置,完美解决了这个问题。

1. 核心原理

混合持久化发生在 AOF 重写 的过程中。

当 Redis 重写 AOF 文件时,它不再只是单纯地把内存转成 AOF 命令,而是:

  1. 前半部分:将当前的内存数据,以 RDB (二进制快照) 的格式写入 AOF 文件开头。

  2. 后半部分:在重写期间产生的新增量数据,依然以 AOF (文本命令) 的格式追加在后面。

2. 最终的文件结构

打开一个开启了混合持久化的 .aof 文件,你会发现:

  • 开头是乱码一样的二进制数据(RDB 快照)。

  • 末尾是可读的文本命令(AOF 增量日志)。

3. 压倒性的优势

  • 启动超快:Redis 启动时,先加载开头的 RDB 部分,速度飞快。

  • 数据不丢:加载完 RDB 后,再执行末尾少量的 AOF 命令,补全最后时刻的数据。


四、 总结与选型建议

特性RDB (快照)AOF (日志)混合持久化
底层原理Fork + Copy-On-Write追加写 + 重写RDB + AOF
恢复速度
数据安全性低 (可能丢几分钟)高 (丢1秒)
文件大小中等

给开发者的建议:

  1. 生产环境:强烈建议开启 混合持久化(Redis 4.0+ 默认开启)。这是目前的最佳实践。

  2. 纯缓存模式:如果你完全不在乎数据丢失(比如只是做数据库的缓存,丢了可以回源查 MySQL),可以关闭所有持久化,获得极致的性能。

  3. 永远不要只开启 RDB:除非你这台 Redis 是用来做纯粹的离线备份,否则数据丢失的风险在生产环境中是不可接受的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值