分布式系統的架構天險:CAP Theorem 的一點探討

現在人的日常生活離不開各種大型資訊系統,平常上網購物、演唱會搶票、看熱門視頻或是玩遊戲,背後都少不了這些系統。你一定也有這樣的經驗:網路購物結帳時付款始終不成功、別人能登入熱門遊戲的某個伺服器偏偏自己不行、限購票券一下子顯示無票,但是一經過刷新瀏覽器或是換成手機登入又顯示為有票……,到底是怎麼回事?

不只消費者有無數抱怨心聲,企業老闆更是往往無法理解為什麼這些花了重金打造的「大數據」、「高吞吐」、「高可靠性」系統總還是有問題,其實,資訊系統並非萬能,從設計架構的角度來看它有一些先天的限制,就像馬不會飛、鳥不會游一樣, Eric A. Brewer 教授在 2000 年的一場研討會上優雅地以《Towards Robust Distributed Systems》報告中提出的 CAP 定理總結了這些限制,並催生出一些現代資訊系統的設計準則及改善之道,透過今天這篇文章我們就來學習一下 CAP 的核心精神。

寫在 CAP Theorem 之前

在進入 CAP 定理的主旨之前,我們首先要了解資訊系統的兩大類型標準設計準則,第一種準則稱為「 ACID 」,追求資訊的「 一致性(Consistency) 」,第二種準則「 BASE 」則是以系統的「 可用性 (Availability) 」為最高指導原則。

以一個簡單的商品訂購網站 + 資料庫的例子可以很容易了解兩者的區別,在 ACID 的例子中,最重要的內部邏輯是要首先確保不同消費者看到的庫存品與真實資料庫裡的商品數量是相同的,所以不會出現明明剩下 1 件商品卻同時有 2 個消費者下單成功的事情發生;而 BASE 的設計想法則是以瀏覽體驗為主軸,優先確保網頁能夠正確運作,至於是不是每個消費者畫面上看到的東西都一樣,或是畫面上的庫存數量是不是一定和資料庫中的數字一樣,則是次要考量。

你可能已經隱約感覺到了, 對同一個資訊系統而言,Consistency 與 Availability 兩者是有所衝突的。

稍微再說詳細一些,對於剛才的商品訂購網站 + 資料庫範例,我們如何確保 Consistency ?

請參考下方示意圖,其中 1) / 2) / 3) …代表操作的時間順序,一個簡單的作法是當使用者 A 將商品加入購物車時(還未結帳/確定訂單),直接將商品庫存 – 1 ,這樣一來,當同一時間使用 B 也想將購買該商品的時候,就會發現該商品已經售罄(實際上並沒有)。

這個做法可以簡單粗暴的保證不會有「兩個消費者同時結帳成功,但是商品實際上不足的尷尬情況。

但是缺點也是顯而易見,對於消費者 B 而言,這個商品/系統就不具備 Availability 的特性 (因為沒有東西返回)。

CAP-1_System-Design-to-Ensure-Consistency-an-Example

假如我們想要提高系統 Availability 呢? 同樣的例子,參考下圖,做法則是剛好相反。

當 A 使用者僅僅是將商品加入購物車時,資料庫並不會對商品庫存的剩餘數量做出修改,因為實際上商品仍然在庫等待銷售,而當消費者 B 這時也對同樣的商品感興趣,就能夠成功的將商品也加入自己的購物車。這樣的設計邏輯,能夠最大化一件商品的曝光潛力,只要商品仍然在庫,就能夠提取商品資訊。

至於缺點呢,雖然兩個消費者都能將商品放置於購物車,但是畢竟商品只有 1 件!於是最終只能有一位消費者成功買下這個商品。

什麼是 CAP Theorem

所以,什麼是 CAP 定理?

CAP 定理的三個字母意義分別為:

  • Consistency
  • Availability
  • Tolerance to Network Partitions

前兩個定義我們已經提過了, ACID (Consistency) 及 BASE (Availability) 以前是分開來看的,而 Brewer 覺得兩者像是一條光譜的兩端,一邊是系統的 Consistency ,一邊是系統的 Availability。魚與熊掌基本是不可兼得的。

Tolerance to Network Partitions 則是比較有趣的一個新維度, 資料庫大神 Michael Stonebraker 是這麼解釋的:

“If there is a network failure that splits the processing nodes into two groups that cannot talk to each other, then the goal would be to allow processing to continue in both subgroups.”

這是啥意思呢? 回到剛才的商品訂購網站 + 資料庫範例,假如這裡的網站有實際上 n 個網站伺服器 + n 個資料庫主機的一對一配對集成而來,那麼基本上就是一個「分布式系統( Distributed System )」,對於分布式系統而言,一個相當基本的要求就是當系統的一部分癱瘓時,剩餘的系統仍然能夠持續作業,可以想像成其中一組網站 + 資料庫當機時,剩餘的 n-1 個網站/資料庫還能繼續使用。

這個情況就是 Tolerance to Network Partitions ,可以說分布式系統大致都符合 CAP 的這項定義。

這是看起來不怎麼樣卻相當重要的結果,因為 CAP 定理的核心論述為:

“You can have at most two of these properties for any shared-data system.”

C、A、P,對一個資訊系統而言三者只能取其二!而實際上因為現代大型系統多半是分布式設計,使得 Consistency 及 Availability 成為常常無法兼得的兩個重要能力。

現在你應該明白,為什麼跑得快的網站內容有時不即時,絕不出錯的交易系統卻容易無法存取,以及跨國網站上同一時間的不同使用者可能看到不一樣的網站內容了,因為這些都是資訊系統先天限制的一部份。

至於為什麼定理取名 CAP 而不是字首縮寫的 CAT, Brewer 在一封郵件裡承認只是覺得比較好念,有助於行銷罷了。

突破 CAP 定理的資訊系統設計

CAP 定理的存在,似乎設下了資訊系統架構的一道難題,因為俗世眾生最想要的,往往是「又要馬兒跑,又要馬兒不吃草」。有沒有什麼設計策略,可以避開或是減輕 Consistency 及 Availability 之間的牴觸呢?

學者們提供了幾個努力的方向,最常被應用的一個,就是設計混合式系統 (Hybrid System),意思是,一個大型系統的一部分採用 High-Availability 的設計,而另外一些部分則採取 High-Consistency 的作法。

具體應該怎麼區分何時靠向 Availability 何時轉往 Consistency 取決於具體的業務場景,一般來說,靠近前端(網頁或是 UI )比較適合採用High-Availability,而到了後端底層(資料庫)則是天然地需要採用 High-Consistency 的系統。

要說現實生活中 High-Availability 最鮮明的案例各種搜尋引擎 (文本/商品…etc) 可以算是一個,重點是要讓每次搜尋都能快速返回結果,至於是不是每次都搜出一樣的內容或是內容準確或即時性就不是那麼關鍵;而 High-Consistency 的代表就是線上購物付款了,回應速度往往慢吞吞的原因就是為了保證資料高度正確,事實上付款 API 在很多系統裡面都是系統瓶頸的所在。

另一個稍微比較複雜的作法是根據商業條件切割系統特性,例如:

  • By function: DNS 跟 cache system 的要求可能比較類似,兩者又跟 database 比較不同
  • By operation: 例如 read 操作的可用性要求較高; write 操作的一致性要求較高
  • By user type:有些系統的 user 只是需要參考資訊,對於精準度要求不高;另一些高級系統用戶可能對精確資訊的需求較強
  • By data type:靜態資料不常變動,所以可以著重在 availability;交易資料跟錢有關出錯成本很高,必須小心考量 consistency

其他像是運用根據地理區、網路速度等條件來做系統區隔也都是可以考慮的設計作法。

看得完你真是太厲害了,再挑戰一下吧?

 

(Visited 125 times, 3 visits today)

Wendell.Huang

科技公司嫌棄太活潑,消費品牌挑剔太沉悶…, 經常必須解釋自己在學什麼, 不小心就摔破對方眼鏡的業餘書呆子。

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *