容错与故障转移⚓︎
在主从复制(Leader-based Replication)的分布式系统中,主节点负责处理全部的写入流量。若主节点发生宕机或网络隔离,将直接导致系统无法处理写入请求。为了保证系统的高可用性,必须通过故障转移(Failover)机制将主节点的职责安全地交接给某一个从节点。
故障转移的核心步骤⚓︎
完整的故障转移流程通常涉及以下三个核心步骤:节点失效检测、新主节点选举以及系统配置重配。
1. 节点失效检测(Failure Detection)⚓︎
由于分布式网络本身的不可靠性,节点之间无法确定对方是真正宕机、发生过长 GC 停顿还是仅仅由于网络延迟引发了通信超时。因此,失效检测主要依赖超时机制。
节点之间会周期性地发送心跳包(Heartbeat)。如果一个节点在设定的超时阈值(Timeout)内没有收到主节点的心跳包或响应,系统就会假定该主节点已经失效。超时阈值的设定需要在误判率(过短导致频繁的不必要切换)和恢复时间(过长导致系统不可用时间增加)之间进行工程权衡。
2. 选举新主节点(Leader Election)⚓︎
当主节点被判定失效后,系统必须从现有的从节点中选举出一个作为新的主节点。该过程通常基于共识算法(如 Raft、Paxos)或依赖外部的分布式协调服务(如 ZooKeeper、etcd)完成。
选举机制需要确保以下条件:
- 数据完整性:优先选举拥有最新数据(即同步进度最靠前)的从节点,以最大程度减少数据丢失风险。
- 唯一性:通过 Quorum 机制(超过半数节点同意)确保同一时刻只能选出一个主节点以避免脑裂。
3. 请求路由与配置重配(Reconfiguration)⚓︎
新主节点产生后,系统的拓扑配置发生了实质性变更。客户端、请求网关及其他存活的从节点必须被及时通知。
客户端需要将后续的写入请求重新路由至新的主节点;其他从节点需要将数据同步源切换为新主节点。若旧主节点在故障转移完成后重新上线,系统必须强制其降级为从节点,并根据新主节点的状态合并或丢弃其未同步的本地数据。
典型异常与工程挑战⚓︎
故障转移过程涉及复杂的工程实现,处理不当可能引发严重的数据不一致问题。
异步复制与数据丢失⚓︎
如果系统采用异步复制(Asynchronous Replication),主节在向客户端返回写入成功后,可能尚未将该数据同步给任何从节点就发生了宕机。在这类场景下发生故障转移时,新主节点必然缺失部分最新数据。
解决该问题通常有两种策略:
- 丢弃冲突数据:旧主节点恢复后,丢弃所有未共识的本地写入,以新主节点的数据为准,但这违反了客户端认为写入成功的预期。
- 人工介入冲突:保留冲突状态,依靠应用层的定制逻辑或人工介入进行数据合并。
脑裂与隔离机制(Split-Brain & Fencing)⚓︎
当旧主节点因为瞬时网络分区或长 GC 等原因失去连接,并在新的主节点选举完成后再次恢复与客户端的网络互通时,可能会出现两个节点同时认为自己是合法主节点的局面。这种现象称为脑裂(Split-Brain)。
为了防止旧主节点继续接收写请求从而破坏数据一致性,必须引入隔离机制(Fencing):
- Fencing Token(隔离令牌):每次主节点选举后递增一个全局版本号,存储系统在执行写入前校验该版本号,直接拒绝携带旧版本号的请求。
- STONITH(Shoot The Other Node In The Head):通过网络指令直接切断旧主节点的电源或剥夺其网络访问权限,从物理层面隔离故障节点。