系統設計面試:如何設計多區域使用者資料寫入與衝突合併?
題目與場景
一個全球 SaaS 允許使用者在任意區域編輯個人資料。網路分區期間,歐洲和美國區域都接受了同一使用者的更新,恢復後出現姓名、頭像、時區和隱私設定衝突。請設計寫入、複製、衝突偵測、合併、稽核和使用者恢復方案,並說明可用性與一致性的取捨。
面試官考察點
- 能否先區分欄位語義和一致性需求,而不是對整筆記錄使用一個衝突策略。
- 能否設計區域路由、版本資訊、複製延遲和冪等重試。
- 能否處理不可自動合併的隱私或安全欄位,並讓使用者看見可解釋結果。
- 能否在故障恢復、成本、延遲和資料遺失風險之間做清晰取捨。
先問清楚的澄清問題
- 哪些欄位可獨立合併,哪些欄位涉及隱私、身分或安全,必須串行或人工確認?
- 目標是強一致、工作階段一致還是最終一致?使用者能接受多長複製延遲?
- 是否允許同一使用者在多個區域主動寫入,還是可以按使用者或租戶固定主區域?
- 發生衝突時必須保留兩個版本多久,使用者、客服和稽核人員需要看到哪些記錄?
30 秒回答示範
我會先按欄位定義一致性:頭像和簡介可做欄位級合併,隱私與安全設定需要更強的版本檢查。每次寫入帶使用者版本、區域、操作 ID 和欄位變更,複製採用冪等事件。預設按使用者固定主區域降低衝突;必須多活時偵測並發版本,自動合併安全欄位,對敏感欄位產生待確認衝突。結果要寫入不可變稽核日誌,並提供使用者可見的恢復入口。以衝突率、複製延遲、遺失更新率和恢復時間驗證設計。
深入拆解
1. 先做欄位級一致性分類
把資料拆成可交換欄位和安全敏感欄位。顯示名、簡介或頭像通常允許最後寫入或按版本合併,但信箱、MFA、隱私可見性和帳戶狀態可能要求條件寫、單主或人工確認。欄位分類決定資料模型、UI 提示和恢復權限,不能只依賴資料庫的整行時間戳。
2. 選擇單主、分區主或多主路由
最簡單的方案是按使用者或租戶固定主區域,其他區域就近讀並在故障時暫時接管。若業務必須多主寫入,要接受衝突偵測和合併成本。路由層應攜帶區域和版本資訊,故障切換要有租約或明確的接管 epoch,避免舊主恢復後繼續寫入產生回放衝突。
3. 設計版本、事件和冪等
每個欄位或欄位組保存版本向量、區域、邏輯時間和最後操作 ID。寫入條件應驗證用戶端基於的版本仍然有效;重試使用操作 ID 去重。複製事件包含舊版本、新版本和變更欄位,重複到達、亂序到達和延遲到達都不會重複套用或覆蓋更新。
4. 定義衝突偵測與自動合併
兩個版本互不包含對方時才是並發衝突。無交集欄位可以合併;同一欄位要按業務策略選擇保留主區域、最後寫入或產生衝突。不要把牆上時鐘直接當作使用者意圖;時鐘偏差可能讓較舊內容勝出。每次合併都記錄規則、來源版本和結果。
5. 保護隱私和安全欄位
隱私可見性、信箱、登入方式和 MFA 不能使用普通最後寫入策略。可以要求條件寫、單主授權或人工確認,並在衝突期間保持更保守的可見性。恢復介面必須驗證操作者身分、理由和權限,防止「解決衝突」成為越權修改路徑。
6. 讓恢復和可觀測性成為一等能力
保存衝突前後版本、事件鏈和合併決定,提供使用者撤銷或選擇版本的入口。監控衝突率、複製延遲、版本滯留、遺失更新、人工處理時長和區域切換次數。演練區域隔離、舊主復活、重複事件和資料回放,確保恢復流程不會產生第二次覆蓋。
一份更完整的強回答
我會先按欄位分類一致性,給隱私和安全欄位更嚴格的條件寫或單主策略。預設按使用者固定主區域,其他區域就近讀;若必須多主寫入,每次變更攜帶區域、版本、操作 ID 和欄位集合,複製事件冪等且可處理亂序。偵測並發版本後,對無交集欄位自動合併,對同欄位按業務規則或使用者確認處理,絕不把牆上時鐘當作意圖。所有版本、合併規則和操作者寫入稽核日誌,監控衝突率、延遲、遺失更新與恢復時長,並演練舊主復活和重複事件。
常見失分點
- 對整筆使用者資料使用統一的最後寫入獲勝,覆蓋隱私或安全變更。
- 只說「用版本向量」,沒有說明欄位粒度、儲存成本和衝突後的使用者體驗。
- 忽略重複、亂序、延遲複製和舊主復活,導致恢復時再次覆蓋。
- 沒有操作 ID、稽核記錄和使用者撤銷入口,無法解釋或修復錯誤合併。
- 只談可用性和延遲,不衡量遺失更新、衝突率和人工處理成本。
追問與延伸
追問一:為什麼不直接用最後寫入獲勝?
它簡單且能收斂,但牆上時鐘不代表使用者意圖,時鐘偏差會讓較舊內容覆蓋較新內容。對低風險欄位可接受,對隱私、安全和高價值內容應使用條件寫、單主或顯式衝突。
追問二:固定主區域會不會降低可用性?
會增加跨區域寫延遲,並在主區域故障時需要接管流程,但顯著減少衝突和營運複雜度。可以按租戶選擇主區域、提供臨時接管 epoch,並把可用性目標與資料安全要求一起評估。
追問三:怎樣向使用者展示衝突?
顯示欄位、兩個版本的來源和更新時間,解釋為何需要選擇;敏感欄位預設保守,不把內部區域或資料庫術語直接暴露。提供撤銷、重試和聯絡客服路徑,並記錄使用者選擇。
追問四:複製延遲很高時如何處理讀取?
返回版本或區域水位,讓用戶端知道資料新鮮度;關鍵寫後讀可路由到寫入區域,普通讀取接受最終一致。超過閾值時告警、限制高風險變更或引導使用者切換到主區域。