知识卡片
双机切换三种架构:互连式、中介式与模拟式的取舍
内容
按[[双机切换的三个设计关键点,及复杂度暴涨一个量级的原因]]里”状态传递渠道”这个维度的不同实现,常见的主备切换架构有三种。互连式是主备机之间直接建一条状态传递通道(可以是网络连接也可以是串口,可以主推备取也可以备取主推,可以和数据复制通道共用也可以独立,甚至可以多条通道混合),配合客户端共享一个虚拟IP或同时记录主备地址来实现切换后的无感知;它最大的缺点在于状态通道本身也可能故障(比如网线被踢掉),一旦通道断了,备机会误以为主机故障、把自己升级为主机,而实际主机根本没坏,结果就是同时出现两个主机——即使增加多条通道也只能降低这种误判概率,无法根本解决,而且通道越多,备机收到的多路状态信息可能相互矛盾,决策反而更复杂。中介式是在主备之外引入第三方中介,主备都只连中介、通过中介传递和上报状态,看起来多了一层反而更复杂,但实际上状态传递和决策都更简单——连接管理更简单(主备只需要维护和中介的单一连接,不用管理多种类型的通道);状态决策也更简单(可以用一套固定算法:初始状态都是备机,与中介断连就自动降级为备机;主机与中介断连,中介立刻通知备机升级为主机;网络中断导致的断连,原主机自己降级、网络恢复后以新备机身份重新上报;掉电重启这类情况,原主机重启后发现已有主机在位就保持备机状态不变;连接都正常时,就按实际状态指标决定要不要切换)。中介式的真正代价在于中介本身也必须高可用——中介一旦宕机,系统就会陷入”双备机”状态、写操作直接不可用,这就掉进了一个递归陷阱:”为了实现高可用引入中介,中介本身又需要高可用,于是要为中介再设计高可用方案……”好在ZooKeeper、Keepalived这类开源方案已经把中介自身的高可用问题解决了,工程实践中直接基于ZooKeeper搭建中介式切换架构是推荐做法(MongoDB的Replica Set就是这种思路,用主节点+备节点+不存数据的仲裁节点组成)。模拟式是主备之间完全不传递状态数据,而是让备机伪装成一个客户端,主动向主机发起模拟的读写请求,靠这些请求的响应情况来判断主机状态;优点是实现最简单(省去了整套状态传递通道的建立和维护),但简单本身也是代价——模拟读写能拿到的状态信息只有响应层面的信息(如404、超时、响应超过3秒),远不如互连式能拿到的CPU负载、I/O负载、吞吐量等多维指标丰富,基于这么有限的信息做状态决策,容易出现误判。
结构图:
flowchart TB
A["双机切换的三种状态传递架构"]
A --> B["互连式:主备直接建通道"]
B --> B1["优点:实现直观"]
B --> B2["缺点:通道本身可能故障<br/>→备机误判主机故障→出现双主机<br/>多通道只降低概率,不能根治"]
A --> C["中介式:主备都只连第三方中介"]
C --> C1["优点:连接管理更简单+状态决策算法更简单"]
C --> C2["代价:中介自身必须高可用<br/>→递归陷阱(中介宕机=系统双备)<br/>推荐直接用ZooKeeper/Keepalived解决"]
A --> D["模拟式:备机模拟客户端探测主机"]
D --> D1["优点:无需状态传递通道,最简单"]
D --> D2["缺点:只有响应层面信息<br/>(不含CPU/IO/吞吐量等),易误判"]