CAP 定理(CAP theorem)
/ CAP /
假設你在好幾台機器上跑一個服務,每台都保有同一份資料的副本,這樣即使一台機器死了、服務仍維持可用。現在你兩群機器之間的一條網路線被剪斷了——兩群都還能各自服務使用者,但它們再也無法彼此對話。一位顧客在左邊那群更新了自己的地址。右邊那群還沒聽到這次更新,它該回應一個查詢該地址的請求嗎?CAP 定理(以 Eric Brewer 命名)說你躲不掉這個兩難:當網路被分裂時,你必須選擇。
CAP 點名了三個令人嚮往的性質。一致性(C):每次讀取都看到最新的寫入,所以所有副本看起來都一樣——每個人對資料都意見相同。可用性(A):每個請求都得到一個(非錯誤的)答案,系統總是會回應。分區容忍性(P):即使網路在節點之間丟棄訊息,系統仍持續運作。這個定理真正的內容很犀利:當分裂(P)真的發生時,你無法同時擁有 C 與 A。你要嘛在「可能過時」的那一側拒絕回答(選了一致性、犧牲可用性),要嘛用「可能是舊的」資料回答(選了可用性、犧牲一致性)。流行的口號「三選二」是一種簡化;誠實的版本是「在分裂期間,選 C 或選 A」。
為什麼重要,以及常見的誤讀:CAP 逼你做出一個明確的、商業層級的決定。一個銀行餘額最好選一致性(寧可顯示錯誤,也不要顯示錯的餘額),而一個社群動態牆可以選可用性(寧可顯示一則稍微過時的貼文,也好過什麼都不顯示)。有兩點值得平白說清楚:第一,分裂在真實世界並非可選——網路就是會失效——所以 P 基本上是必備的,這正是為什麼真正的選擇是在 C 與 A 之間。第二,當沒有分裂時,一個蓋得好的系統可以同時提供強一致性與高可用性;CAP 只在失效期間才逼你取捨。CAP 也是個粗略的、入門等級的視角:更細的模型(如 PACELC)補充說,即使沒有分裂,你仍在延遲與一致性之間取捨。
一個購物車被複製在兩個資料中心,而它們之間的連線失效了。一個 CP 的選擇:被切斷那個中心裡的購物車在連線修復前都回傳錯誤,這樣你永遠不會看到一個錯的購物車。一個 AP 的選擇:兩個中心都繼續接受變更,等連線修復時、它們的購物車必須被合併——你維持了可用性,但短暫地冒了不一致的險。兩者都沒有「對」;要看產品是什麼。
在網路分裂期間你必須選擇:保持一致(拒絕回答)或保持可用(冒過時的險)。
當心那種偷懶的讀法「三個任選兩個」。分裂是生活的現實,所以 P 是被迫的;真正的選擇是 C 對上 A,而且只在分裂持續期間才成立。沒有分裂時,你兩個都能有。