主题
高可用与容灾模式
本篇定位
让系统"挂一台机器甚至挂一个机房,用户都几乎无感"。本篇讲清高可用是怎么从单点一步步演进到异地多活的(每一步的可用性、成本、RTO/RPO、适用场景)、流量怎么分层负载均衡、有状态组件(MySQL/Redis/MQ)怎么做高可用、怎么防脑裂,以及备份的 3-2-1 原则。配套:容量估算、架构方法论、容量规划与灾备。
一、高可用架构演进路线
小白类比:高可用就是"别把鸡蛋放一个篮子"。篮子从 1 个 → 2 个 → 分散到两个城市 → 两个城市都能同时做菜。每多一份冗余,成本翻一倍,但停服时间趋近于零。
| 模式 | 可用性 | 成本 | RTO | RPO | 适用场景 |
|---|---|---|---|---|---|
| 单点 | 无(挂了就全停) | 最低 | 小时级 | 看运气 | 个人项目、测试环境 |
| 主备双机(Active-Standby) | ~99.9% | 低(备机闲置) | 分钟级 | 秒~分钟(取决于同步) | 小业务入门、DB 主从 |
| 主主 / 双活(同机房) | ~99.95% | 中(两台都跑业务) | 秒级 | 接近 0(同步) | 中等业务、网关/应用层 |
| 集群(多副本) | ~99.95%~99.99% | 中高 | 秒级 | 接近 0 | 微服务无状态层、Redis Cluster |
| 两地三中心 | ~99.99% | 高 | 分钟级 | 分钟级 | 金融、对机房级故障有要求 |
| 异地多活 | ~99.995%+ | 很高 | 秒级 | ≈0 | 头部互联网、双11 级别 |
RTO / RPO 是什么(见下节):演进的本质,就是花更多钱把 RTO(恢复要多久)和 RPO(最多丢多少数据)压得更小。
二、RTO / RPO 与可用性等级
| 概念 | 含义 | 大白话 | 达标手段 |
|---|---|---|---|
| RTO(Recovery Time Objective) | 故障后恢复服务的目标时间 | 挂了之后多久能恢复 | 自动故障转移、无状态多副本、预热 |
| RPO(Recovery Point Objective) | 恢复后最多能容忍丢多久的数据 | 最多丢多久的数据 | 同步复制(RPO≈0)、半同步、定期备份 |
| 可用性 | 年允许停机时间 | 大约对应 |
|---|---|---|
| 99% | 3.65 天 | 单点 |
| 99.9% | 8.76 小时 | 主备双机 |
| 99.95% | 4.3 小时 | 双活/集群 |
| 99.99% | 52.6 分钟 | 两地三中心 |
| 99.999% | 5.26 分钟 | 异地多活 |
可用性每多一个 9,成本大致翻一倍。别盲目追求 5 个 9——内部系统 99.9% 往往就够了。
三、分层负载均衡:DNS → 四层 → 七层
大流量不能只靠一个 Nginx,要层层分流,每一层都自己是高可用集群:
| 层级 | 组件 | 工作在哪层 | 作用 | 高可用做法 |
|---|---|---|---|---|
| 第 1 层 | DNS(智能解析 / GSLB) | 应用层 | 按地域/运营商把流量导到不同机房 | 多机房解析、健康检查切流 |
| 第 2 层 | LVS / DPVS | 四层(TCP/UDP,按 IP+端口) | 海量并发入口,内核态转发性能极高 | LVS 主备 + Keepalived VIP,见 LVS+Keepalived |
| 第 3 层 | Nginx / 网关(APISIX) | 七层(按 URL/Header) | 路由、限流、鉴权、SSL 卸载 | 多实例 + 上面 LVS 转发,见 Nginx、APISIX |
| 第 4 层 | 应用服务 | 业务层 | 无状态实例,随便加机器 | 前面网关轮询,实例挂了自动摘除 |
口诀:DNS 选机房 → LVS 扛大并发 → Nginx 做路由 → 应用随便扩。小流量可以直接用 Nginx、跳过多层;但量大了必须分层,否则单点网卡/CPU 先成瓶颈。
四、无状态 vs 有状态
| 类型 | 特点 | 高可用策略 |
|---|---|---|
| 无状态组件(应用、网关、Nginx) | 不在本地存会话,请求随便发给哪台都行 | 直接水平加副本,前面挂负载均衡,挂一台无感。会话放 Redis 共享 |
| 有状态组件(MySQL、Redis、MQ) | 自己存数据,换机器很麻烦 | 需要主从复制 + 故障转移,不能简单加机器 |
4.1 有状态组件高可用清单
| 组件 | 高可用方案 | 故障转移 | 关键点 |
|---|---|---|---|
| MySQL | 主从复制 + 半同步;MGR(组复制)或 Orchestrator/MHA 自动切主 | MHA/Orchestrator 自动提升从库 | 防止脑裂、VIP 漂移、应用改连接串。详见 MySQL 进阶与高可用 |
| Redis | 主从 + 哨兵(Sentinel);大数据量上 Cluster 分片 | 哨兵自动选新主 | 主从切换期间可能丢少量写(异步复制)。详见 Redis |
| Kafka | 多 Broker + Topic 多副本(acks=all) | Leader 挂了 Controller 选新 Leader | 副本数 ≥3、min.insync.replicas 保证不丢。详见 Kafka |
五、故障切换与脑裂防护
脑裂(Split-Brain):主备之间的心跳线断了,备机以为主机挂了,自己也起来当主——结果两个主同时写一份数据,数据就乱了。
| 防护手段 | 做法 |
|---|---|
| 仲裁节点(Quorum) | 引入第三方仲裁(如 VIP/表决服务器),少数派那侧自动下台,不能自己说了算 |
| 双心跳线 | 同时用两条独立链路做心跳,一条断了不误判 |
| Fencing(隔离) | 切主时强制把旧主"踢下去"(如 STONITH 断电/关端口),防止它还在写 |
| 资源锁 | 旧主启动前先抢锁,抢不到就不提供服务 |
主备切换不是"脚本跑一下"那么简单:切之前要确认旧主真的挂了(脑裂防护),切之后要校验数据一致性、把连接切过去。没演练过的故障切换等于没有——定期做故障演练,见混沌工程。
六、备份 3-2-1 原则
再高的架构也得留备份兜底。业界黄金法则 3-2-1:
| 数字 | 含义 |
|---|---|
| 3 | 至少保留 3 份数据(生产 + 2 份备份) |
| 2 | 备份放在 2 种不同介质上(如本地盘 + 对象存储) |
| 1 | 其中 1 份异地存放(防机房火灾/地震) |
补充实践:备份要定期做恢复演练(能恢复的备份才算备份)、敏感数据备份要加密、MySQL 用 mysqldump/xtrabackup 定期全量 + binlog 增量(见 MySQL 备份恢复)。
七、延伸阅读
- 机器与容量:容量估算与服务器选型
- 方法论:架构设计方法论
- 四层负载:LVS + Keepalived;七层:Nginx
- DB/缓存/MQ 高可用:MySQL 进阶、Redis、Kafka
- 灾备与容量专题:容量规划、高可用与灾备;故障演练:混沌工程
- 云原生高可用:K8s 架构与集群