高可用架構設計#

高可用(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 --- AP
CAP 細節解析

細節一: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

設計原則

  1. 保證核心業務:不是所有業務都要異地多活
  2. 保證大部分用戶:故障時允許少量用戶受影響
  3. 核心資料最終一致:允許短時間不一致
  4. 採用多種手段:消息隊列、資料庫同步、重試機制
異地多活實戰技巧

技巧一:用戶分區

用戶 ID % 100 < 50  → 北京機房
用戶 ID % 100 >= 50 → 上海機房

優點:減少跨機房呼叫,降低延遲

技巧二:資料分類處理

資料類型同步策略
用戶基礎資訊異步同步,允許 1 分鐘延遲
用戶餘額同步寫入,或單機房處理
瀏覽記錄各機房獨立,不同步
登錄態各機房獨立生成

技巧三:故障切換流程

  1. 監控發現故障
  2. 確認是真正的機房故障(避免網路抖動誤判)
  3. DNS/GSLB 切換流量
  4. 處理資料不一致(人工或自動)
  5. 通知相關方

FMEA 分析方法#

FMEA(Failure Mode and Effects Analysis)是系統化分析故障的方法。

FMEA 步驟#

  1. 列出功能點:系統有哪些功能
  2. 列出故障模式:每個功能可能怎麼壞
  3. 評估故障影響:對用戶、業務的影響
  4. 計算風險優先級:嚴重度 x 發生率 x 檢測難度
  5. 制定應對措施:預防、檢測、恢復

FMEA 表格範例#

功能故障模式影響嚴重度發生率檢測度RPN措施
登錄DB 故障無法登錄93254主從切換
登錄快取故障登錄變慢64372快取降級
支付第三方超時支付失敗85280重試+補償

RPN(Risk Priority Number)= 嚴重度 x 發生率 x 檢測難度,數值越高越需要優先處理。

本章小結#

主題核心思想關鍵技術
計算高可用任務管理與故障切換主備、主從、集群
存儲高可用資料複製與一致性權衡CAP、主從複製
狀態決策沒有完美方案,選擇合適的獨裁、協商、民主
異地多活應對機房級故障資料分區、分類同步

高可用設計的核心公式:

高可用 = 冗餘 + 故障檢測 + 故障切換 + 資料恢復