題幹與適用場景
系統有多個保存同一業務資料的節點,節點之間可能網路分割。面試要求解釋 Consistency、Availability、Partition tolerance,並落到訂單、庫存或社交動態的具體行為。回答不能只背「只能選兩個」,還要說明分割時使用者看到什麼、哪些寫入被接受與恢復後如何收斂。
面試官考察點
面試官會看你是否知道取捨發生在分割期間,能否把一致性定義為讀到最新寫入,把可用性定義為每個請求得到回應,並說明分割容錯是分散式網路的現實約束。高品質回答會連接業務風險、降級、衝突、監控與恢復。
回答前需要釐清的問題
- 一致性是線性一致、工作階段一致,還是允許短暫陳舊?
- 可用性是全部請求成功,還是允許明確可重試錯誤?
- 分割時哪些操作必須阻斷,例如扣庫存、扣款與取消訂單?
- 是否允許本地暫存、冪等重試、衝突合併或人工仲裁?
- 恢復目標是零遺失、單調收斂,還是有補償時間窗?
30 秒回答框架
CAP 討論網路分割存在時,系統不能同時保證強一致與對所有請求可用;P 是面對分割仍運作的約束。我會先按業務定義不可接受錯誤:扣款與庫存寧可回傳可重試錯誤,動態內容可短暫陳舊。再說明冪等、衝突日誌、恢復重播與指標,避免把資料庫宣稱為永久「既 CP 又 AP」。
分步深入解答
第一步:準確說明三個術語
一致性要求讀取符合系統承諾,強一致常指讀到最新完成寫入;可用性要求每個請求在合理時間收到非錯誤回應;分割容錯表示節點通訊遺失或延遲無界時仍能處理部分工作。CAP 的關鍵情境是 P 已發生。
第二步:建立分割時序
假設東京與新加坡節點無法通訊。若兩邊都接受同一帳戶相反寫入並立即回應,之後可能衝突,無法保證強一致;若只讓一側寫入或雙方拒絕不確定操作,就犧牲部分可用性。先畫時序再談選型。
第三步:按業務風險選行為
庫存、付款與唯一名稱要避免雙寫,分割時可回傳稍後重試或排隊。按讚、閱讀數與推薦列表通常可接受陳舊與非同步合併。選擇由錯誤成本決定,而非只看 AP/CP 標籤。
partitioned:
if operation == payment_or_inventory:
reject_or_queue_with_idempotency_key()
else:
serve_stale_read_and_record_reconciliation()第四步:定義寫入與衝突策略
可重試寫入帶冪等鍵與版本。多地寫入時記錄來源、邏輯時間與證據;恢復後按業務規則合併、補償或人工處理。支付與庫存不能用最後寫入獲勝掩蓋衝突。
第五步:說明恢復流程
分割恢復後交換日誌與版本,檢測缺口與重複,再順序重播可重試事件。未決訂單要有明確狀態,避免重複付款。恢復過程需要速率限制、死信與人工隊列。
第六步:連接驗證指標
記錄分割時間、拒絕率、陳舊時長、衝突數、補償成功率與重複請求率。以故障注入測試讀、寫、重試、恢復與跨區延遲,確認文案與實際狀態一致。
設計取捨與邊界
CAP 不等於所有系統只能選兩個字母
分割期間才在一致性與可用回應間選行為;正常狀況還要討論延遲、成本、耐久性與運維。把 CAP 當資料庫永久標籤會掩蓋請求級策略。
一致性強度要寫清楚
「一致」可能指線性、因果、工作階段或最終收斂。先定義讀寫保證,再討論節點與協定,避免契約不同卻使用同一詞。
落地計畫與證據
需求到策略映射
為付款、庫存、訂單狀態、搜尋與社交計數分別寫出分割行為、文案、重試邊界與恢復動作,並映射到介面與資料模型。
故障演練
演練單向斷網、延遲、重複訊息與部分恢復。核對最終回應、冪等記錄、衝突隊列、補償帳務與告警,演練後清除測試資料並復核稽核日誌。
常見誤區與追問
誤區:說 CA 系統能抵抗網路分割
CA 只在不考慮分割的理想條件描述一致性與可用性;真實跨節點系統要處理通訊失敗。
誤區:把可用性等同永遠成功
可用性是及時回應的保證,錯誤、排隊或明確重試也可能是業務選擇,重點是契約清楚。
誤區:用最後寫入覆蓋所有衝突
付款與庫存衝突不能簡單覆蓋;需要冪等、版本、補償或人工仲裁。
追問:為什麼 P 通常不可選?
跨區網路會分割或出現不可接受延遲,放棄 P 等同通訊失敗時停止分散式服務。
追問:如何證明取捨正確?
提出分割演練、使用者狀態、衝突與補償指標,並說明何時回滾策略。