高可用架構設計#
高可用(High Availability)是指系統無中斷地執行其功能的能力。本章介紹高可用架構的核心模式,包括冗餘設計、故障轉移和災難恢復。
高可用的本質#
高可用的核心難點在於「無中斷」,但無論是硬件還是軟件,都不可能做到絕對的無中斷:
- 硬件會出故障、會老化
- 軟件會有 bug、會崩潰
- 外部環境有斷電、地震、光纜被挖
高可用的本質是通過「冗餘」來規避部分故障的風險。一台機器不夠就兩台,一個機房不夠就兩個。
高可用 vs 高效能#
雖然高可用和高效能都是增加機器,但本質不同:
| 目標 | 增加機器的目的 | 核心問題 |
|---|---|---|
| 高效能 | 擴展處理能力 | 任務如何分配 |
| 高可用 | 冗餘處理單元 | 故障如何切換 |
計算高可用架構#
計算(業務邏輯處理)的特點是:同樣的算法和輸入,在任何機器上執行結果都一樣。因此計算高可用的關鍵是任務管理。
主備架構#
最簡單的高可用架構,無需資料複製。
flowchart TB
D[任務分配器]
D -->|故障切換| M[主機<br/>(Active)]
D -.->|不分配任務| S[備機<br/>(Standby)]
style M fill:#e8f5e9
style S fill:#ffecb3備機類型:
| 類型 | 狀態 | 切換時間 | 場景 |
|---|---|---|---|
| 冷備 | 業務系統未啟動 | 分鐘級 | 成本敏感 |
| 溫備 | 業務系統已啟動,不對外服務 | 秒級 | 推薦方案 |
| 熱備 | 實時同步狀態,隨時可切換 | 毫秒級 | 金融級 |
主備架構的缺點:需要人工切換,效率低、容易出錯。適用於內部管理系統等對可用性要求不高的場景。
主從架構#
主機和從機都執行任務,但執行不同類型的任務。
flowchart TB
D[任務分配器]
D -->|任務 A| M[主機<br/>任務 A]
D -->|任務 B| S[從機<br/>任務 B]
style M fill:#e8f5e9
style S fill:#e3f2fd典型應用:
- MySQL 讀寫分離:主機寫,從機讀
- ZooKeeper:Leader 處理寫,Follower 處理讀
集群架構#
多台伺服器組成集群,自動進行故障檢測和切換。
對稱集群(負載均衡集群)
每台伺服器角色相同,都可執行任何任務。
flowchart TB
D["任務分配器<br/>(負載均衡 + 健康檢查)"]
D --> S1[S1]
D --> S2[S2]
D --> S3[S3]
D --> S4[S4]
style S1 fill:#e8f5e9
style S2 fill:#e8f5e9
style S3 fill:#e8f5e9
style S4 fill:#e8f5e9設計關鍵點:
- 分配策略:輪詢、隨機、最少連接
- 狀態檢測:心跳、健康檢查、超時判斷
非對稱集群
不同伺服器角色不同,如 Master-Slave。
flowchart TB
D[任務分配器]
D -->|寫請求| M[Master]
D -->|讀請求| Slaves
subgraph Slaves[Slaves]
S1[S1]
S2[S2]
end
style M fill:#fff3e0
style S1 fill:#e3f2fd
style S2 fill:#e3f2fd設計關鍵點:
- 角色分配:選舉算法(ZAB、Raft)
- 任務路由:根據任務類型路由到對應角色
存儲高可用架構#
存儲高可用比計算高可用更複雜,原因在於:資料需要在節點間複製,而複製需要時間。
┌─────────┐ 傳輸 ┌─────────┐
│ 節點 A │ ──────────→ │ 節點 B │
│ 資料 v1 │ 網路延遲 │ 資料 v0 │
└─────────┘ (毫秒~秒) └─────────┘
│
▼
資料不一致窗口存儲高可用的難點不在於如何備份資料,而在於如何減少或規避資料不一致對業務的影響。
CAP 定理#
分布式系統最多只能同時滿足以下三項中的兩項:
| 屬性 | 含義 |
|---|---|
| C (Consistency) | 一致性:所有節點看到相同的資料 |
| A (Availability) | 可用性:每個請求都能得到響應 |
| P (Partition Tolerance) | 分區容錯:網路分區時系統繼續運作 |
flowchart TD
C((C<br/>一致性))
A((A<br/>可用性))
P((P<br/>分區容錯))
C --- CP[CP 系統<br/>如 ZooKeeper]
C --- CA[CA 系統<br/>如傳統 RDBMS]
A --- CA
A --- AP[AP 系統<br/>如 Cassandra]
P --- CP
P --- APCAP 細節解析
細節一:CAP 關注的粒度是資料,而非整個系統
同一系統中,不同資料可以選擇不同策略:
- 用戶賬號資料 → CP(一致性優先)
- 用戶偏好設置 → AP(可用性優先)
細節二:CAP 忽略網路延遲
即使選擇 CP,在資料複製的幾毫秒內,節點間資料也是不一致的。因此:
- 單用戶餘額這類資料,實際上只能選擇 CA(單點寫入)
- 但系統整體可以是分布式的(用戶分區)
細節三:正常情況下可以同時滿足 CA
CAP 只在發生分區(P)時才需要在 C 和 A 之間選擇。
細節四:「放棄」不等於什麼都不做
分區恢復後,需要有機制讓系統重新達到 CA 狀態(如日誌同步)。
資料複製模式#
| 模式 | 一致性 | 可用性 | 適用場景 |
|---|---|---|---|
| 同步複製 | 強 | 低 | 金融交易 |
| 異步複製 | 弱 | 高 | 日誌、評論 |
| 半同步複製 | 中 | 中 | 訂單、庫存 |
同步複製:
Client ──→ Master ──→ Slave ──→ ACK ──→ Client
等待複製完成異步複製:
Client ──→ Master ──→ Client (立即返回)
│
└──→ Slave (後台複製)高可用狀態決策#
無論是計算還是存儲高可用,都需要決策:當前狀態是正常還是異常?
通過冗餘實作的高可用系統,狀態決策本質上不可能做到完全正確。
決策方式對比#
| 方式 | 機制 | 問題 | 應用 |
|---|---|---|---|
| 獨裁式 | 單一決策者 | 決策者故障則系統癱瘓 | 簡單場景 |
| 協商式 | 兩節點互相協商 | 連接中斷時決策困難 | 主備切換 |
| 民主式 | 多節點投票 | 腦裂問題 | ZK, etcd |
腦裂問題#
民主式決策的固有缺陷:網路分區時可能選出多個「主」。
正常狀態:
┌───┬───┬───┬───┬───┐
│ 1 │ 2 │ 3 │ 4 │ 5★│ 5 是 Master
└───┴───┴───┴───┴───┘
分區後:
┌───┬───┬───┐ ┌───┬───┐
│ 1 │ 2★│ 3 │ │ 4 │ 5★│ 選出兩個 Master!
└───┴───┴───┘ └───┴───┘
子集群A 子集群B解決方案:過半機制
投票節點數必須超過總節點數的一半。子集群 B 只有 2 個節點(未過半),不會發起選舉。
這種方案降低了可用性:如果真的有 3 個節點故障,系統也無法選出 Master。
異地多活架構#
當災難影響整個機房時,單機房的高可用方案就失效了。異地多活是應對機房級故障的方案。
多活模式#
| 模式 | 描述 | 複雜度 | 適用場景 |
|---|---|---|---|
| 同城雙活 | 同城兩機房 | 低 | 機房級故障 |
| 異地雙活 | 不同城市兩機房 | 中 | 城市級故障 |
| 異地多活 | 多城市多機房 | 高 | 極端災難 |
異地多活設計要點#
flowchart TB
U[用戶] -->|DNS/GSLB| BJ
U -->|DNS/GSLB| SH
subgraph BJ["北京機房"]
BJ_APP[應用集群]
BJ_DB[資料庫]
BJ_APP --> BJ_DB
end
subgraph SH["上海機房"]
SH_APP[應用集群]
SH_DB[資料庫]
SH_APP --> SH_DB
end
BJ_APP <-.->|資料同步| SH_APP
BJ_DB <-.->|資料同步| SH_DB
style BJ fill:#e3f2fd
style SH fill:#fff3e0設計原則:
- 保證核心業務:不是所有業務都要異地多活
- 保證大部分用戶:故障時允許少量用戶受影響
- 核心資料最終一致:允許短時間不一致
- 採用多種手段:消息隊列、資料庫同步、重試機制
異地多活實戰技巧
技巧一:用戶分區
用戶 ID % 100 < 50 → 北京機房
用戶 ID % 100 >= 50 → 上海機房優點:減少跨機房呼叫,降低延遲
技巧二:資料分類處理
| 資料類型 | 同步策略 |
|---|---|
| 用戶基礎資訊 | 異步同步,允許 1 分鐘延遲 |
| 用戶餘額 | 同步寫入,或單機房處理 |
| 瀏覽記錄 | 各機房獨立,不同步 |
| 登錄態 | 各機房獨立生成 |
技巧三:故障切換流程
- 監控發現故障
- 確認是真正的機房故障(避免網路抖動誤判)
- DNS/GSLB 切換流量
- 處理資料不一致(人工或自動)
- 通知相關方
FMEA 分析方法#
FMEA(Failure Mode and Effects Analysis)是系統化分析故障的方法。
FMEA 步驟#
- 列出功能點:系統有哪些功能
- 列出故障模式:每個功能可能怎麼壞
- 評估故障影響:對用戶、業務的影響
- 計算風險優先級:嚴重度 x 發生率 x 檢測難度
- 制定應對措施:預防、檢測、恢復
FMEA 表格範例#
| 功能 | 故障模式 | 影響 | 嚴重度 | 發生率 | 檢測度 | RPN | 措施 |
|---|---|---|---|---|---|---|---|
| 登錄 | DB 故障 | 無法登錄 | 9 | 3 | 2 | 54 | 主從切換 |
| 登錄 | 快取故障 | 登錄變慢 | 6 | 4 | 3 | 72 | 快取降級 |
| 支付 | 第三方超時 | 支付失敗 | 8 | 5 | 2 | 80 | 重試+補償 |
RPN(Risk Priority Number)= 嚴重度 x 發生率 x 檢測難度,數值越高越需要優先處理。
本章小結#
| 主題 | 核心思想 | 關鍵技術 |
|---|---|---|
| 計算高可用 | 任務管理與故障切換 | 主備、主從、集群 |
| 存儲高可用 | 資料複製與一致性權衡 | CAP、主從複製 |
| 狀態決策 | 沒有完美方案,選擇合適的 | 獨裁、協商、民主 |
| 異地多活 | 應對機房級故障 | 資料分區、分類同步 |
高可用設計的核心公式:
高可用 = 冗餘 + 故障檢測 + 故障切換 + 資料恢復