Skip to content

Redis 主从复制

Redis 主从复制是 Redis 高可用性架构的基础,通过主从复制可以实现数据的冗余备份、读写分离和负载均衡。本文档将详细介绍 Redis 主从复制的核心概念、工作原理、配置方法、管理和监控以及最佳实践。

主从复制原理

1. 复制的三个阶段

Redis 主从复制过程分为三个阶段:

1.1 连接建立阶段

  • 从节点发起连接:从节点通过 SLAVEOF 命令或配置文件指定主节点地址和端口
  • 主从握手:从节点向主节点发送 SYNC 命令,请求同步数据
  • 建立复制关系:主节点接受从节点的连接请求,建立复制关系

1.2 数据同步阶段

  • 主节点生成 RDB 文件:主节点执行 BGSAVE 命令生成 RDB 文件
  • 主节点发送 RDB 文件:主节点将生成的 RDB 文件发送给从节点
  • 从节点加载 RDB 文件:从节点接收 RDB 文件并加载到内存中
  • 主节点发送缓冲区命令:主节点将生成 RDB 文件期间的写命令发送给从节点
  • 从节点执行缓冲区命令:从节点执行主节点发送的缓冲区命令,实现数据一致性

1.3 命令传播阶段

  • 主节点发送写命令:主节点将后续的写命令实时发送给从节点
  • 从节点执行写命令:从节点实时执行主节点发送的写命令,保持数据与主节点一致
  • 心跳机制:主从节点之间通过心跳机制保持连接

2. 全量复制

全量复制是指从节点第一次连接主节点时,主节点将所有数据发送给从节点的过程。

2.1 全量复制触发条件

  • 从节点第一次连接主节点
  • 从节点与主节点的复制偏移量差距超过复制积压缓冲区大小
  • 主节点重启后,从节点重新连接

2.2 全量复制过程

  1. 从节点向主节点发送 PSYNC ? -1 命令,请求同步数据
  2. 主节点返回 FULLRESYNC <runid> <offset> 命令,告知从节点需要执行全量复制
  3. 主节点执行 BGSAVE 命令生成 RDB 文件
  4. 主节点将生成 RDB 文件期间的写命令存储到复制缓冲区
  5. 主节点将 RDB 文件发送给从节点
  6. 从节点接收并加载 RDB 文件
  7. 主节点将复制缓冲区中的写命令发送给从节点
  8. 从节点执行这些写命令,实现数据一致性

2.3 全量复制的影响

  • 主节点开销:生成 RDB 文件和发送 RDB 文件会消耗主节点的 CPU、内存和网络资源
  • 从节点开销:接收和加载 RDB 文件会消耗从节点的网络、内存和磁盘资源
  • 复制延迟:全量复制过程中,从节点数据与主节点存在延迟
  • 带宽消耗:大量从节点同时进行全量复制会消耗大量网络带宽

3. 部分复制

部分复制是指从节点与主节点断开连接后重新连接时,只复制断开期间主节点的写命令的过程。

3.1 部分复制触发条件

  • 从节点与主节点的复制偏移量差距在复制积压缓冲区大小范围内
  • 从节点重新连接主节点时,主节点的 runid 未发生变化

3.2 部分复制关键组件

  • 复制偏移量:主节点和从节点各自维护一个复制偏移量,记录已复制的字节数
  • 复制积压缓冲区:主节点维护的一个环形缓冲区,存储最近的写命令
  • runid:每个 Redis 实例的唯一标识符,用于标识主节点身份

3.3 部分复制过程

  1. 从节点向主节点发送 PSYNC <runid> <offset> 命令,请求部分复制
  2. 主节点检查 runid 和复制偏移量:
    • 如果 runid 匹配且偏移量在复制积压缓冲区内,返回 CONTINUE,执行部分复制
    • 否则,返回 FULLRESYNC <runid> <offset>,执行全量复制
  3. 主节点从复制积压缓冲区中读取从节点缺失的写命令
  4. 主节点将这些写命令发送给从节点
  5. 从节点执行这些写命令,实现数据一致性

3.4 部分复制的优势

  • 减少复制延迟:只复制断开期间的写命令,减少复制时间
  • 降低主节点开销:不需要生成和发送 RDB 文件
  • 减少网络带宽消耗:只传输断开期间的写命令
  • 提高复制效率:适用于网络不稳定的场景

4. 心跳机制

主从节点之间通过心跳机制保持连接,监控对方状态。

  • 主节点心跳:主节点每隔 10 秒向从节点发送 PING 命令
  • 从节点心跳:从节点每隔 1 秒向主节点发送 REPLCONF ACK <offset> 命令,包含当前复制偏移量
  • 心跳作用
    • 检测主从节点之间的网络连接状态
    • 主节点通过从节点的 ACK 命令了解从节点的复制进度
    • 从节点通过主节点的 PING 命令了解主节点的状态

主从复制配置

1. 配置主节点

主节点默认不需要特殊配置,只需确保以下配置正确:

txt
# redis.conf

# 监听地址,建议绑定到特定IP
bind 0.0.0.0

# 端口号
port 6379

# 开启保护模式
protected-mode yes

# 设置密码(可选)
requirepass your_password

# 复制积压缓冲区大小(默认1mb)
repl-backlog-size 1mb

# 复制积压缓冲区过期时间(默认3600秒)
repl-backlog-ttl 3600

2. 配置从节点

从节点需要配置主节点的地址和端口,可以通过配置文件或命令方式配置。

2.1 配置文件方式

txt
# redis.conf

# 监听地址
bind 0.0.0.0

# 端口号
port 6380

# 开启保护模式
protected-mode yes

# 配置主节点地址和端口
replicaof 127.0.0.1 6379

# 配置主节点密码
masterauth your_password

# 从节点只读模式(默认yes)
replica-read-only yes

# 启用无盘复制(默认no)
repl-diskless-sync no

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

# 从节点优先级(默认100)
replica-priority 100

2.2 命令方式

bash
# 连接从节点
redis-cli -p 6380

# 配置主节点
127.0.0.1:6380> SLAVEOF 127.0.0.1 6379

# 配置主节点密码
127.0.0.1:6380> CONFIG SET masterauth your_password

# 查看复制状态
127.0.0.1:6380> INFO replication

2.3 取消复制关系

bash
# 连接从节点
redis-cli -p 6380

# 取消复制关系
127.0.0.1:6380> SLAVEOF NO ONE

3. 验证复制状态

使用 INFO replication 命令可以查看主从复制状态:

3.1 主节点复制状态

bash
redis-cli -p 6379 info replication

输出示例:

# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1000,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=1000,lag=0
master_replid:5337f03d7d9a8c9a900c8912b893594a08bc71f0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1000
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1000

3.2 从节点复制状态

bash
redis-cli -p 6380 info replication

输出示例:

# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:1000
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:5337f03d7d9a8c9a900c8912b893594a08bc71f0
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1000
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1000

主从复制管理

1. 查看复制状态

使用 INFO replication 命令查看主从复制状态,重点关注以下指标:

  • master_link_status:从节点与主节点的连接状态(up/down)
  • slave_repl_offset:从节点的复制偏移量
  • master_repl_offset:主节点的复制偏移量
  • lag:从节点与主节点的复制延迟(秒)
  • connected_slaves:主节点连接的从节点数量

2. 从节点只读模式

从 Redis 2.6 开始,从节点默认处于只读模式,可以通过以下配置修改:

txt
# redis.conf
replica-read-only yes

或通过命令方式:

bash
redis-cli -p 6380 CONFIG SET replica-read-only no

3. 从节点故障处理

  • 检测故障:通过监控 master_link_status 指标检测从节点故障
  • 处理故障
    • 如果从节点暂时不可用,等待其恢复后自动重连
    • 如果从节点永久故障,移除该从节点并添加新的从节点
  • 数据一致性:从节点恢复后,会自动与主节点同步数据

4. 主节点故障处理

  • 检测故障:通过监控主节点的心跳或使用 Sentinel 检测主节点故障
  • 手动故障转移
    1. 选择一个健康的从节点
    2. 执行 SLAVEOF NO ONE 命令将其提升为主节点
    3. 其他从节点执行 SLAVEOF new-master-ip new-master-port 命令连接新主节点
  • 自动故障转移:使用 Redis Sentinel 实现自动故障转移

5. 更换主节点

在某些情况下,需要更换主节点,例如主节点硬件升级、迁移等:

  1. 选择新主节点:选择一个健康的从节点作为新主节点
  2. 执行手动故障转移
    • 在新主节点上执行 SLAVEOF NO ONE
    • 在其他从节点上执行 SLAVEOF new-master-ip new-master-port
  3. 更新客户端配置:将客户端连接指向新主节点
  4. 监控新主节点状态:确保新主节点正常运行,从节点同步正常

主从复制监控

1. 监控指标

  • 复制状态

    • master_link_status:从节点与主节点的连接状态
    • connected_slaves:主节点连接的从节点数量
    • slave_repl_offset:从节点的复制偏移量
    • master_repl_offset:主节点的复制偏移量
    • lag:从节点与主节点的复制延迟
  • 复制性能

    • repl_backlog_active:复制积压缓冲区是否激活
    • repl_backlog_size:复制积压缓冲区大小
    • repl_backlog_histlen:复制积压缓冲区中当前存储的字节数
    • repl_backlog_first_byte_offset:复制积压缓冲区中第一个字节的偏移量
  • 持久化相关

    • rdb_last_bgsave_status:最后一次 BGSAVE 命令的执行状态
    • rdb_last_bgsave_time_sec:最后一次 BGSAVE 命令的执行时间
    • aof_last_bgrewrite_status:最后一次 AOF 重写命令的执行状态

2. 监控工具

  • Redis 内置命令

    • INFO replication:查看复制状态
    • MONITOR:实时监控 Redis 命令执行
    • CLIENT LIST:查看客户端连接信息
  • 第三方监控工具

    • Prometheus + Grafana:常用的监控组合,支持自定义仪表盘
    • Redis Exporter:用于采集 Redis 监控指标
    • Datadog:提供 Redis 监控集成
    • New Relic:提供 Redis 监控集成
    • Zabbix:支持 Redis 监控模板

3. 常见问题

3.1 从节点与主节点连接断开

  • 原因:网络故障、主节点故障、配置错误等
  • 检测:监控 master_link_status 指标
  • 处理:检查网络连接、主节点状态、配置文件等

3.2 复制延迟过大

  • 原因

    • 主节点写入量过大
    • 从节点性能不足
    • 网络带宽不足
    • 全量复制正在进行
    • 从节点执行了慢查询
  • 处理

    • 优化主节点写入性能
    • 提升从节点硬件配置
    • 增加网络带宽
    • 合理配置复制积压缓冲区大小
    • 避免在从节点执行慢查询

3.3 从节点频繁进行全量复制

  • 原因

    • 主节点频繁重启
    • 从节点与主节点的复制偏移量差距超过复制积压缓冲区大小
    • 主节点的 runid 发生变化
  • 处理

    • 减少主节点重启次数
    • 增加复制积压缓冲区大小
    • 确保从节点与主节点的网络连接稳定

主从复制最佳实践

1. 部署建议

  • 主从节点分布:将主节点和从节点部署在不同的物理机器或可用区,避免单点故障
  • 从节点数量:根据业务需求和主节点性能确定从节点数量,一般建议 2-5 个
  • 级联复制:对于大量从节点的场景,使用级联复制减少主节点的复制压力
  • 硬件配置:主节点和从节点使用相同或相似的硬件配置,确保从节点能够处理主节点的写负载

2. 配置优化

  • 复制积压缓冲区:根据主节点的写入量调整 repl-backlog-size,建议设置为平均写入量的 2-3 倍
  • 无盘复制:对于网络带宽充足、磁盘 IO 紧张的场景,启用无盘复制(repl-diskless-sync yes
  • 从节点优先级:根据从节点性能设置不同的 replica-priority,确保故障转移时选择最优从节点
  • 持久化配置:主节点启用 AOF 持久化,确保数据安全;从节点可以禁用持久化或使用不同的持久化策略
  • 内存配置:主节点和从节点配置足够的内存,避免内存溢出

3. 监控与告警

  • 建立完善的监控体系:监控主从复制状态、复制延迟、网络连接等指标
  • 设置合理的告警阈值
    • 复制延迟超过 10 秒告警
    • 从节点与主节点连接断开告警
    • 主节点连接的从节点数量异常告警
  • 定期检查:定期检查主从复制状态,确保数据一致性
  • 记录日志:开启 Redis 日志,便于分析问题

4. 故障处理

  • 制定故障转移计划:提前制定手动和自动故障转移计划
  • 定期测试故障转移:模拟主节点故障,测试故障转移流程
  • 备份数据:定期备份主节点数据,确保数据安全
  • 恢复演练:定期进行数据恢复演练,确保能够快速恢复数据

5. 性能优化

  • 读写分离:将读取请求分散到从节点,减轻主节点压力
  • 连接池:使用连接池管理客户端连接,减少连接开销
  • 合理使用管道:使用管道(Pipeline)减少网络往返次数
  • 避免慢查询:在从节点避免执行慢查询,如 KEYS *SORT
  • 优化主节点写入:减少大键写入,优化数据结构

常见问题(FAQ)

Q1: 主从复制如何保证数据一致性?

A1: Redis 主从复制通过以下机制保证数据一致性:

  1. 命令传播:主节点将写命令实时发送给从节点
  2. 复制偏移量:主从节点通过复制偏移量确保数据同步进度
  3. 复制积压缓冲区:用于部分复制,确保断开连接后的数据一致性
  4. 心跳机制:监控主从节点连接状态
  5. 持久化:主节点启用持久化,确保数据不丢失

Q2: 主从复制会影响主节点性能吗?

A2: 主从复制会对主节点产生一定的性能影响:

  • CPU 开销:生成 RDB 文件、处理从节点请求
  • 内存开销:维护复制积压缓冲区、复制缓冲区
  • 网络开销:发送 RDB 文件和写命令给从节点
  • 磁盘开销:生成 RDB 文件

可以通过以下方式减少影响:

  • 合理配置从节点数量
  • 使用级联复制
  • 启用无盘复制
  • 优化网络带宽

Q3: 从节点可以有自己的从节点吗?

A3: 是的,Redis 支持级联复制,从节点可以作为其他从节点的主节点,形成链式或树状复制结构。这种方式可以减少主节点的复制压力,适用于大量从节点的场景。

Q4: 如何选择合适的从节点优先级?

A4: 从节点优先级(replica-priority)用于故障转移时选择新主节点,优先级值越小,优先级越高。选择合适的从节点优先级需要考虑:

  1. 从节点性能:性能更好的从节点优先级更高
  2. 复制延迟:复制延迟更小的从节点优先级更高
  3. 硬件配置:硬件配置更好的从节点优先级更高
  4. 网络位置:网络更稳定的从节点优先级更高

Q5: 主从复制与 Redis Cluster 有什么区别?

A5: 主从复制和 Redis Cluster 是 Redis 两种不同的高可用解决方案:

  • 主从复制

    • 适用于中小规模 Redis 部署
    • 提供数据冗余和读写分离
    • 不支持数据分片
    • 需要手动或使用 Sentinel 实现故障转移
  • Redis Cluster

    • 适用于大规模 Redis 部署
    • 提供数据分片、高可用性和自动故障转移
    • 支持水平扩展
    • 内置故障检测和自动故障转移功能

Q6: 如何监控主从复制延迟?

A6: 监控主从复制延迟的方法:

  1. 使用 INFO replication 命令:查看 lag 指标
  2. 监控复制偏移量:比较主节点和从节点的 master_repl_offsetslave_repl_offset
  3. 使用监控工具:Prometheus + Grafana、Datadog 等提供复制延迟监控
  4. 自定义脚本:编写脚本定期检查复制延迟