272. 멀티 마스터 (Multi-Master) 복제

핵심 인사이트 (3줄 요약)

  1. 본질: 멀티 마스터(Multi-Master) 복제는 두 개 이상의 노드가 모두 쓰기를 받을 수 있는 복제 아키텍처로, 각 마스터가 다른 마스터의 쓰기를 비동기적으로 복제한다.
  2. 가치: 쓰기 부하를 분산시키고, 특정 마스터 장애 시에도 다른 마스터가 쓰기를 受入れる어 가용성을 높이며, 쓰기 집중 환경에 효과적이다.
  3. 융합: 쓰기 충돌, 충돌 해결, 비동기식 복제, CAP 정리, 최종 일관성과 밀접하게 연관된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

개념 정의

멀티 마스터(Multi-Master) 복제는 두 개 이상의 노드가 모두 쓰기 요청을 받을 수 있는 복제 아키텍처이다. 각 마스터 노드는 쓰기를 受入れて 로컬에 적용하고, 다른 마스터에게 비동기적으로 복제한다. 쓰기 충돌이 발생할 수 있으므로, 충돌 감지 및 해결 메커니즘이 필수적이다.

필요성

마스터-슬레이브 복제에서는 마스터가 단일 쓰기 지점이므로 쓰기 확장성에 한계가 있다. 멀티 마스터 복제를 사용하면 여러 노드가 쓰기를 처리하므로 쓰기 부하를 분산시킬 수 있다. 또한 하나의 마스터가故障しても他のマターが書き込みを受け続ける어 가용성이 향상된다.

배경

멀티 마스터 복제는 Cassandra, CouchDB, MongoDB(레플리카셋 내), PostgreSQL(BDR), MySQL(멀티 소스 복제) 등에서 지원된다. 그러나 쓰기 충돌 관리가 복잡하므로, 충돌이 잘 발생하지 않는 워크로드에 적합하다.

비유

멀티 마스터 복제는각 지점에 창구가 있는 은행과 같다. 고객(클라이언트)은 가까운 창구(마스터 어디든)에서 거래할 수 있다. 그러나 두 창구에서 동시에 같은 계좌를 거래하면 충돌이 발생할 수 있어, 은행 중앙 시스템(충돌 해결 메커니즘)이 이를 조정한다.

📢 섹션 요약: 멀티 마스터 복제는 여러 노드가 쓰기를受入れ어 쓰기 확장성과 가용성을 높이지만, 쓰기 충돌 관리가 핵심 과제이다.


Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

멀티 마스터 동작 구조

┌─────────────────────────────────────────────────────────────────────────────┐
│                    멀티 마스터 복제 동작 구조                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [쓰기 동작]                                                               │
│                                                                             │
│       Client A                    Client B                                   │
│         │                            │                                      │
│         ▼                            ▼                                      │
│    ┌─────────────┐              ┌─────────────┐                           │
│    │  Master A   │              │  Master B   │                           │
│    │  (쓰기受入) │              │  (쓰기受入)  │                           │
│    └──────┬──────┘              └──────┬──────┘                           │
│           │                            │                                      │
│           │ 복제                      │ 복제                                  │
│           ▼                            ▼                                      │
│    ┌─────────────┐              ┌─────────────┐                           │
│    │  Master B   │              │  Master A   │                           │
│    │  (비동기복제)│              │  (비동기복제)│                           │
│    └─────────────┘              └─────────────┘                           │
│                                                                             │
│  [읽기 동작]                                                               │
│                                                                             │
│       Client A, B                                                           │
│         │                                                                   │
│         ├──▶ Master A (읽기) ──▶ 응답                                      │
│         ├──▶ Master B (읽기) ──▶ 응답                                      │
│         └──▶ ...                                                           │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

쓰기 충돌 발생

┌─────────────────────────────────────────────────────────────────────────────┐
│                    멀티 마스터 쓰기 충돌 발생 예시                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  [동시 쓰기 충돌]                                                          │
│                                                                             │
│  Time T0: Master A와 Master B가 각각 쓰기 受入れ                             │
│                                                                             │
│  Master A에서: UPDATE users SET balance = 1500 WHERE id = 1;               │
│  Master B에서: UPDATE users SET balance = 1800 WHERE id = 1;               │
│                                                                             │
│  ※ 네트워크 지연으로 인해 서로의 쓰기를 몰랐음                                │
│                                                                             │
│  결과:                                                                      │
│  Master A: balance = 1500                                                 │
│  Master B: balance = 1800                                                 │
│                                                                             │
│  ※ 복제 후: 어느 값이 적용될까? → 충돌!                                     │
│                                                                             │
│  [해결 방법]                                                               │
│                                                                             │
│  1. Last Writer Wins (LWW)                                                │
│  ───────────────────────────                                              │
│  • 가장 최신 타임스탬프(또는 Version)의 쓰기 적용                            │
│  • 예: Master B의 쓰기가 더 최신 → balance = 1800                          │
│  • Cassandra, DynamoDB에서 사용                                              │
│                                                                             │
│  2. Version vectors                                                        │
│  ────────────────────                                                      │
│  • 각 노드의 버전을 추적                                                    │
│  • 충돌发生时 모든 버전을保持                                              │
│  • 애플리케이션에서 해결策略 선택                                           │
│  • Riak에서 사용                                                            │
│                                                                             │
│  3. 애플리케이션 수준 병합                                                  │
│  ───────────────────────                                                    │
│  • 비즈니스 로직에 따라 충돌 해결                                            │
│  • 예: balance는 합산, 카운터는 증가                                       │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 멀티 마스터 복제에서 가장 큰 문제는 쓰기 충돌이다. 두 마스터가 동시에 같은 데이터를 수정하면, 복제 후 데이터 불일치가 발생한다. 이를 해결하기 위해 Last Writer Wins, Version vectors, 애플리케이션 수준 병합 등의 방법이 사용된다.

충돌 해결 메커니즘 상세

┌─────────────────────────────────────────────────────────────────────────────┐
│                    멀티 마스터 충돌 해결 메커니즘                                   │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  1. Last Writer Wins (LWW)                                                │
│  ───────────────────────────                                              │
│  • 타임스탬프 비교: 가장 최근 쓰기 적용                                      │
│  • 문제: 시간 서버 오차로 인한 정확도 저하                                   │
│  • 해결: 논리적 시계 (Lamport Clock 등) 사용                               │
│  • 사용: Cassandra, DynamoDB                                               │
│                                                                             │
│  2. Version Vectors (VV)                                                 │
│  ────────────────────────                                                  │
│  • 각 노드의 操作 카운트를 추적                                             │
│  • 충돌 감지 후 모든 버전을 보유                                             │
│  • 애플리케이션에서 선택적 해결                                             │
│  • 사용: Riak                                                              │
│                                                                             │
│  3. Operational Transformation (OT)                                        │
│  ─────────────────────────────────                                         │
│  • 조작 변환을 통해 충돌 해결                                              │
│  • 예: 두 concurrent 편집 → 병합                                            │
│  • 사용: Google Docs, Collaborative editing                                 │
│                                                                             │
│  4. CRDT (Conflict-free Replicated Data Types)                             │
│  ─────────────────────────────────────────                                 │
│  • 충돌 없이 자동으로 병합 가능한 자료구조                                    │
│  • G-Counter, PN-Counter, LWW-Register, OR-Set 등                        │
│  • 사용: Redis CRDT 모듈, Riak                                            │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐  │
│  │   충돌 최소화 전략                                                      │  │
│  │                                                                        │  │
│  │   • 쓰기 키 공간 분할: 각 마스터가管理하는 키 범위 지정                    │  │
│  │     예: Master A: user_id 1-1000, Master B: user_id 1001-2000         │  │
│  │   • 애플리케이션에서 특정 마스터로 쓰기 라우팅                           │  │
│  │   • 이러한 분할은 완전한 멀티 마스터는 아니지만 충돌을 회피              │  │
│  └─────────────────────────────────────────────────────────────────────┘  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 멀티 마스터 충돌 해결에는 다양한 방법이 있다. LWW는 가장 간단하지만 시간 서버 의존성이 있고, VV는 정확한 충돌 추적이 가능하지만 복잡하며, OT는协同 편집에 특화되어 있다. CRDT는数学적으로 충돌 없는 병합을 보장하지만 모든 자료구조에 적용 가능한 것은 아니다.

📢 섹션 요약: 멀티 마스터 복제의 핵심 과제는 쓰기 충돌 해결이며, LWW, Version vectors, CRDT 등의 메커니즘을 활용한다.


Ⅲ. 구현 및 실무 응용 (Implementation & Practice)

Cassandra 멀티 마스터

-- Cassandra: 기본적으로 멀티 마스터 아키텍처

-- 키스페이스 생성
CREATE KEYSPACE myapp
WITH REPLICATION = {
  'class': 'NetworkTopologyStrategy',
  'dc1': 3,
  'dc2': 3
};

-- 쓰기 (어떤 노드에서든 쓰기 가능)
INSERT INTO users (user_id, name, email)
VALUES (1, 'Kim', 'kim@test.com')
USING CONSISTENCY QUORUM;

-- Consistency Level에 따른 동작
-- • ANY: 가용성 최고, 일관성 가장 낮음
-- • QUORUM: 균형점
-- • ALL: 일관성 최고, 가용성 가장 낮음

-- 충돌 해결: LWW (Timestamp 기반)
-- 각 열에 마지막으로 기록된 값이 적용됨

MySQL 멀티 소스 복제

-- MySQL: 멀티 소스 복제 (한 슬레이브가 여러 마스터에서 복제)

-- 슬레이브 설정
CHANGE MASTER TO
    MASTER_HOST = 'master1'
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql-bin.000001',
    MASTER_LOG_POS = 120
    FOR CHANNEL 'master-1';

ADD MASTER MASTER_HOST = 'master2'
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'password',
    MASTER_LOG_FILE = 'mysql-bin.000001',
    MASTER_LOG_POS = 120
    FOR CHANNEL 'master-2';

START SLAVE FOR CHANNEL 'master-1';
START SLAVE FOR CHANNEL 'master-2';

PostgreSQL BDR

-- PostgreSQL BDR (Bi-Directional Replication)

-- BDR 확장 설치
CREATE EXTENSION bdr;

-- 첫 번째 노드 시작
SELECT bdr.init_node(
    local_node_name := 'node1',
    local_dbname := 'mydb'
);

-- 두 번째 노드 연결
SELECT bdr.connect_node(
    local_node_name := 'node2',
    remote_node_name := 'node1',
    remote_dbname := 'mydb'
);

-- 이후 양방향 복제가 자동으로 설정됨

-- 충돌 정책 설정
ALTER TABLE users SET (
    bdr.conflict_policy = 'last_update_wins'
    -- 'first_update_wins', 'skip', 'error' 등
);

📢 섹션 요약: 멀티 마스터 복제는 Cassandra처럼 기본 멀티 마스터인系统和 MySQL 멀티 소스 복제처럼 설정으로 가능하게 하는 시스템이 있다.


Ⅳ. 결론

멀티 마스터 복제는 쓰기 확장성과 가용성을 높이지만, 쓰기 충돌 관리가 핵심 과제이다. 충돌 해결 메커니즘(LWW, Version vectors, CRDT 등)을 활용하고, 가능하다면 쓰기 키 공간을 분할하여 충돌을 최소화하는 것이 좋다. 충돌이 자주 발생하지 않는 워크로드(주로 다른 데이터를 修改하는 경우)에 적합하다.

📢 섹션 요약: 멀티 마스터 복제는 쓰기 분산에 효과적이지만, 충돌 해결 메커니즘의 선택과 충돌 빈도 분석이 핵심 설계 요소이다.


핵심 인사이트 ASCII 다이어그램 (Concept Map)

┌─────────────────────────────────────────────────────────────────────────────┐
│            Multi-Master Replication Concept Map                            │
│                                                                             │
│              ┌───────────────────────────┐                                   │
│              │ Multi-Master Replication  │                                   │
│              │   (멀티 마스터 복제)      │                                   │
│              └───────────┬───────────────┘                                   │
│                          │                                                  │
│       ┌──────────────────┼──────────────────┐                             │
│       ▼                  ▼                  ▼                              │
│  ┌─────────┐       ┌─────────┐       ┌─────────┐                        │
│  │  양방향  │       │  쓰기   │       │  충돌   │                        │
│  │  복제   │       │  분산   │       │  해결  │                        │
│  └────┬────┘       └────┬────┘       └────┬────┘                        │
│       │                  │                  │                               │
│       ▼                  ▼                  ▼                               │
│  ┌─────────────────────────────────────────────────────┐                  │
│  │  LWW | Version Vectors | CRDT | OT                  │                  │
│  └─────────────────────────────────────────────────────┘                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

참고

  • 멀티 마스터 복제는 여러 노드가 쓰기를受入れる 복제 아키텍처이다.
  • 쓰기 충돌이 발생할 수 있어 충돌 해결 메커니즘이 필수적이다.
  • LWW, Version vectors, CRDT 등의 충돌 해결 방법이 있다.
  • 충돌이 드문 워크로드에 적합하다.