マスター・マスター レプリケーション
Master-Master Replication
両方(以上)のマスターが読み書きを受け付け、互いに変更を同期し合う構成。片方が落ちても書き込みを続けられるが、書き込み競合の解決という難問が生じる。
master-slave との違い(まずここ)
- master-slave: 書けるのは1台(マスター)だけ。スレーブは読み専用。→ 書き込みはスケールせず、マスター障害で書けなくなる。
- master-master: 複数台が書ける。互いに同期し合う。→ 書き込みの可用性が上がる(1台落ちても書ける)。
図を描画中...
一番の難所: 書き込み競合
両方が書けるということは、同じデータを同時に別の値へ書いてしまう事故が起きえます。
例: マスター1で在庫を『残り0』に、ほぼ同時にマスター2で『残り1』に更新。さて、正解はどっち?
これを**競合解決(conflict resolution)**といい、master-masterの最大の難しさです。解決方針には『後に書いた方を採用(last write wins)』『タイムスタンプで判断』『アプリでマージ』などがありますが、どれも完璧ではありません。
図を描画中...
同期 vs 非同期のジレンマ
- 同期レプリケーション: 全マスターに書き終わってから完了を返す。整合性は保てるが、待つので書き込みが遅い。
- 非同期レプリケーション: 自分に書いたら即完了を返し、裏で他へ伝播。速いが、伝播前は他のマスターと値が食い違う(緩い整合性 = ACIDを部分的に諦める)。
つまずきポイント
- master-masterは『書き込みもスケール・可用化できる魔法』に見えるが、競合解決の複雑さという大きな代償がある。安易に台数を増やすと競合が増える。
- どちらのマスターに書くかを振り分けるロジック(LBやアプリ側)も必要。master-slaveより構成も運用も重い。
- 多くの実務では、まずmaster-slaveで読み取りをスケールし、書き込みのスケールが本当に必要になってからsharding等を検討することが多い。