無主複製 (leaderless) 的招牌做法:寫
w份、讀r份,只要w + r > n讀寫副本集合就保證有交集,於是「讀至少看得到一份最新寫」。聽起來像強一致,但它既非線性一致、嚴格說連單調都不保證——它本質上是「最終一致 + 機率性的新鮮度」。
🧠 Intuition
TIP
w + r > n 只保證讀寫副本必有交集,不保證你能認出交集裡哪份才是最新值,也不保證並發/失敗中的寫入會乾淨呈現。它給的是「鴿籠原理級」的存在性保證,不是線性一致的即時性保證。
- 最終一致 (eventual consistency):停止寫入後,所有副本終將收斂到同值——但「終將」沒有時限。
- Quorum 在收斂之上多給一層:用
w + r > n提高「讀到夠新的值」的機率,並靠讀修復 / anti-entropy 推動收斂。 - 它是 Dynamo 風格 (Cassandra、Riak) 的核心:拿可用性與低延遲,換掉強一致。
⚖️ Tradeoffs
w + r > n 給的保證 — 與它的盲點
- 保證:讀寫副本集合相交,所以一次讀至少觸及一個含最新寫的副本。
- 盲點 1(辨識):讀到多個版本時要靠版本號/時間戳挑最新——時鐘偏差或缺版本向量就可能挑錯。
- 盲點 2(並發寫):兩個並發寫各達 quorum,最後是 LWW (last-write-wins) 丟資料,或留多版本要應用解衝突。
- 盲點 3(部分失敗):寫只成功在部分副本(未達 w)卻沒回滾,後續讀可能一下看到、一下看不到。
最終一致的語意 — 「終將」有多弱
- 唯一硬承諾:沒有新寫入時,副本最終收斂。對「多久」「過程中讀到什麼」幾乎零保證。
- 過程中可能:讀到舊值、讀到比上次更舊的值(回退)、不同 client 看到不同順序。
- 這些異常在低負載時罕見、易被忽略,卻會在故障 / 高延遲時集中爆發——是最危險的「看起來能用」。
Session 保證 — 把弱一致補強成「對單一使用者合理」
- 讀己之寫 (read-your-writes):自己寫完,自己後續讀一定看得到——避免「我剛改完卻顯示沒改」。
- 單調讀 (monotonic reads):讀到新值後不再讀回舊值——避免時光倒流。
- 單調寫 (monotonic writes):同一 client 的寫入按序生效。
- 這些是以單一 session 為界的保證,比全域因果弱,但能用「黏同一副本 / 帶版本戳」便宜地實作。
為何 quorum 仍非線性一致
- 並發:兩個並發讀落在不同副本,可能一個看到新值、一個看到舊值——違反「讀到新值後全體不回退」。
- 未完成的寫:寫入進行中(達了部分副本但未確認),交錯的讀會時新時舊,沒有單一生效瞬間。
- 無同步讀修復:交集只保證「存在」最新副本,不保證讀操作回傳它;要近似線性一致得加同步讀修復或 quorum 讀時修復。
- 結論:quorum 是機率性新鮮度,線性一致是確定性即時序,本質不同。
🔑 Takeaways
w + r > n只保證讀寫副本集合相交,給的是存在性/機率性新鮮度,不是即時性。- 最終一致唯一硬承諾是「停寫後收斂」,過程中可舊可回退——故障時集中爆發。
- Session 保證(讀己之寫、單調讀/寫)是便宜的補丁,把弱一致補強到「對單一使用者合理」。
- Quorum 不是線性一致:並發讀、未完成寫、無同步讀修復都會破壞 recency——要強一致請上共識。
2026-07-01
- Q: 既然
w + r > n保證交集,那把 r 拉大、讀很多副本,是不是就等於線性一致了? - A: 不會。交集只保證讀觸及到含最新寫的副本,但兩個並發讀可能各自落在不同的合法 quorum、看到不一致的版本;而且寫入若還在進行(部分副本完成),讀會看到時新時舊的中間態,沒有單一「生效瞬間」。要逼近線性一致,得在讀路徑加上同步讀修復(讀到舊副本就當場寫回最新),把多次讀之間的回退堵死——但那已經超出純 quorum 的範疇了。