Chuyển đến nội dung chính

レッスン 10: データベース レプリケーション - マスター/スレーブおよびマスター/マスター

レプリケーションとは何ですか?なぜレプリケーションが必要なのでしょうか?同期レプリケーションと非同期レプリケーション。マスター/スレーブ: リードレプリカ、フェイルオーバー、プロモーション。マスター-マスター: 競合解決、スプリットブレイン。レプリケーション ラグとその対処方法。 PostgreSQL ストリーミング レプリケーションの実践。

🏗️ アーキテクチャ — レッスン 10 レッスン 10: データベースのレプリケーション - マスター-スレーブ & マスター-マスター

システムアーキテクチャ: ゼロからヒーローへ

パート 3: データベース アーキテクチャとデータ管理

xdev.asia

はじめに

単一のデータベース サーバーは 単一障害点 となります。クラッシュするとシステム全体がクラッシュします。データベース レプリケーションは、データを複数のサーバーにコピーすることでこの問題を解決します。


1. なぜレプリケーションが必要なのでしょうか?

目標レプリケーションがどのように役立つのか
高可用性マスターが失敗する → スレーブが引き継ぐ
読み取りスケーリング読み取りを複数のレプリカに分散する
データの局所性ユーザーの近くのレプリカ (待ち時間を短縮)
バックアップ「ホットバックアップ」としてのレプリカ
分析レプリカで大量のクエリを実行し、運用環境に影響を与えません

2. 同期レプリケーションと非同期レプリケーション

2.1 同期

Client → Master: INSERT INTO orders (...)
Master → Replica 1: "Replicate this!"
Replica 1 → Master: "Done!"
Master → Replica 2: "Replicate this!"
Replica 2 → Master: "Done!"
Master → Client: "INSERT success"

Đảm bảo: Tất cả replicas có data trước khi confirm
Nhược điểm: Chậm (phải đợi tất cả replicas)

2.2 非同期

Client → Master: INSERT INTO orders (...)
Master → Client: "INSERT success"  ← Return ngay!
Master → Replica 1: "Replicate this" (async)
Master → Replica 2: "Replicate this" (async)

Ưu điểm: Nhanh (không đợi replicas)
Rủi ro: Master crash trước khi replicate → data loss

2.3 準同期

Client → Master: INSERT
Master → Replica 1: Sync (đợi 1 replica confirm)
Master → Client: "Success"
Master → Replica 2: Async (replicate sau)

→ Cân bằng giữa durability và performance
→ PostgreSQL: synchronous_commit = on (1 replica)

3. マスター - スレーブ (プライマリ - レプリカ)

3.1 アーキテクチャ

                    Writes
  Client ───────────────────► Master (Primary)
                                │
                      Replication│ Stream
                    ┌───────────┼───────────┐
                    ▼           ▼           ▼
                ┌───────┐  ┌───────┐  ┌───────┐
     Reads ────►│Slave 1│  │Slave 2│  │Slave 3│
                │(Read) │  │(Read) │  │(Read) │
                └───────┘  └───────┘  └───────┘

3.2 フェイルオーバープロセス

Normal:
  App ──write──► Master ──replicate──► Slave 1, 2, 3
  App ──read───► Slave 1, 2, 3

Master fails:
  1. Detect: Health check fails (timeout 30s)
  2. Elect: Chọn Slave có data mới nhất → Promote
  3. Reconfigure: Các Slaves khác trỏ về new Master
  4. Update: App connection string → new Master

  App ──write──► Slave 1 (now Master)
  App ──read───► Slave 2, 3

Timeline:
  T=0:    Master crash
  T=30s:  Detected (health check timeout)
  T=35s:  Slave 1 promoted
  T=40s:  Connections reconfigured
  → Downtime: ~40 giây

3.3 レプリケーションの遅延

Vấn đề:
  T=0:   User update profile (write → Master)
  T=0.1: User refresh page (read → Slave)
  Slave chưa có data mới → User thấy data cũ!

  "Tôi vừa update avatar mà sao vẫn thấy avatar cũ?"

解決策:

1. Read-after-write consistency:
   Sau khi write, read từ Master (trong vài giây)

2. Monotonic reads:
   User luôn đọc từ cùng 1 Slave

3. Causal consistency:
   Track version, đảm bảo read ≥ write version

4. Tăng tốc replication:
   Parallel replication, minimize network latency

4. マスター-マスター (マルチプライマリ)

4.1 アーキテクチャ

  Client A ──write──► Master 1 ◄──sync──► Master 2 ◄──write── Client B
                        │                    │
                   Read + Write         Read + Write

4.2 競合の解決

Vấn đề:
  T=0: Master 1: UPDATE user SET name='John'
  T=0: Master 2: UPDATE user SET name='Jane'
  → Conflict! Tên nào đúng?

Strategies:
  1. Last Write Wins (LWW):
     So sánh timestamp, write mới nhất thắng
     Đơn giản nhưng có thể mất data

  2. Application-level resolution:
     App quyết định merge strategy
     Phức tạp nhưng chính xác

  3. CRDT (Conflict-free Replicated Data Types):
     Data structure tự động merge
     Ví dụ: Counter → Tổng tất cả increments

4.3 スプリットブレイン問題

Vấn đề:
  Network partition giữa Master 1 và Master 2
  Cả 2 đều nhận writes → Data diverge

  Master 1: user.balance = 1000 - 500 = 500
  Master 2: user.balance = 1000 - 300 = 700
  
  Network recovered: balance = 500? 700? 200? 

Giải pháp:
  - Quorum-based writes (majority phải đồng ý)
  - Fencing tokens (chỉ 1 master active)
  - External coordination (Zookeeper, etcd)

5. PostgreSQL ストリーミング レプリケーション

5.1 セットアップマスター(postgresql.conf)

# Master configuration
wal_level = replica
max_wal_senders = 5
wal_keep_size = 1GB
synchronous_standby_names = 'replica1'

5.2 レプリカのセットアップ

# Tạo base backup từ Master
pg_basebackup -h master-host -D /var/lib/postgresql/data \
  -U replication -Fp -Xs -P -R

# -R: Tạo standby.signal và postgresql.auto.conf tự động

5.3 レプリケーションの監視

-- Trên Master: kiểm tra replicas
SELECT client_addr, state, sent_lsn, write_lsn,
       flush_lsn, replay_lsn,
       pg_wal_lsn_diff(sent_lsn, replay_lsn) AS lag_bytes
FROM pg_stat_replication;

-- Trên Replica: kiểm tra lag
SELECT now() - pg_last_xact_replay_timestamp() AS replication_lag;

6. 自動フェイルオーバーツール

ツールデータベース説明
パトローニポストグレSQLetcd/ZooKeeper による HA クラスター管理
PgBouncerポストグレSQL接続プーラー + フェイルオーバー
オーケストレーターMySQLトポロジー管理 + 自動フェイルオーバー
MHAMySQLマスター高可用性マネージャー
レディ センチネルレディスRedis の自動フェイルオーバー

概要

トポロジ書き込み読み取り複雑さ使用例
シングル1サーバー1サーバー低い開発、小規模アプリ
マスタースレーブマスターのみマスター+スレーブ中読み取り負荷の高いアプリ
マスターマスター両方両方高マルチリージョン、高書き込み

演習

  1. レプリケーション設計: 電子商取引は 90% 読み取り、10% 書き込み、50K QPS です。レプリケーション トポロジを設計します (マスターとスレーブの数はいくつですか?)。

  2. レプリケーション ラグ: システムには 500 ミリ秒のレプリケーション ラグがあります。ユーザーはパスワードを変更して再度ログインしました。ログイン クエリがスレーブに届いた場合 (新しいパスワードがまだない場合)、ユーザーはログインできません。ソリューション設計。

  3. フェールオーバー計画: PostgreSQL マスター/スレーブ クラスターのフェールオーバー Ru​​nbook を作成します。検出、決定、実行、検証が含まれます。