冗余与故障转移
冗余是可用性的物理基础:同一份能力部署多份,坏一份不影响整体。故障转移是冗余的自动化:探测故障、切换流量。面试主线:冗余形态、健康检查、切换机制。
冗余形态
| 形态 | 结构 | 特点 |
|---|---|---|
| 主备(冷备) | 主服务,备机待命 | 切换慢(要拉起),成本低 |
| 主从(热备) | 主读写,从同步待命 | 切换快,从可分担读 |
| 多活 | 多节点同时服务 | 无切换(或就近切换),成本高 |
- 数据库:主从复制 + 哨兵/Patroni 自动切换(见 Redis 和数据库分类的复制篇)
- 应用层:无状态多实例,LB 摘除故障实例(见水平扩展篇)
- 存储:副本集/多副本写入
健康检查
健康检查: 失败摘除, 恢复加入
| 方式 | 机制 | 适用 |
|---|---|---|
| 心跳 | 定时上报/保活 | 内部节点(etcd、哨兵) |
| HTTP 探活 | 请求健康端点(/healthz) | 应用实例(LB 用) |
| TCP 探测 | 端口连通性 | 基础存活 |
要点:健康检查端点要反映真实能力(能连数据库、依赖正常),只返回 200 但内部已坏是假健康;探测频率和失败阈值决定切换速度(快 = 误判多,慢 = 故障窗口长)。
故障转移机制
| 机制 | 原理 | 场景 |
|---|---|---|
| VIP 漂移 | 虚拟 IP 绑到健康节点 | 数据库主备切换 |
| DNS 切换 | 域名解析到新节点 | 容灾切换(有缓存延迟) |
| LB 摘除 | 探测失败自动摘除 | 应用实例 |
| 选举 | 多数派选新主 | 分布式协调(etcd、哨兵) |
自动切换的关键指标:切换时间 = 探测时间 + 决策时间 + 拉起时间。探测要快但别误判(多次失败才判死),决策要可靠(多数派防脑裂)。
脑裂问题
主备场景的经典故障:网络分区导致两个节点都认为自己是主,同时写数据,恢复后数据冲突。
防脑裂三板斧:
- 多数派(quorum):只有拿到多数票才能当主,分区中的少数派自动降级
- 租约(lease):主的身份有时效,过期未续租自动让位(etcd、Patroni)
- 拒写:失联的主拒绝写(Redis 的 min-replicas-to-write,见主从与哨兵篇)
面试追问
- 主备和主从的区别? 备机待命不服务(切换慢),从机同步并可分担读(切换快)。热备优于冷备
- 健康检查的坑? 假健康:探活端点不检查真实依赖。探测频率与失败阈值的权衡(快 vs 稳)
- 怎么防脑裂? 多数派选举、租约过期、失联拒写。核心是“少数派不干活”
- 切换时间怎么缩短? 探测快、决策快、预热(实例常驻)。每段都是时间
- 故障转移后数据一致性? 看复制模式:同步复制不丢(RPO=0),异步可能丢最近写入。可用性和一致性取舍