Redis 是内存数据库,速度极快但也最怕单点:进程崩溃、机器宕机或内存写满,缓存层一挂,后面的数据库就被瞬时流量打垮。解决思路和其他组件一样,用多台 Redis 组成集群。但 Redis 的高可用方案不止一种,主从复制只解决数据冗余,哨兵模式在此之上加了自动故障转移,Cluster 分片则进一步解决容量和写扩展。很多人分不清这三者的边界,要么用了主从却指望它自动切换,要么一上来就上 Cluster,把小业务做复杂了。
这篇文章把 Redis 主从复制和哨兵模式讲清楚:各自解决什么问题,replicaof 怎么配,sentinel.conf 里的 monitor 和 quorum 是什么意思,主观下线(SDOWN)和客观下线(ODOWN)如何判定,故障转移是怎么完成的,客户端怎么感知新主。最后给出主从、哨兵、Cluster 的选型对比表,帮你在不同规模下做出合适的选择。命令与配置均可在真实环境使用。
主从复制解决的是什么
Redis 主从复制(replication)把一台节点的数据实时同步到其他节点。主节点(master)负责读写,从节点(replica)默认只读,通过复制主节点的数据保持一份或多份副本。它的直接价值有两个:一是数据冗余,主节点磁盘或进程出问题时,从节点上还有数据;二是读扩展,可以把读请求分摊到多个从节点,减轻主节点压力。
配置主从最简单的方式是在从节点的配置文件里加一行 replicaof:
# 从节点 redis.conf
replicaof 192.0.2.41 6379
masterauth REPLACE_WITH_STRONG_PASSWORD
replica-read-only yes
replicaof 指定主节点的 IP 和端口,masterauth 是主节点要求认证时的密码,replica-read-only yes 让从节点只读。旧版本用的是 slaveof,5.0 之后统一改成 replicaof,两者目前都还兼容。也可以运行时动态设置:
# 在从节点执行,使其成为 192.0.2.41:6379 的从节点
redis-cli -h 192.0.2.42 -p 6379 REPLICAOF 192.0.2.41 6379
# 取消复制,恢复为独立主节点
redis-cli -h 192.0.2.42 -p 6379 REPLICAOF NO ONE
复制过程分两步:首次连接时主节点做一次全量同步,生成 RDB 快照发给从节点;之后进入增量同步,主节点把后续写命令通过复制流发给从节点。如果网络短暂中断又在允许范围内重连,可以走部分重同步,避免每次都全量,这依赖主节点的复制积压缓冲区(repl-backlog)。
关键点在于:主从复制本身没有故障检测,也没有自动切换。主节点挂了,从节点不会自动顶上,需要人工或用其他工具介入。所以只配主从的生产环境,只能算"有副本",不能算"高可用"。
哨兵模式解决的是什么
哨兵(Sentinel)是 Redis 官方提供的高可用组件。它独立于数据节点运行,通常部署奇数个(3 个、5 个)组成哨兵集群,持续监控 Redis 主从节点,在主节点故障时自动完成故障转移,把某个从节点提升为新主,并让其他从节点跟随新主。
哨兵的配置文件是 sentinel.conf,最核心的是 sentinel monitor:
# sentinel.conf 示例(三台哨兵内容基本一致)
port 26379
sentinel monitor mymaster 192.0.2.41 6379 2
sentinel auth-pass mymaster REPLACE_WITH_STRONG_PASSWORD
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
逐项解释。sentinel monitor mymaster 192.0.2.41 6379 2 里的 mymaster 是这套主从的集群名,可以自定义;后面是主节点地址和端口;最后的 2 是 quorum,表示至少要有 2 个哨兵认为主节点挂了,才触发客观下线和故障转移。auth-pass 是访问 Redis 的认证密码。down-after-milliseconds 是判定主观下线的超时,这里设 5 秒。failover-timeout 是故障转移的超时。parallel-syncs 控制故障转移后同时向新主同步的从节点数量,数值小可减少主节点压力。
启动哨兵并查看状态:
redis-sentinel /etc/redis/sentinel.conf
# 或
redis-server /etc/redis/sentinel.conf --sentinel
用 redis-cli 连接哨兵端口查看信息:
redis-cli -p 26379 SENTINEL master mymaster
redis-cli -p 26379 SENTINEL replicas mymaster
redis-cli -p 26379 SENTINEL sentinels mymaster
哨兵之间也会互相发现,通过发布订阅频道交换信息,组成一个自治的监控网络。要特别注意:哨兵配置文件在运行时会自动被改写,加入发现的其他哨兵、从节点和故障转移后的新主信息,所以不能用版本管理工具频繁覆盖它。
主观下线与客观下线
理解 SDOWN 和 ODOWN 是理解哨兵的关键。
主观下线(Subjectively Down,SDOWN)指单个哨兵根据自己的判断,认为某个节点已经不可达。判定依据是:哨兵向节点发送 PING,如果在 down-after-milliseconds 时间内没有收到有效回复,就把它标记为主观下线。注意这是"单个哨兵的看法",可能是它自己的网络抖动导致的误判。
客观下线(Objectively Down,ODOWN)指多数哨兵达成一致,认为主节点确实挂了。当某个哨兵把主节点标记为 SDOWN 后,它会询问其他哨兵:"你们看主节点是不是也挂了?"如果认为挂了的哨兵数量达到 quorum(上面配置里的 2),就升级为客观下线,进入故障转移流程。
这个设计的意义在于避免单点误判。单个哨兵网络抖动不会引发切换,只有多数哨兵都确认,才启动切换。所以 quorum 的设置要和哨兵数量匹配:3 个哨兵时 quorum 设为 2 比较合理,5 个时设为 3。quorum 过大可能导致故障时无法达成一致,过小则容易误切换。另外,触发故障转移还需要多数哨兵选举出一个 Leader,所以哨兵数量最好是奇数,并且至少 3 个,2 个哨兵反而更容易脑裂。
故障转移是怎么完成的
当主节点被判定为客观下线后,哨兵集群开始选举 Leader。每个哨兵都可以请求成为 Leader,先获得多数票的当选。Leader 负责执行故障转移,过程大致是:从所有从节点里挑选一个最合适的新主(考虑复制偏移量、优先级、运行时间等),对它执行 REPLICAOF NO ONE 提升为主;把其余从节点重新指向新主;更新自己的配置;通过发布订阅通知客户端新的主节点地址。
故障转移完成后,原来故障的主节点如果恢复,会被哨兵改成从节点,跟随新主,避免出现双主。
客户端如何感知新主?这是哨兵模式里容易被忽略的一环。普通客户端如果直接连主节点 IP,切换后就断了。正确做法是客户端通过哨兵的 API 先查询当前主节点地址,再连接主节点。大多数语言的 Redis 客户端库都支持传入哨兵列表,由客户端库自己完成"问哨兵、连新主、断线重连"。所以应用不要写死 Redis 地址,而要配置哨兵地址列表。
# 客户端可先用哨兵查询当前主节点
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
主从、哨兵与 Cluster 的选型
三者是递进关系,不是互相替代。主从解决冗余,哨兵解决自动切换,Cluster 解决分片和高并发写。选型时主要看数据量、写入压力和对自动化的要求。
| 方案 | 数据冗余 | 自动故障转移 | 水平扩展 | 写扩展 | 复杂度 | 适用规模 |
|---|---|---|---|---|---|---|
| 主从复制 | 有 | 无(需人工/外部工具) | 读可扩展 | 不支持 | 低 | 小规模、读多写少 |
| 哨兵模式 | 有 | 有 | 读可扩展 | 不支持 | 中 | 中等规模、要求自动切换 |
| Cluster 分片 | 有 | 有 | 数据分片 | 支持 | 高 | 大数据量、高并发写 |
具体建议:数据量小、只想要一份副本做备份和读扩展,用主从就够;要求主节点故障后自动恢复且业务不能长时间中断,上哨兵;单机内存放不下全量数据,或者写入并发非常高、需要多个主节点分担,才考虑 Cluster。很多中小业务用"一主两从加三哨兵"就能稳定运行很久,没必要一上来就 Cluster。
还要注意一个易混点:Cluster 是分片集群,每个分片内部也可以有主从复制,它的故障转移是 Cluster 自己实现的,不需要哨兵。所以"哨兵 + 主从"和"Cluster"是两条不同的技术路线,不要混用。
部署与运维注意事项
第一,持久化和复制要一起考虑。从节点也要开启 RDB 或 AOF,否则重启后可能因为全量同步失败而无法提供数据。主节点关闭持久化再配复制是危险的,主进程重启后可能数据为空,进而把空数据同步给从节点。
第二,密码与访问控制要统一。主节点设了 requirepass,从节点就要配 masterauth,哨兵要配 sentinel auth-pass,任何一处漏配都会导致复制或监控失败。
第三,防火墙要放行 Redis 端口 6379 和哨兵端口 26379。RHEL/CentOS/Rocky 系用 firewalld,仅允许内网地址:
# RHEL / CentOS / Rocky 系
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.0.2.0/24" port protocol="tcp" port="6379" accept'
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.0.2.0/24" port protocol="tcp" port="26379" accept'
sudo firewall-cmd --reload
风险提示: Redis 默认无认证且监听所有地址,绝不能把 6379 暴露到公网,历史上大量入侵事件都是未授权访问导致的。务必设置强密码、绑定内网地址或做访问控制。
第四,哨兵和主从都只是缓存层高可用,数据最终要能回源到持久化存储。不要把 Redis 当成唯一数据源,尤其是未开启持久化时。
常见问题
只配主从,主节点挂了会怎样?
不会自动切换。从节点仍在运行,但需要人工把某个从节点提升为主(REPLICAOF NO ONE)并修改客户端配置,业务会有较长中断。
哨兵需要几个节点?
至少 3 个,且用奇数个。2 个哨兵在两个都正常时可能因为网络分区各自认为对方挂了,反而容易脑裂出问题。
quorum 应该设多少?
quorum 是判定客观下线所需的哨兵票数。3 个哨兵建议设 2,5 个建议设 3,即"多数"。设得太高会导致故障时无法达成一致。
哨兵会自动修改配置吗?
会。哨兵运行时会把发现的其他哨兵、从节点和故障转移后的新主信息写回配置文件。所以不要频繁用固定模板覆盖 sentinel.conf,否则可能丢失状态。
Cluster 能替代哨兵吗?
不能简单替代。Cluster 解决的是数据分片和写扩展,哨兵解决的是主从的自动切换。如果不需要分片,用哨兵更简单;如果需要分片,则直接用 Cluster,它自带故障转移。
总结
- 主从复制只提供数据冗余和读扩展,没有自动故障转移,主节点故障需要人工或外部工具处理。
- 哨兵在主从之上加了监控和自动切换,核心是 monitor 里的主节点地址与 quorum,以及 SDOWN 到 ODOWN 的判定。
- 故障转移由哨兵选举 Leader 执行,完成选主、切换、通知客户端;客户端必须通过哨兵地址查询当前主,不能写死。
- 哨兵至少部署 3 个且为奇数,quorum 取多数,避免误判和脑裂;配置文件运行时会自动改写。
- 选型按需求递进:小规模用主从,要自动切换用哨兵,要分片和写扩展才用 Cluster,并且始终做好持久化与访问控制。
企业QQ咨询




