最常見的複製拓撲:一個 leader 接受所有寫入,followers 複製其變更日誌。難點不在「怎麼複製」,而在同步還是非同步、以及隨之而來的一致性與容錯取捨。
🧠 Intuition
TIP
把它想成「一份權威帳本 + 幾份抄本」。寫只進帳本(leader),抄本(follower)照著流水帳重放。所有麻煩都來自一個問題:回覆客戶端「成功」之前,要等幾份抄本抄完?
- 寫入只走 leader,leader 把變更寫進 replication log(如 WAL / row-based / statement-based)。
- followers 拉取並重放該 log,從而追上 leader 的狀態。
- 讀可以走 followers(讀擴展),但會讀到稍舊的資料(複製延遲)。
⚖️ Tradeoffs
同步複製 — 不丟資料,但脆
- leader 等至少一個 follower 確認才回覆成功。
- 優點:該 follower 保證有最新資料,leader 掛了可無損切換。
- 缺點:任一同步 follower 慢/掛,寫入就卡住。實務用半同步:只要一個 follower 同步,其餘非同步。
非同步複製 — 快,但可能丟尾巴
- leader 不等 follower,寫完本地就回成功。
- 優點:寫延遲低、不被慢 follower 拖累。
- 缺點:leader 在變更傳出去前崩潰,那段已回覆成功的寫入會永久遺失。
- 絕大多數高吞吐系統的預設。
複製延遲的三個經典異常
- 讀己之寫 (Read-your-writes):剛寫完讀 follower 卻看不到自己的更新 → 對「自己的資料」改讀 leader。
- 單調讀 (Monotonic Reads):連讀兩次,第二次反而更舊 → 同一使用者固定讀同一個 replica。
- 一致前綴讀 (Consistent Prefix):看到果在因之前 → 因果相關的寫入要路由到同一分區。
故障切換 (Failover) 的坑
- 偵測 leader 死亡(逾時)→ 選新 leader → 重新導向寫入。
- 風險:非同步下新 leader 落後,舊 leader 復活造成腦裂 (split brain);逾時設太短會誤判。
🔑 Takeaways
- 單主複製的核心旋鈕只有一個:回成功前等幾份抄本——同步保資料、非同步保速度,半同步是實務折衷。
- 讀走 follower 能擴展讀,但要正視複製延遲三異常:用「讀己之寫 / 單調讀 / 一致前綴」對應的路由規則修補。
- Failover 真正的難點不是切換動作,是腦裂與資料落後;逾時與 fencing 要設計好。
- 寫無法靠加 follower 擴展(寫只進 leader)——寫擴展要靠分片,不是複製。
2026-07-01
- Q: 既然非同步會丟資料,為什麼還是大多數系統的預設?
- A: 因為同步複製把「寫入可用性」綁死在「最慢的 follower」上——一台抄本變慢,整個寫入路徑就停擺,這在多副本、跨機房時幾乎必然發生。實務折衷是半同步:保證至少一份同步抄本(不丟資料),其餘非同步(不被拖慢)。純非同步則是賭「leader 崩潰且尾巴還沒傳出去」這個窗口夠小,用可用性換掉那一點點持久性。