Skip to content

Redis 复制同步

Redis 复制同步是实现高可用性和数据冗余的关键机制,通过将主节点的数据同步到从节点,确保数据的可靠性和服务的连续性。本文档将详细介绍 Redis 复制同步的核心概念、工作原理、配置、监控、故障处理和优化。

核心概念

1. 复制角色

  • 主节点(Master):负责处理写请求,并将数据同步到从节点
  • 从节点(Slave/Replica):负责接收主节点同步的数据,处理读请求
  • 复制组:由一个主节点和多个从节点组成的复制集群

2. 复制类型

  • 全量复制:从节点首次连接主节点时,主节点将完整数据集同步给从节点
  • 部分复制:从节点断开重连后,主节点仅将断开期间的增量数据同步给从节点
  • 链式复制:从节点可以作为其他从节点的主节点,形成复制链

3. 复制同步相关指标

  • 复制偏移量(Replication Offset):主节点和从节点分别维护的偏移量,用于标识数据同步进度
  • 复制积压缓冲区(Replication Backlog Buffer):主节点维护的环形缓冲区,用于存储近期写入的数据,支持部分复制
  • 复制 ID(Replication ID):主节点每次重启或执行 FLUSHALL/FLUSHDB 命令时生成的唯一标识符,用于标识复制流
  • 主节点运行 ID(Run ID):主节点的唯一标识符,用于从节点识别主节点

复制同步原理

1. 全量复制

全量复制是从节点首次连接主节点或无法进行部分复制时执行的同步方式,过程如下:

  1. 从节点连接主节点:从节点发送 PSYNC ? -1 命令请求同步
  2. 主节点响应:主节点返回 FULLRESYNC <runid> <offset> 命令,开始全量复制
  3. 主节点生成 RDB 文件:主节点执行 BGSAVE 命令生成 RDB 文件
  4. 主节点发送 RDB 文件:主节点将 RDB 文件发送给从节点
  5. 从节点加载 RDB 文件:从节点接收并加载 RDB 文件,清空现有数据
  6. 主节点发送缓冲区数据:主节点将生成 RDB 文件期间的写入命令发送给从节点
  7. 从节点应用缓冲区数据:从节点应用主节点发送的写入命令,完成数据同步

2. 部分复制

部分复制是从节点断开重连后,主节点仅将断开期间的增量数据同步给从节点的方式,过程如下:

  1. 从节点重连主节点:从节点发送 PSYNC <runid> <offset> 命令,请求部分复制
  2. 主节点验证请求:主节点验证从节点提供的 runidoffset
  3. 主节点发送增量数据:如果从节点的 offset 仍在主节点的复制积压缓冲区范围内,主节点返回 CONTINUE 命令,并发送积压缓冲区中的增量数据
  4. 从节点应用增量数据:从节点应用主节点发送的增量数据,完成数据同步
  5. 回退到全量复制:如果从节点的 offset 不在主节点的复制积压缓冲区范围内,主节点回退到全量复制

3. 复制同步流程

复制同步配置

1. 主要配置参数

配置参数描述默认值建议值
replicaof指定主节点地址和端口--
masterauth主节点认证密码-与主节点密码一致
repl-diskless-sync是否使用无盘同步noyes(减少磁盘I/O)
repl-diskless-sync-delay无盘同步延迟时间55
repl-ping-replica-period从节点向主节点发送PING的周期1010
repl-timeout复制超时时间6060
repl-backlog-size复制积压缓冲区大小1mb128mb(根据写入量调整)
repl-backlog-ttl复制积压缓冲区有效期36003600
replica-read-only从节点是否只读yesyes
replica-serve-stale-data从节点是否在同步过程中提供过期数据yesno
min-replicas-to-write主节点允许写入的最小从节点数01(提高数据可靠性)
min-replicas-max-lag主节点允许写入的最大从节点延迟1010

2. 配置示例

从节点配置

txt
# redis.conf(从节点)
# 指定主节点地址和端口
replicaof 192.168.1.100 6379

# 主节点认证密码
masterauth yourpassword

# 使用无盘同步
repl-diskless-sync yes

# 复制积压缓冲区大小
repl-backlog-size 128mb

# 从节点只读
replica-read-only yes

# 同步过程中不提供过期数据
replica-serve-stale-data no

主节点配置

txt
# redis.conf(主节点)
# 允许写入的最小从节点数
min-replicas-to-write 1

# 允许写入的最大从节点延迟
min-replicas-max-lag 10

复制同步监控

1. 使用 redis-cli 监控

bash
# 查看复制状态
redis-cli info replication

# 查看主节点复制偏移量
redis-cli info replication | grep master_repl_offset

# 查看从节点复制偏移量
redis-cli info replication | grep slave_repl_offset

# 查看复制积压缓冲区状态
redis-cli info replication | grep repl_backlog

# 实时监控复制延迟
redis-cli --latency -h <slave-ip> -p <slave-port>

2. 使用 Prometheus + Grafana 监控

关键监控指标

指标名称描述
redis_replication_master_link_status主从连接状态(up/down)
redis_replication_offset_master主节点复制偏移量
redis_replication_offset_slave从节点复制偏移量
redis_replication_offset_delayed从节点复制延迟
redis_replication_backlog_active复制积压缓冲区是否活跃
redis_replication_backlog_size复制积压缓冲区大小
redis_replication_backlog_histlen复制积压缓冲区历史长度

Grafana 监控面板

  1. 安装 Redis 监控面板(ID: 763)
  2. 配置复制同步相关指标的监控图表
  3. 设置复制延迟告警阈值

3. 自定义监控脚本

bash
#!/bin/bash
# Redis 复制同步监控脚本

REDIS_CLI="redis-cli"
MASTER_HOST="192.168.1.100"
MASTER_PORT="6379"
SLAVE_HOST="192.168.1.101"
SLAVE_PORT="6379"

# 获取主节点复制偏移量
MASTER_OFFSET=$($REDIS_CLI -h $MASTER_HOST -p $MASTER_PORT info replication | grep master_repl_offset | awk -F: '{print $2}' | tr -d '[:space:]')

# 获取从节点复制偏移量
SLAVE_OFFSET=$($REDIS_CLI -h $SLAVE_HOST -p $SLAVE_PORT info replication | grep slave_repl_offset | awk -F: '{print $2}' | tr -d '[:space:]')

# 计算复制延迟
REPL_DELAY=$((MASTER_OFFSET - SLAVE_OFFSET))

# 获取从节点连接状态
SLAVE_STATUS=$($REDIS_CLI -h $SLAVE_HOST -p $SLAVE_PORT info replication | grep master_link_status | awk -F: '{print $2}' | tr -d '[:space:]')

# 输出监控结果
echo "$(date +"%Y-%m-%d %H:%M:%S") Redis 复制同步监控:"
echo "  主节点偏移量: $MASTER_OFFSET"
echo "  从节点偏移量: $SLAVE_OFFSET"
echo "  复制延迟: $REPL_DELAY 字节"
echo "  从节点连接状态: $SLAVE_STATUS"

# 检查复制延迟是否超过阈值
if [ $REPL_DELAY -gt 1048576 ]; then
    echo "  告警: 复制延迟超过 1MB"
fi

复制同步故障处理

1. 常见故障类型

1.1 主从连接断开

现象

  • 从节点 master_link_status 显示为 down
  • 从节点日志中出现 Connection refusedConnection reset by peer 错误

原因

  • 主节点宕机
  • 网络故障
  • 主节点配置错误
  • 从节点配置错误

解决方法

  1. 检查主节点是否正常运行
  2. 检查网络连通性
  3. 验证主节点地址和端口配置
  4. 验证主节点认证密码配置
  5. 检查防火墙设置

1.2 复制延迟过高

现象

  • 从节点 slave_repl_offset 与主节点 master_repl_offset 差距过大
  • 应用读取从节点数据时出现数据不一致

原因

  • 主节点写入量过大
  • 网络带宽不足
  • 从节点性能不足
  • 复制积压缓冲区过小
  • 从节点配置不当

解决方法

  1. 增加从节点数量,分担复制压力
  2. 优化网络带宽
  3. 提升从节点硬件配置
  4. 增大 repl-backlog-size 配置
  5. 调整 repl-diskless-syncyes
  6. 优化主节点写入模式,减少大键写入

1.3 全量复制频繁触发

现象

  • 从节点频繁进行全量复制
  • 主节点 BGSAVE 命令频繁执行
  • 网络流量突增

原因

  • 复制积压缓冲区过小
  • 主节点运行 ID 频繁变化(主节点频繁重启)
  • 从节点频繁断开连接
  • 主节点执行 FLUSHALL/FLUSHDB 命令

解决方法

  1. 增大 repl-backlog-size 配置
  2. 确保主节点稳定运行,避免频繁重启
  3. 优化从节点网络连接,减少断开次数
  4. 避免在主节点上执行 FLUSHALL/FLUSHDB 命令
  5. 使用 Redis Sentinel 或 Cluster 提高可用性

1.4 从节点无法加载 RDB 文件

现象

  • 从节点日志中出现 Failed to load the RDB file 错误
  • 从节点无法完成全量复制

原因

  • RDB 文件损坏
  • 从节点内存不足
  • 从节点版本与主节点不兼容
  • 从节点权限不足

解决方法

  1. 验证主节点 RDB 文件完整性
  2. 增加从节点内存配置
  3. 确保从节点版本与主节点兼容(建议使用相同主版本)
  4. 检查从节点数据目录权限
  5. 尝试手动复制 RDB 文件到从节点并加载

2. 故障处理流程

复制同步优化

1. 性能优化

1.1 减少全量复制次数

  • 增大 repl-backlog-size 配置,确保复制积压缓冲区足够大
  • 确保主节点稳定运行,避免频繁重启
  • 优化从节点网络连接,减少断开次数
  • 避免在主节点上执行 FLUSHALL/FLUSHDB 命令

1.2 提高全量复制效率

  • 启用无盘同步:将 repl-diskless-sync 设置为 yes
  • 优化主节点 BGSAVE 性能:调整 save 配置,避免频繁生成 RDB 文件
  • 提升从节点 RDB 加载速度:使用更快的存储设备,优化从节点配置

1.3 减少复制延迟

  • 增加从节点数量,分担复制压力
  • 优化网络带宽,确保主从节点之间网络通畅
  • 提升从节点硬件配置,尤其是 CPU 和内存
  • 优化主节点写入模式,减少大键写入和批量操作
  • 使用链式复制,减少主节点直接复制的从节点数量

2. 可靠性优化

2.1 增加从节点数量

  • 每个主节点至少配置 2 个从节点
  • 从节点分布在不同的物理机器或数据中心
  • 考虑使用 Sentinel 或 Cluster 实现自动故障转移

2.2 配置写保护

  • 将从节点设置为只读:replica-read-only yes
  • 配置 min-replicas-to-writemin-replicas-max-lag,确保主节点在从节点不可用时停止写入

2.3 定期验证复制状态

  • 配置监控告警,及时发现复制故障
  • 定期手动验证主从数据一致性
  • 使用 Redis 5.0+ 的 REPLICAOF NO ONE 命令测试从节点提升为主节点的能力

3. 架构优化

3.1 使用链式复制

  • 对于大规模 Redis 集群,使用链式复制减少主节点压力
  • 主节点 → 从节点1 → 从节点2 → ...
  • 注意控制复制链的长度,避免复制延迟累积

3.2 使用 Sentinel 或 Cluster

  • 对于高可用性要求较高的场景,使用 Redis Sentinel 或 Cluster
  • Sentinel 提供自动故障转移功能
  • Cluster 提供自动分片和故障转移功能

3.3 跨数据中心复制

  • 对于容灾要求较高的场景,实现跨数据中心复制
  • 主数据中心和备数据中心各部署一套 Redis 集群
  • 使用异步复制或半同步复制实现数据同步

常见问题(FAQ)

Q1: 如何判断 Redis 复制同步是否正常?

A1: 可以通过以下方法判断 Redis 复制同步是否正常:

  1. 查看从节点的 master_link_status 指标,应为 up
  2. 比较主节点和从节点的 master_repl_offsetslave_repl_offset,差距应较小
  3. 检查从节点日志,无复制相关错误
  4. 使用 redis-cli info replication 命令查看复制状态
  5. 配置监控告警,及时发现复制故障

Q2: 复制积压缓冲区大小如何设置?

A2: 复制积压缓冲区大小应根据主节点的写入量和从节点可能断开的时间来设置:

  • 计算公式:repl-backlog-size = 主节点每秒写入量 × 从节点最大断开时间
  • 例如:主节点每秒写入 10MB,从节点最大断开时间为 30 秒,则 repl-backlog-size 应设置为 300MB
  • 建议最小值为 64MB,最大值根据实际情况调整

Q3: 主从复制是同步还是异步?

A3: Redis 主从复制默认是异步的:

  • 主节点处理写请求后,将命令发送给从节点,不等待从节点确认
  • 异步复制的优点是性能高,缺点是可能存在数据不一致
  • Redis 2.8+ 支持半同步复制,主节点处理写请求后,等待至少一个从节点确认后再返回给客户端
  • 半同步复制可以提高数据可靠性,但会降低主节点性能

Q4: 如何实现主从数据一致性验证?

A4: 可以通过以下方法实现主从数据一致性验证:

  1. 使用 redis-cli --rdb 命令分别生成主节点和从节点的 RDB 文件,然后比较文件内容
  2. 使用第三方工具如 redis-full-check 进行数据一致性校验
  3. 在应用层实现数据校验逻辑,定期对比主从节点数据
  4. 使用 Redis 5.0+ 的 CLIENT TRACKING 功能,实时监控数据变化

Q5: 从节点可以处理写请求吗?

A5: 默认情况下,从节点是只读的,不允许处理写请求:

  • 可以通过设置 replica-read-only no 允许从节点处理写请求
  • 但从节点的写操作不会同步到主节点,也不会同步到其他从节点
  • 不建议在生产环境中允许从节点处理写请求,容易导致数据不一致

Q6: 主节点宕机后,如何将从节点提升为主节点?

A6: 可以通过以下方法将从节点提升为主节点:

  1. 手动提升:在从节点上执行 REPLICAOF NO ONE 命令
  2. 使用 Redis Sentinel:Sentinel 会自动检测主节点故障并将从节点提升为主节点
  3. 使用 Redis Cluster:Cluster 会自动检测主节点故障并将从节点提升为主节点

Q7: 如何优化 Redis 复制性能?

A7: 可以通过以下方法优化 Redis 复制性能:

  1. 启用无盘同步:repl-diskless-sync yes
  2. 增大复制积压缓冲区:repl-backlog-size 128mb
  3. 优化从节点配置:提升硬件配置,调整 replica-serve-stale-data no
  4. 减少全量复制次数:确保主节点稳定运行,避免频繁重启
  5. 使用链式复制:减少主节点直接复制的从节点数量
  6. 优化主节点写入模式:减少大键写入,避免批量操作

Q8: 半同步复制和异步复制有什么区别?

A8: 半同步复制和异步复制的主要区别:

特性异步复制半同步复制
性能中等
数据可靠性较低较高
主节点等待确认是(至少一个从节点)
延迟中等
配置复杂度中等

半同步复制可以提高数据可靠性,但会降低主节点性能。建议在对数据可靠性要求较高的场景中使用半同步复制。