前言:

        在上一篇文章中,我们介绍了 Redis 的安全管控、性能压测与持久化分析。然而,单机 Redis 始终面临一个致命问题:单点故障。一旦 Redis 服务器宕机,所有依赖它的业务都将中断。本文将系统介绍 Redis 高可用架构的三大核心方案——主从复制哨兵模式Redis Cluster 集群,涵盖从基础的数据冗余到自动故障转移,再到分布式数据分片与水平扩展的完整演进路径。

一、主从复制:高可用的基础

1.1 什么是主从复制

        主从复制(Master-Slave Replication)是指将一台 Redis 服务器的数据复制到其他 Redis 服务器。其中,前者称为主节点(Master),负责处理所有写操作;后者称为从节点(Slave/Replica),实时同步主节点数据,并可分担读请求。数据的复制是单向的,只能由主节点复制到从节点。

主从复制主要实现三大目标:

  • 数据冗余备份:主节点数据在从节点上有多份副本

  • 读写分离:读操作可分散到多个从节点,提升性能

  • 高可用基础:主节点故障时,从节点可接管服务

1.2 主从复制的工作流程

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

第一阶段:建立连接(准备阶段)
        从节点向主节点发送 PSYNC 命令,建立复制连接。

第二阶段:全量同步

  1. 从服务器发送 PSYNC ? -1 命令

  2. 主服务器执行 BGSAVE 生成 RDB 文件

  3. 主服务器将 RDB 文件发送给从服务器

  4. 从服务器清空数据库并载入 RDB 文件

  5. 主服务器将复制积压缓冲区的命令发送给从服务器

触发全量同步的三种情况:首次连接、复制 ID 不匹配、偏移量不在积压缓冲区范围内。

第三阶段:增量同步(命令传播)
        如果偏移量在积压缓冲区范围内,主服务器发送 +CONTINUE 响应,随后发送积压缓冲区中的增量命令。增量同步的优势在于减少网络传输、降低主服务器负载、缩短同步时间。

1.3 主从复制配置步骤

准备工作:确保主节点和从节点都已安装 Redis,且网络互通。

配置主节点redis.conf):

conf

bind 0.0.0.0          # 绑定 IP,确保从节点可连接
port 6379             # 监听端口
requirepass your_password  # 可选:设置密码

配置从节点redis.conf):

conf

bind 0.0.0.0
port 6380
slaveof master_ip master_port  # 指定主节点
masterauth your_password       # 主节点有密码则需配置

建立主从连接的三种方式

  1. 客户端命令:SLAVEOF <masterip> <masterport>

  2. 启动参数:redis-server --slaveof <masterip> <masterport>

  3. 配置文件:在 redis.conf 中写入 slaveof <masterip> <masterport>

启动并验证

bash

# 启动主节点
redis-server /path/to/master/redis.conf
# 启动从节点
redis-server /path/to/slave/redis.conf

# 在主节点查看复制状态
redis-cli info replication
# 输出应显示: role:master, connected_slaves:1

# 在从节点查看复制状态
redis-cli info replication
# 输出应显示: role:slave, master_link_status:up

1.4 主从复制的优缺点

优点 局限
简单易实现,成本低 故障切换需人工干预
读写分离,扩展读性能 写性能无法扩展
数据冗余备份 存在主从延迟

        主从复制解决了数据冗余读扩展的问题,但写操作仍然集中在主节点,且主节点故障时需要人工介入才能恢复服务。哨兵模式正是为解决这一问题而生。

二、哨兵模式:自动故障转移

2.1 为什么需要哨兵

在主从复制架构中,所有写操作都依赖主节点。如果主节点宕机,将无法执行任何写操作,只能通过人工重启或手动切换主节点来恢复服务。哨兵(Sentinel)机制的出现,正是为了实现主从节点的自动故障转移

2.2 哨兵的核心功能

哨兵是一个独立的 Redis 服务器进程,主要提供三大功能:

  1. 节点监控:持续监控主节点和从节点的健康状态

  2. 自动故障转移:主节点不可用时,自动选举新主节点

  3. 通知:在实例发生故障或恢复时,向管理系统发送通知

2.3 哨兵的工作原理

(1)主观下线与客观下线

哨兵每秒向主从节点发送 PING 命令。如果服务器正常,会返回有效回复(+PONG-LOADING-MASTERDOWN 等)。

  • 主观下线(SDOWN) :单个哨兵在指定时间内未收到有效回复,将该节点标记为主观下线

  • 客观下线(ODOWN) :当主节点被标记为主观下线后,哨兵会向其他哨兵发起投票。当投票数达到预设的 quorum 值时,主节点被标记为客观下线

quorum 一般设置为哨兵个数的一半加 1(例如 3 个哨兵设为 2)。

为什么哨兵也要集群? 哨兵本身也需要避免单点故障。多个哨兵节点同时监控 Redis 主从架构,通过协商机制避免误判。

(2)领导者选举与故障转移

客观下线确认后:

  1. 哨兵们通过选举产生一个领导哨兵(Leader Sentinel)

  2. 领导哨兵从所有健康的从节点中选举一个新的主节点

  3. 执行主从切换:新主节点上线,其他从节点指向新主节点

选举算法基于 Raft 协议的变种,确保在分布式环境下达成共识。

2.4 哨兵配置步骤

第一步:配置哨兵节点sentinel.conf

conf

# 监控主节点:<master-name> <ip> <port> <quorum>
sentinel monitor mymaster 192.168.1.100 6379 2

# 连接超时时间(毫秒),默认30秒
sentinel down-after-milliseconds mymaster 30000

# 故障转移超时时间(毫秒),默认180秒
sentinel failover-timeout mymaster 180000

# 允许同时同步的从节点数量
sentinel parallel-syncs mymaster 1

# 如果主节点有密码
sentinel auth-pass mymaster your_password

# 关闭保护模式
protected-mode no

第二步:启动哨兵

bash

redis-sentinel /path/to/sentinel.conf
# 或
redis-server /path/to/sentinel.conf --sentinel

第三步:验证哨兵状态

bash

# 列出所有监控的主服务器
redis-cli -p 26379 SENTINEL masters

# 获取指定集群的从节点
redis-cli -p 26379 SENTINEL slaves mymaster

# 获取当前主节点地址
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

# 手动触发故障转移
redis-cli -p 26379 SENTINEL failover mymaster

2.5 哨兵模式的优缺点

优点 缺点
实现主从自动故障转移 写操作仍集中在主节点,写性能瓶颈未解决
哨兵集群避免单点故障 系统复杂性增加
客户端可自动获取新主节点地址 数据存储能力受限于单节点内存

当数据量持续增长、单节点内存无法满足需求时,就需要Redis Cluster 集群来解决海量数据存储与高并发写入的问题。

三、Redis Cluster 集群:分布式数据分片

3.1 为什么需要集群

        主从复制和哨兵模式解决了高可用问题,但写性能存储容量仍然受限于单节点。Redis Cluster 集群通过数据分片(Sharding) 将数据分散存储到多个节点上,实现:

  • 水平扩展:支持 TB 级数据存储和高并发访问

  • 自动故障转移:数据多副本存储,节点故障自动切换

  • 去中心化:无单点故障,节点自治

3.2 集群核心概念:哈希槽(Hash Slot)

        Redis Cluster 采用 16384 个逻辑槽位(Slot) 进行数据分片。每个键值对通过 CRC16(key) % 16384 算法计算所属槽位,并存储在对应的主节点上。

槽位分配示例(3 主 3 从集群):

主节点 槽位范围 槽位数
Master 1 0 - 5460 5461
Master 2 5461 - 10922 5462
Master 3 10923 - 16383 5461

每个主节点至少有一个从节点作为备份,当主节点故障时,从节点自动晋升。

3.3 集群搭建步骤

环境规划(以 3 主 3 从为例):

节点 IP 端口 角色
节点 1 192.168.1.101 7000 Master
节点 2 192.168.1.101 7001 Master
节点 3 192.168.1.101 7002 Master
节点 4 192.168.1.101 7003 Slave
节点 5 192.168.1.101 7004 Slave
节点 6 192.168.1.101 7005 Slave

第一步:配置每个节点redis-7000.conf

conf

port 7000
cluster-enabled yes
cluster-config-file nodes-7000.conf
cluster-node-timeout 5000
appendonly yes
requirepass yourpassword
masterauth yourpassword

注意cluster-node-timeout 控制故障检测灵敏度,默认 15 秒。生产环境建议每个主节点至少配备 1 个从节点。

第二步:启动所有节点

bash

redis-server /path/to/redis-7000.conf
redis-server /path/to/redis-7001.conf
# ... 依次启动所有节点

第三步:创建集群(Redis 5.0+ 使用 redis-cli 替代 redis-trib.rb

bash

redis-cli --cluster create \
  192.168.1.101:7000 \
  192.168.1.101:7001 \
  192.168.1.101:7002 \
  192.168.1.101:7003 \
  192.168.1.101:7004 \
  192.168.1.101:7005 \
  --cluster-replicas 1 \
  -a yourpassword

--cluster-replicas 1 表示为每个主节点分配 1 个从节点。

第四步:验证集群状态

bash

# 查看集群信息
redis-cli -c -h 192.168.1.101 -p 7000 -a yourpassword CLUSTER INFO

# 查看节点列表
redis-cli -c -h 192.168.1.101 -p 7000 -a yourpassword CLUSTER NODES

# 检查集群健康
redis-cli --cluster check 192.168.1.101:7000 -a yourpassword

3.4 集群高可用与故障切换

故障检测机制

  1. 节点间通信:集群内节点通过 Gossip 协议 定期交换状态信息

  2. 故障标记(PFAIL) :当节点 A 连续 5 次未收到节点 B 的 PING 响应时,将 B 标记为可能故障(PFAIL) 

  3. 故障确认(FAIL) :当半数以上主节点确认某节点为 PFAIL 时,升级为 FAIL 状态

  4. 自动选举:从故障主节点的从节点中选举新主节点(基于 Raft 协议变种)

  5. 槽位重新映射:集群元数据更新,将故障主节点的槽位分配给新主节点

故障切换时间:单分片主节点故障时,备节点通常在 15 秒到 30 秒 内完成主备切换。

运维建议

  • 配置 cluster-node-timeout 控制故障检测灵敏度

  • 保持每个主节点至少 1 个从节点

  • 定期执行 redis-cli --cluster check 验证集群健康状态

四、集群节点管理:增加与删除节点

Redis Cluster 支持在线动态扩缩容,在不中断服务的情况下增加或删除节点。

4.1 增加节点(集群扩容)

场景:业务增长,需要扩展集群的存储和读写能力。

步骤一:启动新节点

bash

# 配置文件 redis-7006.conf
port 7006
cluster-enabled yes
cluster-config-file nodes-7006.conf
cluster-node-timeout 5000
requirepass yourpassword
masterauth yourpassword

# 启动
redis-server /path/to/redis-7006.conf

步骤二:将新节点加入集群

bash

redis-cli --cluster add-node 192.168.1.101:7006 192.168.1.101:7000 -a yourpassword

此时新节点已加入集群,但不承载任何槽位,处于“待分配”状态。

步骤三:迁移槽位(数据重分布) 

bash

# 从现有节点迁移槽位到新节点
redis-cli --cluster reshard 192.168.1.101:7000 \
  --cluster-from <source_node_id> \
  --cluster-to <new_node_id> \
  --cluster-slots <number_of_slots> \
  --cluster-yes \
  -a yourpassword

槽位分配策略

  • 均匀分配:将现有槽位平均分配到所有节点

  • 按需分配:根据业务访问模式,手动指定槽位范围

迁移过程是平滑的,迁移期间访问被迁移的 Key 会被 ASK 临时转发,业务基本无感知。

步骤四:添加从节点(可选) 

bash

redis-cli --cluster add-node 192.168.1.101:7007 192.168.1.101:7000 \
  --cluster-slave \
  --cluster-master-id <new_master_id> \
  -a yourpassword

扩容最佳实践

  • 选择业务低峰期执行扩容操作

  • 每次迁移槽位数量控制在总量的 10% 以内

  • 迁移前备份数据

  • 迁移过程中监控 redis-cli --cluster check 输出

4.2 删除节点(集群缩容)

场景:业务缩减或节点需要下线维护。

步骤一:迁移槽位(仅针对主节点) 

如果待删除的是主节点,需要先将该节点上的所有槽位迁移到其他主节点:

bash

# 将槽位从待删除节点迁移到其他节点
redis-cli --cluster reshard 192.168.1.101:7000 \
  --cluster-from <node_to_remove_id> \
  --cluster-to <target_node_id> \
  --cluster-slots <all_slots> \
  --cluster-yes \
  -a yourpassword

步骤二:删除节点

bash

# 删除节点(主节点需先完成槽位迁移)
redis-cli --cluster del-node 192.168.1.101:7000 <node_id> -a yourpassword

步骤三:集群广播(自动完成)

删除节点后,集群会通过 Gossip 协议向所有节点广播该节点已下线,其他节点从节点表中移除该节点。

缩容注意事项

  • 若主节点上有槽位,必须先迁移槽位再删除

  • 建议先删除从节点,再删除主节点

  • 删除前确认集群有足够的容量承载被删除节点的数据

五、三种架构方案对比

维度 主从复制 哨兵模式 Redis Cluster
数据分片 ❌ 无 ❌ 无 ✅ 16384 槽位
自动故障转移 ❌ 人工干预 ✅ 哨兵自动切换 ✅ 集群内置
水平扩展 ❌ 受限于单机 ❌ 受限于单机 ✅ 在线扩缩容
读写分离 ✅ 支持 ✅ 支持 ✅ 支持
写性能 受限于单机 受限于单机 随节点增加线性扩展
存储容量 受限于单机内存 受限于单机内存 随节点增加线性扩展
复杂度
适用场景 数据量小、读多写少 数据量小、高可用要求高 海量数据、高并发读写

三者是 “基础→增强→扩展” 的递进关系:

  • 主从复制是基础,解决数据冗余和读扩展

  • 哨兵模式在主从之上增强,解决自动故障转移

  • Redis Cluster 进一步扩展,解决海量数据存储和写性能瓶颈

总结

本文系统介绍了 Redis 高可用架构的三大核心方案:

  1. 主从复制:通过一主多从架构实现数据冗余和读写分离,配置简单,是 Redis 高可用的基础。但故障切换需要人工干预,写性能受限于单节点。

  2. 哨兵模式:在主从复制基础上引入哨兵集群,实现主节点自动故障检测与转移。通过主观下线、客观下线和 Raft 选举机制,确保在主节点宕机时服务自动恢复。但存储和写能力仍受限于单节点。

  3. Redis Cluster 集群:通过 16384 个哈希槽实现数据分片,支持水平扩展在线扩缩容。集群内置故障检测与自动恢复机制,适合海量数据和高并发场景。

在实际生产环境中,架构选择应基于业务需求:

  • 数据量小、读多写少 → 主从复制

  • 数据量小、高可用要求高 → 哨兵模式

  • 海量数据、高并发读写 → Redis Cluster

        建议将故障演练纳入常态化运维流程,定期验证自动故障转移机制的有效性,确保在高可用架构真正面临故障时能够平稳切换。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐