先算一笔停机账
谈高可用之前先把数字摆正:99.9% 的可用性,全年允许停机 8.8 小时;99.99% 是 52 分钟;99.999% 是 5 分钟。每多一个 9,成本不是线性而是指数上涨。前面两篇讲的主从、Dledger 解决的是机器级故障——一块盘、一台机挂了不停服。这一篇往上看:机房级故障怎么办。
容灾的三档方案
| 方案 | 机制 | 数据丢失窗口 | 切换耗时 |
|---|---|---|---|
| 冷备 | 备机房环境空转,出事后恢复数据再上 | 最后一次备份之后全丢 | 小时到天级 |
| 异步复制主备 | 主机房实时(异步)复制到备机房 | 复制延迟窗口内的数据 | 分钟级 |
| 双活 | 两机房各自承担流量,互为备份 | 接近零 | 秒级/无感 |
工具侧,Kafka 用 MirrorMaker 2 做跨集群复制,RocketMQ 有 replicator 同步组件。双活不是「买得起就上」:两机房互写带来的消息同步冲突、ID 生成、消费进度管理都是全新的复杂度。老王的咖啡馆结论很务实——同机房双可用区部署 + 异步复制冷备机房,是业务体量过线前的性价比之选。
脑裂:容灾方案里最毒的刺
跨机房部署绕不开脑裂(Split-Brain):机房之间网络断了,两边的节点各自认为对方死了,各自把「自己人」选成主——于是系统里出现两个主,同时接收写入,数据开始分叉,网络恢复时合并无从下手。
防线有几道:多数派协议天然免疫——Raft/Dledger 要求拿不到多数票就不能成为主,三节点断成 1+2 时,1 的一侧自动降级为只读;传统主从集群则要配第三方仲裁(quorum)或 fencing 机制——新主上任前先把旧主隔离(改只读、踢出集群)。宁可短暂不可写,也不能接受双主双写,这是容灾设计的铁律。
客户端容错:最后一道自适应防线
- 多地址种子:bootstrap.servers / NameServer 地址列表至少给两个,别把鸡蛋放进一个 IP;
- 路由定期刷新:RocketMQ 客户端每 30 秒刷新路由,Broker 下线后自动摘除;
- 发送容错:失败自动换一台 Broker 重试(RocketMQ 默认行为),配合超时与退避,别死磕一台;
- 消费端幂等:故障切换与容灾复制都会放大重复,幂等在容灾体系里不是可选项。
没演练过的预案等于没有预案
容灾方案的价值在演练里验证。老王的团队每季度固定做三件事:拔掉一台 Broker(验证自动选主与客户端感知速度);整个可用区网络隔离(验证脑裂防护与降级读写);模拟机房级切换(验证备机房数据完整性与应用重连)。每次演练后复盘 RTO(恢复耗时)与 RPO(丢失数据量)是否达标。文档写得再漂亮,没跑过一遍的预案,出事时大概率变成事故报告里的一句「预案未生效」。
容灾选型的决策线
- 停机损失以小时计 → 同机房高可用 + 每日备份恢复演练即可;
- 核心交易,分钟级 RTO → 双可用区部署 + 异步复制备机房;
- 金融级,RPO 趋近零 → 双活或三机房多数派(接受成本翻倍);
- 无论哪档:多数派协议优先,fencing 兜底,演练按季度。
小结
高可用是层层加码的体系:机器级靠主从与 Raft,机房级靠复制与双活,客户端容错兜住最后一跳,演练让整套体系不是纸面功夫。可用性每多一个 9,都是钱和复杂度堆出来的——按业务真实损失定价,别为用不上的 9 买单。
架构话题到此收官。下一篇进入运维实战:监控与调优——积压告警怎么设、消费 TPS 怎么看、发送与消费的参数清单怎么配。
评论 (0)