知识卡片
高可用状态决策的三种方式及其固有缺陷
内容
无论是计算高可用还是存储高可用,都要先解决同一个基础问题:系统怎么判断当前状态是正常还是异常,判断错了,后面的任何补救行动都没有意义。但这里存在一个本质矛盾:恰恰是靠冗余实现的高可用系统,状态决策本身不可能做到完全正确,三种常见决策方式各自的缺陷都源于这个矛盾。独裁式决策由一个独立的”决策者”收集所有冗余节点上报的信息、统一做判断,好处是不会出现决策混乱(只有一个声音),但决策者本身就成了新的单点——它自己故障时整个系统就失去了准确判断状态的能力,而如果给决策者本身也搞一套高可用状态决策,就陷入了”由谁来判断这个判断者是否正常”的递归死循环。协商式决策靠两个独立个体交换信息后按规则决策,最常见的形式是主备决策:两台机器都从备机启动,建立连接、交换状态,某一台被推举为主机、另一台继续做备机。这套架构简单,难点全在”信息交换出问题”这一刻怎么办——如果主备之间的连接中断,备机要不要认为主机已经故障:认为故障就升级为主机,但主机其实没坏,系统就凭空多出两个主机;不认为故障就继续当备机,但如果主机这次真的坏了,系统就彻底没有主机了。加更多条连接(双连接、三连接)能降低误判概率,但降不到零,还会引入新问题——多条连接传回的信息不一致时该信谁的,这本身也是无解的。民主式决策靠多个独立个体投票、按”多数取胜”确定状态(如ZooKeeper选主用的Paxos算法),比协商式更复杂难懂,还有一个协商式没有的固有缺陷:脑裂——当集群因为连接中断被分割成两个互相看不见对方的子集群时,每个子集群会各自独立选出一个主节点,导致系统同时存在两个主节点、状态陷入混乱。应对脑裂的常规做法是要求”参与投票的节点数必须超过系统总节点数的一半”,未达到半数的子集群不进行选举——这确实能防止脑裂,但代价是降低了整体可用性:如果真的是过半节点故障(而非网络分区导致的脑裂),系统同样会因为凑不够半数投票节点而选不出主节点,即使剩下的少数节点本身完全健康,系统也等同于宕机了。三种方式没有一种能在所有场景下都不出问题,选哪种本身也是一个需要结合具体业务权衡的复杂判断。
结构图:
flowchart TB
Q["状态决策的三种方式"]
Q --> A["独裁式<br/>单一决策者收集信息统一判断<br/>⚠️决策者本身是单点,故障时整个决策失效"]
Q --> B["协商式(如主备)<br/>两方交换信息按规则决策<br/>⚠️连接中断时:升级判故障可能变2主,<br/>不升级判正常可能变0主"]
Q --> C["民主式(如ZooKeeper Paxos)<br/>多方投票,多数取胜<br/>⚠️算法复杂 + 固有的脑裂缺陷"]
C --> D["脑裂:集群分割成两个互不通信的子集群<br/>各自选出主节点→系统出现2个主节点"]
D --> E["应对:投票节点数须过半才能选举<br/>解决脑裂,但真实过半节点故障时<br/>系统也会因凑不够票数而'宕机'"]