コンピューターサイエンス:アルゴリズム / OS / ネットワーク / DB
レプリケーション
レプリケーション
このレッスンで分かること
- Primary / Replica 構成の役割分担
- 同期・準同期・非同期レプリケーションの違い
- レプリカラグが引き起こす問題と対策
レプリケーション とは
Primary / Replica 構成での読み取り分散と整合性。本レッスンでは、レプリケーション の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
レプリケーションとは
レプリケーション (Replication) とは、1 台のデータベース (Primary) の変更を 複数のコピー (Replica) にリアルタイムに反映する仕組みです。
目的は次の 3 つです。
- 読み取りスケール — Replica に SELECT を分散
- 可用性 — Primary が落ちても Replica が引き継げる (
Failover) - バックアップ・分析用途 — Replica で重い分析クエリを走らせる
どう同期されるか
Primary の変更は WAL (Write-Ahead Log) や Binlog (MySQL) という変更ログに記録され、これを Replica に転送して 再適用 することで同期します。
ログ転送方式は次の 2 系統があります。
- 物理レプリケーション — ディスクページの変更そのものを転送 (PostgreSQL のストリーミングレプリケーション)
- 論理レプリケーション — SQL 文や行変更を転送 (PostgreSQL の publication/subscription、MySQL のレプリケーション全般。Row-based・Statement-based はいずれも binlog を用いた論理レプリケーション)
物理は速いが Primary と Replica のバージョンを揃える必要があり、論理は遅いがバージョン差や部分レプリカに柔軟。
3 つのモード
同期レプリケーション (Synchronous)
Primary は 全 Replica が書き込み完了するまで COMMIT を待ちます。
- 一貫性は完璧(コミット済みデータは必ず全 Replica にある)
- 1 台でも遅い Replica があれば全体が遅くなる
- ネットワーク障害で Primary も止まる
金融や予約システムなど、整合性が最優先の場面で使います。
準同期 (Semi-Synchronous)
Primary は 少なくとも N 台の Replica が受信した時点で COMMIT 完了とします。MySQL の準同期はこの方式で、よく N=1 で運用されます。
- パフォーマンスと安全性のバランスが良い
- 1 台落ちても残りで継続可能
非同期 (Asynchronous)
Primary は WAL を送信したらすぐ COMMIT 完了。Replica は遅れて追いつきます。
- 速い(Primary の性能ほぼそのまま)
- Primary 障害時、未転送分が失われる可能性
- レプリカラグが発生する
デフォルトのレプリケーションはほぼ非同期です。
レプリカラグの問題
非同期で起きるのが レプリカラグ (Replication Lag) です。Primary に書いた直後に Replica から読むと、まだ反映されておらず古いデータが返ります。
プレーンテキスト
T1: Primary INSERT user (name='Alice') -- 成功
T2: Replica SELECT user WHERE name='Alice' -- 0 件 ← ラグで未到着これでユーザーの登録直後に「ユーザーが見つかりません」というエラーが起きると体験が壊れます。
対策
- 書き込み直後の読み取りは Primary に向ける — セッションごとに「書き込みフラグ」を持ち、その後の SELECT は Primary
- 同期 / 準同期に切り替える — 遅延を許容できない場面
- Read Your Writes 保証 — ユーザー本人の書き込みは本人が確実に読めるよう、専用ロジックを書く
- アプリ側で再試行 — 数百ミリ秒待って再 SELECT
レプリカラグは「ある」前提で設計する。「ない」前提だと事故る。
フェイルオーバー
Primary が落ちたら Replica の 1 つを Primary に昇格 させます。これを フェイルオーバー と呼びます。
自動フェイルオーバーには専用ツールが必要です。
- PostgreSQL — Patroni、repmgr
- MySQL — MHA、Orchestrator、ProxySQL
- クラウド — RDS の Multi-AZ、Aurora の自動フェイルオーバー
フェイルオーバー時には、未転送のトランザクションが失われたり、DNS / IP の切り替えに数秒〜数分かかります。
読み書き分離
アプリ側で「書き込みは Primary、読み取りは Replica」と振り分けるのが定石です。
JavaScript
const writePool = mysql.createPool({ host: 'primary.example.com' });
const readPool = mysql.createPool({ host: 'replica.example.com' });
await writePool.query('INSERT INTO ...');
const rows = await readPool.query('SELECT FROM ...');ORM やルーター(ProxySQL、PgBouncer)が透過的に振り分ける機能もあります。
カスケードレプリケーション
Replica からさらに別の Replica にレプリケーションする構成です。
プレーンテキスト
Primary → Replica A → Replica A の子 ReplicaPrimary の負荷を抑えられる一方、ラグが二重になります。地理分散構成でよく使われます。
やってみよう
- Docker Compose で MySQL の Primary 1 台 + Replica 1 台を立てる
- Primary に INSERT し、Replica で SELECT して反映時間を計測する
- Replica の
SHOW REPLICA STATUS(旧SHOW SLAVE STATUS) でSeconds_Behind_Sourceを確認する
よくある質問
Q. このトピックは実務でどう役立ちますか?
A. DB のクエリ最適化、API 設計、データ構造の選択など、設計判断の根拠になります。表面的にライブラリを使うだけでなく「なぜそれが速いのか」を理解できると、性能問題を未然に防げます。コーディング面接でも頻出のテーマです。
Q. 計算量はどう求めれば良いですか?
A. ループのネストごとに掛け算する、再帰なら漸化式から解く、というのが基本です。Big-O 表記は定数倍と低次の項を無視するため、n の指数(n²、n log n など)に注目してください。最悪・平均・最良の 3 つを意識すると説得力が増します。
Q. 覚えるべき定番アルゴリズムは何ですか?
A. 二分探索、クイックソート/マージソート、BFS/DFS、ダイクストラ、DP の基本問題(フィボナッチ・ナップサック)が必修です。これらを「白紙から書ける」状態にすると、応用問題が一気に解けるようになります。
次のレッスン
次は シャーディング で、Primary / Replica 構成での読み取り分散と整合性 を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- レプリケーション の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. レプリケーション とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン