资讯动态

Redis哨兵模式实战:从配置到故障转移的完整指南

发布时间:2026/10/27 12:57:19 来源:尧图企业网站定制
Redis 哨兵模式这件事说简单也简单说坑多也是真的坑多。我见过太多团队在主从复制搭完之后觉得“高可用已经搞定了”结果真到主节点挂掉的那一刻发现哨兵压根没切过来或者切过来了但客户端还连着一个已经死掉的旧主。这篇文章就把我在 Linux 环境下配置 Redis 哨兵模式的完整过程拆开讲清楚从为什么需要哨兵、节点规划、配置文件逐项拆解到故障切换验证和踩过的坑全部摊开来说。适合已经会用 Redis 基本命令、但还没在生产环境真正跑过哨兵的同学也适合那些配过一遍但心里没底、想搞清楚每个参数到底在干什么的同行。1. 先想清楚哨兵到底在解决什么问题1.1 主从复制留下的那个缺口单机 Redis 的问题很直白进程一挂数据虽然在磁盘上但服务断了。于是大家都会做主从复制一个主节点负责写若干个从节点同步数据读请求可以分摊到从节点上。这套结构解决了两件事——数据有了冗余副本读性能可以横向扩展。但它留下了一个致命缺口主节点挂了之后没有人自动把从节点提升为新的主节点。你得半夜爬起来手动执行REPLICAOF NO ONE把某个从节点扶正再挨个改其他从节点和客户端的连接地址。这个过程短则几分钟长则半小时业务侧感受到的就是一段不可控的写入中断。哨兵Sentinel就是来填这个缺口的。它是一套独立的进程不存业务数据专门干三件事监控持续检查主从节点是否存活、通知某个节点出问题时通过 API 告知外界、自动故障转移主节点确认失联后选举一个从节点上位并让其余从节点改挂到新主上。客户端只要连哨兵集群而不是直连主节点就能在切换后自动拿到新主地址。这里有个概念要先厘清哨兵不是 Redis 的一个配置开关它是独立运行的进程用的是 Redis 自带的redis-sentinel可执行文件本质上和redis-server是同一个二进制只是启动时带了哨兵模式参数。很多人第一次配的时候以为在主节点配置文件里加几行就行这是最常见的误解。1.2 为什么哨兵必须部署奇数个哨兵之间靠投票来决定“主节点是不是真的挂了”以及“谁来执行切换”。这就涉及两个阈值主观下线单个哨兵自己觉得节点不通了和客观下线足够数量的哨兵都认为它不通了。客观下线的判定依赖quorum参数比如 3 个哨兵、quorum 设为 2意味着至少 2 个哨兵都报告主节点失联才认定为客观下线。而真正执行故障转移还需要选举出一个领头哨兵这个选举要求获得多数派majority的授权3 个哨兵需要 2 票5 个需要 3 票。所以哨兵数量必须是奇数且至少 3 个。2 个哨兵的集群在挂掉 1 个之后就凑不齐多数派无法完成选举4 个哨兵虽然能容忍 1 个故障但多数派是 3容错能力和 3 个一样白白多花资源。这就是“奇数部署”背后的数学逻辑不是玄学。注意哨兵节点要分散在不同的物理机或虚拟机上。如果 3 个哨兵挤在同一台机器机器一宕全部玩完等于没做高可用。这是新手最容易犯的错。1.3 一套典型的小规模部署规划假设我们有三台 Linux 服务器规划如下IP 用示例地址代替实际部署时替换成你自己的角色主机标识端口说明Redis 主节点node-a6379负责写Redis 从节点node-b6379同步主节点Redis 从节点node-c6379同步主节点哨兵 1node-a26379监控哨兵 2node-b26379监控哨兵 3node-c26379监控主从节点和哨兵混布在同一批机器上是小规模场景的常见做法哨兵进程本身资源占用很低内存几十 MB 级别不会和 Redis 抢太多资源。但要注意哨兵的默认端口是26379和 Redis 的 6379 区分开别配串了。2. 主从复制哨兵的地基必须先打牢2.1 主节点配置的关键几行哨兵的所有动作都建立在主从复制正常工作的前提上。如果主从本身就没同步好哨兵切过去也是切了个空壳。先看主节点redis.conf里必须确认的配置# 绑定地址生产环境建议绑定内网地址而非 0.0.0.0 bind 0.0.0.0 # 保护模式绑定了具体地址后可关闭否则保持 yes 并配好密码 protected-mode no # 端口 port 6379 # 后台运行 daemonize yes # 日志文件 logfile /var/log/redis/redis-6379.log # 数据目录 dir /var/lib/redis/6379 # 设置访问密码哨兵和从节点都要用 requirepass YourStrongPassword # 主节点认证密码Redis 5 之后用于主从认证 masterauth YourStrongPassword这里有个细节值得展开requirepass和masterauth为什么要设成一样requirepass是别人连我时需要的密码masterauth是我作为从节点去连主节点时用的密码。在主从切换发生后原来的从节点会变成主节点它需要用masterauth去连新的上游如果有级联同时又要用requirepass接受别人连接。两个设成一致切换后角色互换才不会出认证问题。这是很多人切换后从节点连不上新主的原因之一。2.2 从节点配置与复制的建立从节点的配置和主节点大同小异核心是加一行指向主节点# 从节点专属指定上游主节点 replicaof node-a 6379 # 只读模式防止误写到从节点 replica-read-only yes # 复制相关的密码 masterauth YourStrongPassword requirepass YourStrongPasswordreplica-read-only yes这行别省。从节点默认就是只读的但显式写出来是一种防御——万一有人图省事把它改成 no往从节点写数据会造成主从数据不一致而且这种不一致在哨兵切换后会被放大。配置改完先启动主节点再启动两个从节点然后在主节点上执行INFO replication看输出。正常应该看到role:master、connected_slaves:2以及两个从节点的ip、port、stateonline、offset信息。如果connected_slaves是 0或者从节点状态是down先别急着配哨兵把复制链路修通再说。2.3 验证复制真的在跑光看状态不够得实际写一条数据验证。在主节点执行redis-cli -a YourStrongPassword -p 6379 set smoke:test hello-sentinel然后到两个从节点上分别执行redis-cli -a YourStrongPassword -p 6379 get smoke:test两边都能读到hello-sentinel说明复制链路是通的。这一步看着简单但它是后面所有故障转移验证的基准——如果现在复制就不通切换后新主上的数据一定是残缺的。实操心得我习惯在搭哨兵之前先手动模拟一次“从节点提升”。在某个从节点上执行REPLICAOF NO ONE看它能不能独立对外服务再执行REPLICAOF node-a 6379挂回去。这个动作能提前暴露权限、网络、配置上的问题比等到真故障时才发现要强得多。3. 哨兵配置文件逐项拆解3.1 最小可用配置长什么样哨兵的配置文件通常叫sentinel.conf三个哨兵节点上的内容基本一致只有少数几项因机器而异。先给一份能直接跑起来的最小配置# 哨兵端口默认 26379 port 26379 # 后台运行 daemonize yes # 日志 logfile /var/log/redis/sentinel-26379.log # 工作目录哨兵会在这里写状态文件 dir /var/lib/redis/sentinel # 监控的主节点格式sentinel monitor 主节点名 IP 端口 quorum sentinel monitor mymaster node-a 6379 2 # 主节点和哨兵的认证密码 sentinel auth-pass mymaster YourStrongPassword # 主观下线判定时间毫秒 sentinel down-after-milliseconds mymaster 30000 # 故障转移时同时重新配置的从节点数量 sentinel parallel-syncs mymaster 1 # 故障转移超时时间 sentinel failover-timeout mymaster 180000sentinel monitor这一行是整个配置的灵魂。mymaster是给这个主节点起的逻辑名字客户端连接哨兵时要用这个名字来查询主节点地址所以三个哨兵必须用完全一致的名字。后面的2就是 quorum前面讲过3 个哨兵配 2 是合理的。3.2 那几个时间参数到底怎么定sentinel down-after-milliseconds设成 3000030 秒是很多团队的默认选择但它的取值需要结合业务容忍度来算。这个参数的意思是哨兵连续 30 秒 ping 不通主节点才把它标记为主观下线。设太短网络抖动一下就可能触发误判设太长真故障时切换延迟大。我的经验是先测一下你环境里正常的网络 RTT 和 Redis 的响应延迟把阈值设在正常延迟的几十倍以上。内网环境 RTT 通常不到 1ms30 秒已经非常宽松能过滤掉绝大多数瞬时抖动。如果业务对中断极其敏感可以压到 10 秒但要确保网络质量足够稳定。sentinel failover-timeout设 1800003 分钟控制的是故障转移各阶段的总超时包括选举、提升从节点、重新配置其他从节点等。这个值不宜太小因为切换过程中涉及多次状态同步网络慢的环境下 1 分钟可能不够。3 分钟是个比较稳妥的起点。sentinel parallel-syncs设为 1 意味着故障转移后从节点是逐个去同步新主的而不是一拥而上。这样做的原因是新主刚上任如果多个从节点同时发起全量同步新主的 IO 和网络会被打满反而拖慢整个恢复过程。设成 1 最保守恢复慢一点但稳从节点多、数据量小的场景可以适当调大。3.3 密码认证这一块别漏sentinel auth-pass mymaster YourStrongPassword这行必须和主从节点的requirepass对上。哨兵需要用它去连主节点和从节点做健康检查密码不对的话哨兵会一直报NOAUTH错误监控形同虚设。这里有个容易忽略的点如果你的 Redis 6 及以上版本用了 ACL 用户体系认证方式会变成sentinel auth-user加sentinel auth-pass的组合。老版本只有auth-pass。配置前先确认你的 Redis 版本别照抄了不匹配的配置。注意三个哨兵的配置文件里sentinel monitor指向的必须是同一个主节点地址。哨兵之间会自动发现彼此通过主节点的__sentinel__:hello频道交换信息你不需要手动配置哨兵之间的连接。这一点很多人不知道以为要像集群那样配一堆节点地址其实不用。4. 启动哨兵并验证集群状态4.1 启动顺序与启动方式推荐先启动所有 Redis 主从节点确认复制正常再依次启动三个哨兵。启动命令有两种写法# 方式一用 redis-sentinel 可执行文件 redis-sentinel /etc/redis/sentinel.conf # 方式二用 redis-server 带 --sentinel 参数 redis-server /etc/redis/sentinel.conf --sentinel两种方式等价redis-sentinel本质上就是redis-server --sentinel的软链接。我一般用第一种语义更清晰。启动后连上任意一个哨兵端口 26379执行INFO sentinel重点看这几行redis-cli -p 26379 info sentinel输出里应该有sentinel_masters:1、master0:namemymaster,statusok,addressnode-a:6379,slaves2,sentinels3。sentinels3说明三个哨兵已经互相发现集群成型了。如果这里是 1 或者 2说明哨兵之间的自动发现还没完成等几十秒再看或者检查网络和密码配置。4.2 用 SENTINEL 命令做健康检查哨兵提供了一组SENTINEL开头的命令日常运维非常有用# 查看主节点信息 redis-cli -p 26379 sentinel master mymaster # 查看所有从节点 redis-cli -p 26379 sentinel slaves mymaster # 查看其他哨兵 redis-cli -p 26379 sentinel sentinels mymaster # 查看主节点地址客户端常用 redis-cli -p 26379 sentinel get-master-addr-by-name mymastersentinel master mymaster的输出里有个flags字段正常应该是master。如果出现s_down或o_down说明哨兵认为主节点有问题得去查主节点状态。num-slaves和num-other-sentinels也要和预期对上。4.3 客户端怎么连哨兵这是配置哨兵时经常被忽略的一环客户端不能直连主节点必须通过哨兵获取主节点地址。以常见的客户端为例连接参数从“主节点 IP 端口”变成“哨兵地址列表 主节点名”。以 Java 生态里常用的客户端为例配置大致是这样伪代码示意具体类名依客户端库而定// 哨兵地址列表不是主节点地址 ListString sentinels Arrays.asList( node-a:26379, node-b:26379, node-c:26379 ); // 主节点逻辑名必须和 sentinel monitor 里的一致 String masterName mymaster; // 密码 String password YourStrongPassword;客户端连上哨兵后会订阅哨兵的切换通知频道主节点一变客户端自动重连到新主。这就是哨兵模式对客户端透明的原因。如果你的客户端还在硬编码主节点 IP那哨兵切了也白切客户端照样连旧地址。实操心得切换验证时一定要用真实客户端去测而不是只用 redis-cli 连哨兵看地址。有些客户端库对哨兵通知的处理有延迟或 bug只有真实业务流量才能暴露出来。5. 故障转移实测把主节点干掉看看5.1 模拟主节点故障配置得再漂亮不实测都是纸上谈兵。最直接的验证方式是把主节点进程杀掉# 在主节点上找到 redis 进程并终止 redis-cli -p 6379 -a YourStrongPassword shutdown nosave用shutdown nosave而不是kill -9是为了模拟一次“正常但突然”的退出。nosave表示不落盘直接退更接近真实故障场景。杀掉之后盯着哨兵的日志看/var/log/redis/sentinel-26379.log应该能看到类似这样的过程先是sdown主观下线然后odown客观下线说明凑够 quorum 了接着try-failover、elected-leader、selected-slave、promoted-slave、failover-end最后switch-master。这一串事件就是一次完整的故障转移流水账。5.2 确认切换结果等日志里出现switch-master后到任意哨兵上执行redis-cli -p 26379 sentinel get-master-addr-by-name mymaster返回的地址应该已经变成某个从节点的 IP 和端口。再到那个被提升的节点上执行INFO replication确认role:master并且另一个从节点已经挂到它下面connected_slaves:1。数据层面也要验证之前在旧主上写的smoke:test在新主上应该还能读到。如果读不到说明复制有延迟或者切换时数据没同步完这是需要警惕的信号。5.3 旧主恢复后会发生什么把原来的主节点重新启动它会以从节点的身份加入集群——哨兵会自动给它下发REPLICAOF命令让它挂到新主下面。这个过程不需要人工干预但要注意旧主重新加入时会做一次全量同步如果数据量大这段时间新主的负载会上升。验证方法重启旧主后在它上面执行INFO replicationrole应该变成slavemaster_host指向新主。如果它还是master说明哨兵的自动重配置没生效去查哨兵日志里有没有convert-to-slave相关记录。阶段哨兵日志事件预期状态主节点失联sdown单哨兵标记主观下线达到 quorumodown多哨兵确认客观下线选举领头elected-leader选出执行切换的哨兵提升从节点promoted-slave某从节点变主切换完成switch-master全局主节点地址更新旧主回归convert-to-slave旧主降级为从6. 踩过的坑与排查速查表6.1 切换后客户端连不上新主这是最高频的问题。原因通常有两个一是客户端没配哨兵还在硬编码旧主地址二是新主的requirepass和客户端配置的密码不一致。排查时先确认客户端连接的是哨兵地址而非主节点地址再用sentinel get-master-addr-by-name拿到新主地址手动用客户端密码连一下新主能连上就说明是客户端配置问题。还有一种隐蔽情况切换后新主的protected-mode是 yes 且没绑定具体地址导致外部连不上。检查新主的bind和protected-mode配置确保和切换前一致。6.2 哨兵之间互相发现不了INFO sentinel里sentinels数量少于预期说明哨兵没组成集群。常见原因三个哨兵的sentinel monitor里主节点名不一致比如一个写mymaster一个写master1或者主节点密码配错导致哨兵连不上主节点、无法通过__sentinel__:hello频道交换信息。逐个检查配置文件的sentinel monitor行和auth-pass基本能定位。6.3 频繁误切换如果日志里反复出现sdown又-sdown说明down-after-milliseconds设得太短或者网络本身不稳定。先把阈值调大观察同时排查网络层是否有丢包。另外主节点如果因为执行了耗时的BGSAVE或大 key 操作导致短暂无响应也可能被误判这种情况要结合慢查询日志一起看。6.4 故障转移卡住不完成日志停在try-failover之后没有下文通常是failover-timeout太短或者被选中的从节点数据太旧、同步太慢。可以适当调大failover-timeout并检查从节点的master_link_status是否为up。如果某个从节点长期同步不上哨兵可能选它做新主却提升失败考虑把它从集群里摘掉。现象可能原因排查动作客户端连不上新主未配哨兵/密码不符/保护模式查客户端配置、手动连新主哨兵数量不足主节点名不一致/认证失败核对 monitor 行和密码频繁误切换超时阈值过短/网络抖动调大 down-after-milliseconds切换卡住超时太短/从节点数据旧调大 failover-timeout、查同步状态旧主不降级哨兵重配置失败查 convert-to-slave 日志6.5 一个容易被忽视的细节状态文件哨兵运行时会往dir指定的目录写一个sentinel.conf的运行时状态配置会被哨兵自己改写记录当前主节点是谁、有哪些从节点和哨兵。这意味着你手动改的配置文件在运行中可能被覆盖。所以改配置前先停哨兵改完再启动或者用SENTINEL SET命令在运行时动态调整参数避免直接编辑文件被覆盖。这个坑我在早期项目里踩过改完配置重启发现改动没了排查半天才反应过来是哨兵自己重写了文件。7. 生产环境还要补的几件事7.1 哨兵进程的守护与开机自启哨兵进程挂了监控就断了所以必须用系统级的进程管理来守护。常见的做法是写一个 systemd 服务单元配置Restartalways让进程异常退出后自动拉起。三个哨兵节点都要配别只配一个。开机自启也一并加上避免机器重启后哨兵没起来、集群处于“无监控”状态。7.2 监控告警要覆盖哨兵本身很多人只监控 Redis 主从忘了监控哨兵。哨兵的关键指标包括sentinel_masters数量、各主节点的flags状态、sentinels数量是否达标。一旦某个哨兵的sentinels数量掉下来说明集群完整性受损要立即告警。另外哨兵日志里的switch-master事件应该触发通知让团队知道发生了一次切换便于事后复盘。7.3 数据一致性的边界要心里有数哨兵模式用的是异步复制主节点写入后不等从节点确认就返回成功。这意味着故障转移时如果旧主上有少量数据还没同步到从节点这部分数据会丢失。哨兵能保证服务可用性但保证不了零数据丢失。对数据一致性要求极高的场景需要评估是否接受这个边界或者在上层做补偿。这一点在方案评审时一定要说清楚别让业务方误以为哨兵等于数据不丢。7.4 定期演练切换配置好不等于永远好用。网络拓扑变了、机器换了、密码改了都可能让哨兵失效。我建议至少每季度做一次故障转移演练用SENTINEL FAILOVER mymaster命令手动触发一次切换这个命令会强制发起故障转移不需要真的杀进程验证整个链路是否还能正常工作。演练完记得确认旧主正确降级、客户端正常重连。# 手动触发一次故障转移用于演练 redis-cli -p 26379 sentinel failover mymaster这个命令比杀进程温和适合在业务低峰期做例行检查。执行后同样观察日志里的switch-master事件确认切换成功。我个人在实际操作中的体会是哨兵模式的配置本身并不复杂真正花时间的是验证和边界确认——把切换流程跑通、把客户端改造到位、把数据丢失的边界和业务方对齐。配置文件抄一遍十分钟但这些验证工作可能要花上一两天。别跳过验证直接上生产哨兵这东西平时安安静静出事的时候才知道配得对不对。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑