前置知识: Redis

无盘复制

00:00
6 min Advanced 2026/6/14

Redis无盘复制:避免磁盘I/O的复制方案、配置与适用场景

1. 无盘复制概述

无盘复制(Diskless Replication)是 Redis 2.8.18 引入的特性,允许在主从复制过程中跳过磁盘 I/O,直接通过网络将 RDB 数据从主节点发送到从节点,无需在主节点磁盘上生成临时 RDB 文件。

传统复制流程

主节点内存 → RDB文件(磁盘) → 读取磁盘 → 网络发送 → 从节点

无盘复制流程

主节点内存 → 网络直接发送 → 从节点

2. 传统复制的磁盘瓶颈

2.1 问题分析

传统主从复制的 RDB 生成过程涉及两次磁盘 I/O:

  1. 写入磁盘:子进程将 RDB 数据写入临时文件
  2. 读取磁盘:主进程读取临时文件发送给从节点

当数据集较大时,磁盘 I/O 成为瓶颈:

2.2 磁盘瓶颈场景

场景磁盘类型数据集大小磁盘写入耗时网络传输耗时
HDD + 大数据集HDD50 GB~500s~400s (1Gbps)
SSD + 大数据集SSD50 GB~50s~400s (1Gbps)
SSD + 小数据集SSD5 GB~5s~40s (1Gbps)

对于 HDD 环境,磁盘 I/O 可能成为复制的主要瓶颈。

2.3 临时文件对磁盘的影响

  • 临时 RDB 文件可能占用大量磁盘空间
  • 频繁的全量同步会加速磁盘磨损(SSD)
  • 磁盘空间不足会导致复制失败

3. 无盘复制工作原理

3.1 核心机制

无盘复制通过管道(pipe)将 RDB 数据直接从子进程传输到网络套接字:

主节点:
  fork() → 子进程

              │ 生成 RDB 数据


           管道(pipe)


           主进程读取管道 → 网络发送 → 从节点

3.2 详细流程

  1. 主节点收到从节点的 PSYNC 请求
  2. 主节点判断使用无盘复制
  3. 主节点 fork() 子进程
  4. 子进程将 RDB 数据写入管道(而非磁盘文件)
  5. 主进程从管道读取数据,通过套接字发送给从节点
  6. 从节点接收 RDB 数据,写入临时文件
  7. 从节点加载临时 RDB 文件完成同步

3.3 管道缓冲区

管道有容量限制,当子进程写入速度超过网络发送速度时,管道缓冲区满,子进程被阻塞:

// 管道缓冲区大小
#define PIPE_BUF 65536  // 64KB (Linux 默认)

// 实际 Redis 使用更大的管道
// 通过 fcntl(fd, F_SETPIPE_SZ, size) 调整

Redis 会根据网络带宽动态调整管道大小,避免子进程频繁阻塞。

4. 配置与启用

4.1 核心配置

# 开启无盘复制
repl-diskless-sync yes

# 无盘复制延迟启动时间(秒)
repl-diskless-sync-delay 5

# 无盘复制加载模式(Redis 7.0+)
repl-diskless-load on-empty-db

4.2 repl-diskless-sync-delay

延迟启动是为了等待更多从节点同时连接,实现并行复制

从节点1 连接 ──→ 等待 delay 秒
从节点2 连接 ──→ 等待 delay 秒
从节点3 连接 ──→ 等待 delay 秒

                    ▼ delay 到期
              一次性向所有从节点发送 RDB
  • 设为 0:第一个从节点请求时立即开始复制
  • 设为 5(默认):等待 5 秒,收集更多从节点
  • 设为较大值:适合大量从节点同时同步的场景

4.3 repl-diskless-load

Redis 7.0+ 支持从节点无盘加载,直接从网络套接字解析 RDB 数据到内存:

# 配置选项
repl-diskless-load disabled    # 禁用(默认,先写磁盘再加载)
repl-diskless-load on-empty-db # 仅当从节点数据库为空时使用
repl-diskless-load swapdb      # 使用交换数据库(保留旧数据直到加载完成)
repl-diskless-load flush-before-load  # 直接清空后加载(不推荐)

swapdb 模式

1. 从节点创建备份数据库(swapdb)
2. 直接从网络加载 RDB 到主数据库
3. 加载成功后,删除备份数据库
4. 加载失败时,从备份数据库恢复

5. 无盘复制的适用场景

5.1 适合无盘复制

场景原因
HDD 磁盘磁盘 I/O 是瓶颈,无盘复制大幅提升速度
临时磁盘避免写入临时文件
高频全量同步减少磁盘磨损
磁盘空间有限不需要额外空间存储 RDB 文件
多从节点同时同步并行发送效率更高

5.2 不适合无盘复制

场景原因
SSD 磁盘磁盘 I/O 不是瓶颈
网络带宽受限网络成为瓶颈,无盘复制无优势
节点并行复制收益
需要持久化 RDB无盘复制生成磁盘文件

5.3 决策流程

磁盘类型?

  ├─ HDD → 网络带宽 > 磁盘写入速度? → 是 → 开启无盘复制
  │                                    → 否 → 不开启

  └─ SSD → 从节点数量 > 3? → 是 → 考虑开启
                             → 否 → 不开启

6. 性能对比

6.1 复制耗时对比

假设数据集 20GB,HDD 写入 100MB/s,网络带宽 1Gbps:

方案磁盘写入磁盘读取网络传输总耗时
传统复制200s200s160s~560s
无盘复制0s0s160s~160s
提升比例---3.5x

6.2 内存开销

无盘复制复制期间的内存开销:

传统复制相比,无盘复制的内存开销基本相同,因为两者都需要 fork() 和 COW 机制

7. 无盘复制的注意事项

7.1 网络中断

  • 无盘复制过程中网络中断,无法断点续传
  • 必须重新发起全量同步
  • 传统复制可以从已写入的 RDB 文件继续

7.2 多从节点同步

  • 无盘复制支持同时向个从节点发送 RDB
  • 但如果从节点在不同时间请求,后到的从节点需要等待下一次全量同步
  • repl-diskless-sync-delay 可以缓解问题

7.3 与 AOF 的交互

  • 无盘复制影响 AOF 持久化
  • AOF 仍然正常写入磁盘
  • 无盘复制跳过复制过程中的 RDB 磁盘写入

7.4 监控指标

# 查看复制状态
INFO Replication

# 关键指标
# repl_diskless_sync: 是否开启无盘复制
# repl_diskless_sync_delay: 延迟时间
# connected_slaves: 已连接从节点数

知识检测

学习进度

-- 已学文档
--% 知识覆盖率

学习推荐

专注模式