Quorum 讀寫 (Quorum Reads & Writes)

★★★★Draft

FromDDIA

📚 From the Books

Quorum 讀寫 (Quorum Reads & Writes)ConceptConsistency & Consensus

無主(leaderless)複製沒有 failover,客戶端直接對多個副本寫、也對多個副本讀。要在「不等所有副本、又不讀到舊值」之間取得平衡,靠的是一條簡單的不等式:w + r > n。它不是萬靈丹——理解它保證什麼、又在哪些邊界失效,才是重點。

🧠 Core Ideas

TIP

n 個副本,一次寫入要 w 個節點確認、一次讀取要查 r 個節點。只要 w + r > n,讀取的節點集合就一定與最近一次成功寫入的節點集合重疊——那個重疊的節點握有最新值,所以讀取至少能看到一個新版本,再靠版本號挑出它。

⚖️ w + r > n 保證什麼、不保證什麼

為什麼相交就夠
  • 寫入在 w 個節點落地、讀取查 r 個節點。若 w + r > n,兩個集合在 n 個節點裡不可能不相交(鴿籠原理)。
  • 相交的那個節點同時見過最新寫入與這次讀取,因此讀取結果裡一定含最新值。
  • 客戶端平行讀多個副本,拿版本號最高的為準;落後的副本再用 read repair 補回。
即使 w + r > n,仍可能讀到舊值的邊界情況

DDIA 列出幾種 strict quorum 仍失守的場景:

  • sloppy quorum 時,w 個寫入與 r 個讀取可能落在完全不同的節點上,兩集合不再保證相交。
  • 兩個寫入並行發生、先後無法判定;若用 LWW 合併,時鐘偏差可能讓某次寫入被默默丟掉。
  • 寫入與讀取同時發生,寫入可能只反映在部分副本。
  • 寫入在部分副本成功、其他失敗(如磁碟已滿),成功的副本不回滾;後續讀取拿不拿得到這次寫入,不確定。
  • 攜帶新值的節點故障,從攜帶舊值的副本恢復,使持有新值的副本數掉到 w 以下。

所以 Dynamo 風格資料庫通常針對最終一致性最佳化,而非把 quorum 當成 strong consistency。要真正的線性一致得靠共識,不是 quorum。

⚖️ 讓副本收斂:Read Repair 與 Anti-Entropy

兩種補償機制

無主系統沒有 leader 主動推送變更,靠兩個機制讓落後副本最終追上:

  • Read repair:客戶端平行讀取時發現某副本回傳舊值,就把新值寫回那個副本。適合經常被讀到的資料——冷門資料可能長期不被修復。
  • Anti-entropy process:背景程式持續比對副本間差異、把缺的資料補過去。與單主複製不同,它不保證複製順序,且可能有顯著延遲。

⚖️ Sloppy Quorum 與 Hinted Handoff

用可用性換一致性
  • 大型叢集(節點數遠大於 n)遇網路問題時,客戶端可能連不到指定的那 n 個節點。兩個選擇:對達不成 quorum 的請求回錯誤,或接受寫入、先塞進 n 之外任何可達的節點——後者就是 sloppy quorum
  • Hinted handoff:網路恢復後,暫時收留寫入的節點把資料送回原本「正確」的節點。
  • 效果:只要有任意 w 個節點可用就能寫,寫入可用性提高。代價:即使 w + r > n 也不保證讀到最新值——最新值可能還暫存在 n 以外的節點上。
多資料中心的無主複製
  • Cassandra、Voldemort 在無主模型下支援多資料中心:n 個副本分散於多個資料中心,寫入送往所有副本,但只等本地資料中心的 quorum 確認。
  • 跨資料中心的複製在背景非同步進行——本地低延遲、跨區容錯,兩者兼得。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading