高可用架构设计
概述
高可用架构(High Availability Architecture)的目标是确保系统在硬件故障、软件错误、人为失误乃至区域灾难等场景下仍能持续提供服务。本文从可用性度量(SLA)出发,系统讲解三大保障场景(本地高可用、业务逻辑保护、容灾多活)、CAP 理论权衡、集群与分布式架构对比,以及 MySQL/Redis/微服务的高可用实战方案。
前置知识
- 高性能架构设计(QPS/TPS 概念)
- 参见:高性能架构设计
学习目标
- 理解 SLA 等级与年停机时间的对应关系
- 掌握高可用三大保障场景及典型技术方案
- 理解 CAP 理论并能在 CP/AP 间做出权衡
- 区分集群架构与分布式架构的适用场景
- 了解 MySQL 主从、Redis Sentinel/Cluster、微服务熔断降级方案
一、可用性度量
1.1 SLA 等级
| 等级 | 可用性 | 年停机时间 | 典型场景 |
|---|---|---|---|
| 1 个 9 | 90% | 36.5 天 | 个人博客 |
| 2 个 9 | 99% | 3.65 天 | 内部系统 |
| 3 个 9 | 99.9% | 8.76 小时 | Web 服务 |
| 4 个 9 | 99.99% | 52.6 分钟 | 企业核心应用 |
| 5 个 9 | 99.999% | 5.26 分钟 | 金融系统 |
| 6 个 9 | 99.9999% | 31.5 秒 | 核心基础设施 |
计算公式:可用性 = (总时间 - 停机时间) / 总时间 × 100%
1.2 三大保障场景
图表渲染中…
二、本地高可用
2.1 故障类型
| 层面 | 典型故障 |
|---|---|
| 硬件 | 服务器主板/CPU/内存故障、硬盘坏道 |
| 网络 | 交换机/路由器故障、网线断裂 |
| 存储 | 存储阵列故障、SAN/NAS 故障 |
特点:恢复快、实施简单、影响范围小。
2.2 典型技术方案
磁盘阵列(RAID):
| RAID 级别 | 最少磁盘 | 容量利用率 | 容错能力 | 适用场景 |
|---|---|---|---|---|
| RAID 0 | 2 | 100% | 无 | 临时数据/缓存 |
| RAID 1 | 2 | 50% | 允许 1 盘故障 | 系统盘/重要数据 |
| RAID 5 | 3 | (n-1)/n | 允许 1 盘故障 | 数据库/文件服务 |
| RAID 10 | 4 | 50% | 每组允许 1 盘故障 | 高 I/O 应用 |
网络冗余:HSRP/VRRP 协议实现路由器主备切换 + LACP 链路聚合。
电源冗余:双电源模块 + UPS(不间断电源)+ 柴油发电机三级保障。
三、业务逻辑保护
3.1 故障类型
| 类别 | 示例 |
|---|---|
| 人为失误 | 误删数据、错误配置、发布错误版本 |
| 软件错误 | OS/数据库/应用/第三方库 Bug |
| 安全事件 | 数据泄露、恶意攻击 |
特点:需要数据恢复、决策干预、问题追溯。
3.2 典型技术方案
| 方案 | 核心思想 | 实现要点 |
|---|---|---|
| 数据快照 | 操作前创建还原点 | 定时全量/增量快照,支持一键回滚 |
| 审计日志 | 记录所有关键操作 | 操作人/时间/IP/变更内容,持久化存储 |
| 灰度发布 | 新版本先小流量验证 | 按用户哈希分流,错误率超阈值自动回滚 |
3.3 灰度发布核心逻辑
javascript
class CanaryDeployment {
constructor() {
this.stable = { version: 'v1.0.0', weight: 90 };
this.canary = { version: 'v2.0.0', weight: 10 };
}
route(userId) {
const hash = this.hashCode(userId) % 100;
return hash < this.canary.weight ? this.canary.version : this.stable.version;
}
monitor() {
const errorRate = this.getErrorRate('canary');
if (errorRate > 0.05) this.rollback(); // 错误率 > 5% 自动回滚
}
rollback() {
this.canary.weight = 0;
this.stable.weight = 100;
}
}四、容灾多活
4.1 容灾等级
| 等级 | 方案 | 恢复时间 | 数据丢失 |
|---|---|---|---|
| Tier 0 | 无异地备份 | 数天~数周 | 全部 |
| Tier 1 | 本地备份异地存储 | 数天 | 1 天 |
| Tier 2 | 异地热备 | 数小时 | 数分钟 |
| Tier 3 | 异地双活 | 数分钟 | 秒级 |
| Tier 4 | 异地多活 | 秒级 | 0 |
4.2 架构方案对比
| 方案 | 拓扑 | 恢复时间 | 成本 | 适用 |
|---|---|---|---|---|
| 主备 | 主中心 + 备中心(异步复制) | 数小时 | 低 | 中小企业 |
| 双活 | 两地同时服务 + 数据同步 | 分钟级 | 中 | 大型企业 |
| 多活 | 多地同时服务 + GSLB | 秒级 | 高 | 金融/互联网巨头 |
图表渲染中…
4.3 故障转移核心逻辑
javascript
class MultiDataCenter {
constructor() {
this.dcs = {
beijing: { status: 'active', weight: 30 },
shanghai: { status: 'active', weight: 30 },
guangzhou:{ status: 'active', weight: 40 }
};
}
failover(failedDC) {
const failedWeight = this.dcs[failedDC].weight;
this.dcs[failedDC].status = 'failed';
this.dcs[failedDC].weight = 0;
const active = Object.keys(this.dcs).filter(k => this.dcs[k].status === 'active');
const extra = failedWeight / active.length;
active.forEach(dc => { this.dcs[dc].weight += extra; });
}
}五、CAP 理论
5.1 三要素
| 要素 | 含义 |
|---|---|
| C(Consistency) | 所有节点同一时间看到的数据一致 |
| A(Availability) | 每个请求都能在合理时间内得到响应 |
| P(Partition Tolerance) | 网络分区发生时系统仍能运行 |
核心结论:分布式系统中 P 不可避免,因此只能在 CP 与 AP 之间选择。
5.2 组合选择
| 组合 | 特点 | 代表系统 |
|---|---|---|
| CA | 强一致 + 高可用,不支持分区 | MySQL 主从、Oracle RAC |
| CP | 强一致 + 分区容错,分区时不可用 | MongoDB、HBase、ZooKeeper |
| AP | 高可用 + 分区容错,数据最终一致 | Cassandra、DynamoDB、CouchDB |
5.3 权衡实践
- CP 写入:获取分布式锁 → 写入所有节点 → 全部成功才提交 → 任一失败则回滚
- AP 写入:尝试写入所有节点 → 至少一个成功即返回 → 异步同步到失败节点(最终一致性)
六、集群 vs 分布式
| 维度 | 集群架构 | 分布式架构 |
|---|---|---|
| CAP | CA | CP 或 AP |
| 部署 | 多节点部署相同应用 | 多节点部署不同服务 |
| 数据一致性 | 强一致 | 最终一致 |
| 扩展方式 | 垂直扩展为主 | 水平扩展为主 |
| 复杂度 | 相对简单 | 较高 |
| 故障影响 | 单节点故障影响小 | 服务间故障可能传播 |
6.1 技术栈对比
| 层面 | 集群 | 分布式 |
|---|---|---|
| 负载均衡 | Nginx / HAProxy / F5 | Kong / APISIX / Istio |
| 消息队列 | RabbitMQ / ActiveMQ | Kafka / RocketMQ / Pulsar |
| 缓存 | Redis 主从 / Memcached | Redis Cluster / Codis |
| 数据库 | MySQL 主从 / Oracle RAC | TiDB / OceanBase / CockroachDB |
| 协调服务 | — | ZooKeeper / etcd / Consul |
七、高可用实战方案
7.1 MySQL 主从复制
图表渲染中…
关键配置:主库开启 log-bin,从库配置 relay-log + read-only=1,监控复制延迟。
7.2 Redis 高可用
| 方案 | 特点 | 适用场景 |
|---|---|---|
| Sentinel 哨兵 | 监控 + 自动故障转移 | 数据量适中、高可用需求 |
| Cluster 集群 | 数据分片 + 自动故障转移 + 水平扩展 | 大数据量、高吞吐 |
Sentinel 核心配置:sentinel monitor mymaster <ip> 6379 2(quorum=2 表示 2 个哨兵同意才执行故障转移)。
7.3 微服务熔断降级
javascript
class CircuitBreaker {
constructor(threshold = 5, timeout = 60000) {
this.states = new Map();
this.threshold = threshold;
this.timeout = timeout;
}
isOpen(service) {
const s = this.states.get(service);
if (!s || s.status !== 'open') return false;
if (Date.now() - s.lastFailure > this.timeout) {
s.status = 'half-open'; // 半开:允许试探性请求
return false;
}
return true;
}
recordFailure(service) {
const s = this.states.get(service) || { status: 'closed', count: 0 };
s.count++;
s.lastFailure = Date.now();
if (s.count >= this.threshold) s.status = 'open';
this.states.set(service, s);
}
recordSuccess(service) {
this.states.set(service, { status: 'closed', count: 0 });
}
}降级策略:
- 推荐服务 → 返回热门商品兜底
- 评论服务 → 返回缓存数据
- 支付服务 → 不可降级,返回"稍后重试"
八、监控与告警
8.1 监控指标分层
| 层级 | 关键指标 |
|---|---|
| 系统层 | CPU / 内存 / 磁盘 / 网络流量 |
| 应用层 | QPS / 响应时间 / 错误率 / 可用性 |
| 数据层 | 连接数 / 查询时间 / 复制延迟 / 磁盘 I/O |
| 中间件层 | MQ 延迟 / 缓存命中率 / 服务健康状态 |
8.2 告警策略
| 指标 | Warning | Critical |
|---|---|---|
| CPU | > 70% 持续 5min | > 90% 持续 1min |
| 错误率 | > 1% 持续 3min | > 5% 持续 1min |
| 可用性 | < 99.95% | < 99.9% |
常见问题
| 问题 | 根因 | 解决方案 |
|---|---|---|
| 单点故障 | 关键组件无冗余 | 集群部署 + 主备切换 |
| 数据不一致 | 异步复制延迟 | 同步复制 / 最终一致性补偿 |
| 故障转移慢 | 手动干预 | 自动健康检查 + 自动转移 |
| 雪崩效应 | 服务级联失败 | 熔断 + 降级 + 限流 |
| 数据丢失 | 缺乏异地容灾 | 异地备份 + 实时同步 |
| 恢复时间长 | 缺乏预案 | 定期演练 + 自动化恢复 |
最佳实践
- 消除单点:所有关键组件至少双节点部署
- 分层防护:硬件冗余 → 数据保护 → 应用多实例 → 容灾多活
- 自动化故障转移:Sentinel / K8s 健康检查,减少人工介入
- 灰度发布:新版本先 10% 流量验证,异常自动回滚
- 定期演练:每季度进行故障注入演练,验证预案有效性
- 监控全覆盖:系统/应用/数据/中间件四层指标 + 分级告警
延伸阅读
- 《高可用架构》- 李智慧
- 《Release It!》- Michael Nygard
- 《分布式系统原理》- 范磊
- Redis Sentinel 文档
- CAP 定理详解 - IBM