Redis哨兵(Sentinel)体系里有两个绕不开的概念:SDOWN和ODOWN,也就是常说主观下线和客观下线。不少运维人员在排查主从切换问题时,看到日志里出现+sdown和+odown字样却搞不清楚两者先后关系和触发条件,结果配置调了半天也没调到点子上。要真正掌握Redis的高可用故障转移,必须先把这两个状态的理解打通。

一、什么是SDOWN主观下线
SDOWN的全称是Subjectively Down,翻译过来就是主观下线。它是指单个哨兵实例根据自己的探测结果,独立判定某个Redis节点不可用。哨兵默认每隔1秒会向所有已知节点(包括主节点、从节点和其他哨兵)发送PING命令,如果在配置项down-after-milliseconds指定的时间内没有收到有效回复(有效回复包括+PONG、-LOADING、-MASTERDOWN这三种),这个哨兵就会把对应节点标记为SDOWN状态。
注意这里的判定是完全“单方面”的,不与其他任何哨兵商量。哪怕网络只是这一台哨兵与Redis之间出了抖动,其他哨兵都通信正常,这台哨兵依然会单方面认为主节点下线了。这也是为什么它叫“主观”下线——判断结果只代表一个哨兵的视角,可能与真实情况不符。
在哨兵配置文件中,这个参数的写法如下:
# sentinel monitor <master-name> <ip> <port> <quorum> sentinel monitor mymaster 192.168.1.10 6379 2 # 超过30秒无有效回复则判定为主观下线 sentinel down-after-milliseconds mymaster 30000
当SDOWN发生时,哨兵日志中会出现类似+sdown master mymaster 192.168.1.10 6379的记录。需要强调的是,单纯进入SDOWN状态并不会触发故障转移,它只是一个前置信号,为后续的ODOWN判定和 Leader选举做准备。另外,SDOWN状态不是持久的:如果之后PING恢复了正常回复,节点会被重新标记为在线,日志中会出现-sdown表示主观下线状态被移除。
二、什么是ODOWN客观下线
ODOWN的全称是Objectively Down,即客观下线。既然单个哨兵的判断可能出错,那就需要引入“多数派”机制来修正。具体流程是:当某个哨兵认定主节点进入SDOWN后,它会询问其他哨兵:“你们觉得这个主节点下线了吗?”其他收到询问的哨兵会回复自己视角下该主节点的状态,这里的有效判定只有SDOWN或非SDOWN两种。
如果收集到的SDOWN判定数量达到配置中quorum参数指定的值,发起询问的哨兵就会把主节点标记为ODOWN,日志输出类似+odown master mymaster 192.168.1.10 6379 #quorum 2/2。举个例子,部署了3个哨兵、quorum配置为2,那么只要有2个哨兵都独立判定主节点SDOWN,客观下线就成立了。
这里有几个容易忽略的细节值得展开说明:
- ODOWN只针对主节点。从节点和哨兵自身只有SDOWN概念,不会走客观下线流程,因为从节点故障不需要投票选举,直接从可用从节点列表中剔除即可。
- quorum只负责判定ODOWN,不负责选举。很多文章把quorum说成故障转移的投票数,这是不准确的。真正执行故障转移时,需要哨兵候选Leader获得 majority票数(即超过半数,例如3个哨兵需要2票,5个需要3票),这与quorum是两个独立的数值。
- quorum可以大于哨兵总数的一半。比如5个哨兵配quorum为5,意味着判定ODOWN更严格,但即使ODOWN成立,故障转移仍需拿到至少3票majority才能执行。
当ODOWN成立后,哨兵集群会先通过Raft-like的选举流程选出执行故障转移的Leader哨兵,由它挑选最优从节点提升为新主,再通知其他从节点复制新主、更新客户端连接。整套链路环环相扣,ODOWN正是从“怀疑”走向“行动”的分水岭。
三、配置取值与常见误判场景
down-after-milliseconds的取值直接影响故障发现的灵敏度。设得太小(比如几百毫秒),网络稍有抖动或主节点在做RDB持久化导致回复变慢,就会频繁出现误判;设得太大(比如几分钟),真实故障的切换时间又会拉长,影响业务可用性。生产环境一般建议5000到30000毫秒之间,结合自身网络质量和业务容忍度来定。
quorum的取值同样讲究。哨兵官方推荐至少部署3个实例且分布在不同的机器或机房。如果哨兵总数是3,quorum通常配2;如果追求更保守的判定,也可以配3,但要意识到quorum等于哨兵总数时,任何一个哨兵挂掉都可能导致无法达成客观下线。反过来,如果把quorum配成1,只要一个哨兵主观判定下线就能进入ODOWN,误切换风险会明显升高,一般不建议。
还有一个经典误判场景:哨兵与Redis主节点之间的网络分区。假设3个哨兵中有1台与主节点之间链路异常,它会持续输出+odown尝试,但另外2个哨兵视角正常,SDOWN数量达不到quorum,ODOWN不成立,主节点继续服务,这正是客观下线机制要达到的效果——用多数派视角抵御单点误判。反之,如果客户端与主节点整体断连,但哨兵们都能正常探测到主节点,就不会触发任何下线判定,这也是排查“客户端连不上但哨兵不切换”问题时的重要思路。
日常运维中可以通过命令观察判定过程:
# 查看主节点状态,flags中带有s_down、o_down标记 redis-cli -p 26379 sentinel master mymaster # 查看其他哨兵对该主节点的判定 redis-cli -p 26379 SENTINEL sentinels mymaster
在sentinel master的输出里,flags字段如果包含s_down说明主观下线,包含o_down说明客观下线,配合日志时间线排查故障转移慢、误切换等问题非常直观。
总结一下:SDOWN是单个哨兵基于超时探测的独立判断,ODOWN是达到quorum数量的哨兵形成的集体共识,前者是后者的前提,后者才是故障转移的触发条件。理解了这条链路,再去调down-after-milliseconds和quorum,就知道每一项配置分别卡在哪一环,排查哨兵问题也就有了清晰的抓手。