系統設計中的 CAP 理論

當從單體應用程式 (Monolithic Application) 走向微服務或任何分散式架構時,享受了擴展性與彈性的好處,但也必須面對一個新的挑戰:如何在多個節點之間維持資料的可靠性與服務的可用性?

想像一下這個場景:在一個全球知名的電商平台搶購限量版球鞋。當按下「購買」的瞬間,系統背後可能有數十甚至數百台伺服器在同時運作。系統如何確保你買到的這雙鞋不會同時被另一個人買走?又如何保證即使某個地區的機房發生網路問題,依然能順利完成交易?

這就是 CAP 理論要解決的核心問題。

在分散式系統設計中,CAP 理論(CAP Theorem)是一個核心概念,用來描述在分散式資料庫中,系統無法同時滿足 一致性(Consistency)可用性(Availability)分區容錯性(Partition Tolerance) 這三大特性。理解 CAP 理論對於後端工程師在設計資料庫架構或分散式系統時至關重要。


什麼是 CAP 理論?

CAP 理論,又稱布魯爾定理 (Brewer’s Theorem),由電腦科學家 Eric Brewer 在 2000 年提出。它指出,任何一個分散式資料儲存系統,最多只能同時滿足以下三個特性中的兩項。

在一個分散式系統中,一致性 (Consistency)可用性 (Availability)分區容錯性 (Partition Tolerance),這三者無法兼得。

CAP 三大特性

1. 一致性(Consistency)

  • 定義:所有節點在同一時間點讀取到的資料,必須是完全相同的。

  • 白話解釋:當成功寫入一筆新資料後,任何後續的讀取操作,都應該要能讀到這筆最新的資料。系統就像只有一個「真相」來源,絕不允許讀到舊的或不一致的資料。

  • 優點:避免資料不同步問題,提供強一致性體驗。

  • 缺點:可能需要等待資料同步完成,導致延遲。


2. 可用性(Availability)

  • 定義:每一次的請求,不論是讀取或寫入,都必須收到一個(非錯誤的)回應。

  • 白話解釋:系統永遠處於「開機」狀態。只要使用者發出請求,系統就一定會回應,它不能因為內部忙碌或網路問題就直接拋出錯誤或無止盡地等待。不過,它不保證回傳的資料是最新的。

  • 優點:系統可靠、不間斷服務。

  • 缺點:可能回傳舊資料,導致一致性下降。


3. 分區容錯性(Partition Tolerance)

  • 定義:即使叢集中的部分節點之間因為網路問題而無法互相通訊(也就是發生「網路分區」),系統整體仍然能夠繼續運作。

  • 白話解釋:在現代雲端架構中,網路閃爍、交換機故障、機房斷線是家常便飯。分區容錯性意味著系統設計必須能容忍這些意外,不能因為兩個節點「失聯」就導致整個系統崩潰。

  • 優點:保證系統在網路異常下仍能運行。

  • 缺點:必須在一致性與可用性之間做取捨。


CAP 不可能三角

CAP 理論指出,在發生網路分區的情況下,系統只能同時滿足 一致性(C)可用性(A) 其中之一,而無法同時兼顧。這就是所謂的 「不可能三角」

用圖來表示如下:

graph TD
    C[一致性<br>Consistency] --- A[可用性<br>Availability]
    A --- P[分區容錯性<br>Partition Tolerance]
    P --- C
    style C fill:#d6f0ff,stroke:#3399ff,stroke-width:2px
    style A fill:#d6f0ff,stroke:#3399ff,stroke-width:2px
    style P fill:#d6f0ff,stroke:#3399ff,stroke-width:2px

CAP 理論最關鍵的部分在於:P (分區容錯性) 在現今的分散式系統中,是一個「必選項」,而不是「可選項」

只要系統部署在多台機器上,就必須假設網路隨時可能出問題。因此,系統設計的真正權衡,其實是在網路分區發生時,必須在 C (一致性)A (可用性) 之間做出抉擇。

用一個簡單的圖示來思考:

[資料庫節點 A]  <---- 網路連線正常 ---->  [資料庫節點 B]
  (資料: v1)                             (資料: v1)

假設此時,一個寫入請求進來,將資料更新為 v2。資料成功寫入節點 A,並開始同步到節點 B。

[資料庫節點 A]  <---- 同步中 ---->  [資料庫節點 B]
  (資料: v2)                       (資料: v1)

就在這個瞬間,網路發生了分區!

[資料庫節點 A]  <---- X 網路中斷 X ---->  [資料庫節點 B]
  (資料: v2)                             (資料: v1)

現在,一個讀取請求進來了,它可以被路由到節點 A 或節點 B。這時面臨了抉擇:

  1. 選擇 C (一致性),放棄 A (可用性) - 稱為 CP 系統

    • 為了保證一致性,節點 B 因為無法與節點 A 同步以獲取最新的 v2 資料,它必須拒絕所有的讀取請求,或者回傳錯誤。
    • 這樣做確保了任何讀取請求都不會讀到舊的資料 (v1),維持了資料的強一致性。但犧牲了節點 B 的可用性。
  2. 選擇 A (可用性),放棄 C (一致性) - 稱為 AP 系統

    • 為了保證可用性,節點 B 即使知道自己可能不是最新的,它仍然會回傳它目前擁有的資料 (v1)。
    • 這樣做確保了系統永遠可以回應使用者的請求,但犧牲了資料的一致性(使用者可能會讀到舊資料)。

現實世界的例子

CP 系統 (Consistency > Availability)

當資料的正確性至關重要,不容許絲毫偏差時,就會選擇 CP。

  • 應用場景:銀行交易、金融系統、訂單管理。絕對不希望因為讀到舊的餘額資料而造成超額提款,或因為庫存資料不一致而超賣商品。
  • 代表技術:MongoDB、Redis、HBase。這些系統都提供了調整一致性等級的選項,在需要時可以配置為強一致性模式。

AP 系統 (Availability > Consistency)

當使用者體驗和系統的永遠在線比短暫的資料不一致更重要時,就會選擇 AP。

  • 應用場景:社群媒體的按讚數、貼文瀏覽次數、電商網站的商品評論。晚幾秒鐘看到最新的按讚數不會造成嚴重後果,但如果網站頻繁顯示錯誤訊息,使用者會立刻流失。
  • 代表技術:Cassandra、DynamoDB (Amazon)、CouchDB。它們天生就是為了高可用性和高擴展性而設計的,採用的是「最終一致性」(Eventual Consistency) 模型。

那 CA 系統呢?

理論上,一個沒有分區容錯需求的系統就是 CA 系統。這意味著什麼?它只有一個節點!傳統的單體關聯式資料庫(如 MySQL、PostgreSQL)可以被視為 CA 系統。它們在單機內保證了強大的 ACID 一致性與可用性,但一旦這台機器掛了,或是網路斷了,整個系統就無法服務了。這在分散式架構中是不可行的。


結論

CAP 理論不是一個僵硬的規則,而是一個幫助我們理解分散式系統設計權衡的框架。它提醒我們:

  1. 在分散式世界裡,網路分區 (P) 是必然的,必須為它設計。
  2. 你的選擇是在發生分區時,要 犧牲一致性 © 還是可用性 (A)
  3. 這個選擇沒有絕對的好壞,完全取決於業務需求。問問自己:是「絕對不能出錯的資料」比較重要,還是「永不中斷的服務」比較重要?

在設計分散式系統時,不可能同時兼顧 一致性、可用性、分區容錯性 三者,只能依照應用場景做出取捨。

  • 金融或高敏感度資料 → CP 系統
  • 高可用、用戶體驗優先 → AP 系統
  • 小型單機系統 → CA 系統

理解 CAP 理論,能幫助我們在不同業務需求下選擇合適的架構,設計更可靠與合理的分散式系統。