본문 바로가기
카테고리 없음

DDIA-Chapter 5. 복제 (Replication)

by 코헤0121 2026. 2. 8.
728x90
반응형

핵심 개념

  • 복제: 네트워크로 연결된 여러 머신에 동일한 데이터의 복사본을 유지하는 것
  • 목적: 고가용성, 지연 시간 감소, 읽기 처리량 확장

발표 도입 (5분)

왜 복제가 필요한가?

데이터를 단일 서버에만 저장하면 세 가지 근본적 한계에 부딪힙니다.

  1. 가용성(Availability): 서버 한 대가 죽으면 서비스 전체가 중단됩니다.
  2. 지연 시간(Latency): 서울에서 미국 서버까지 왕복 150ms — 사용자 체감으로는 답답합니다.
  3. 읽기 처리량(Read Throughput): 트래픽이 폭증하면 단일 서버의 CPU/IO가 병목이 됩니다.

복제(Replication) 는 동일한 데이터의 복사본을 네트워크로 연결된 여러 머신에 유지하여 이 세 가지 문제를 동시에 해결하는 기법입니다.

               ┌──────────┐
  쓰기 ──────▶  │  리더(L) │
               └────┬─────┘
                    │ 복제 스트림
          ┌─────────┼─────────┐
          ▼         ▼         ▼
     ┌─────────┐ ┌─────────┐ ┌─────────┐
     │팔로워 1  │ │팔로워 2  │ │팔로워 3 │  ◀── 읽기 분산
     └─────────┘ └─────────┘ └─────────┘

복제의 세 가지 아키텍처

아키텍처 쓰기 노드 대표 시스템 핵심 트레이드오프
단일
리더
1개 MySQL, PostgreSQL, MongoDB 단순하지만 쓰기 확장 불가
다중
리더
N개 (보통 DC당 1개) Aurora Multi-Writer, CouchDB 쓰기 확장 가능하지만 충돌 해소 필요
리더
없음
모든 노드 Cassandra, Riak, DynamoDB 고가용성이지만 일관성 보장 복잡

발표 전체를 관통하는 핵심 메시지: 복제에서 "은탄환"은 없습니다. 모든 선택은 일관성(Consistency) vs 가용성(Availability) vs 지연 시간(Latency) 사이의 트레이드오프입니다.


상세 내용


테마 1: 단일 리더 복제 (25분)


1-1. 리더와 팔로워

단일 리더 복제(Single-Leader Replication) 는 가장 일반적인 복제 방식입니다. 핵심 원리는 단순합니다:

클라이언트 ──▶ 리더 ──▶ 복제 로그 ──▶ 팔로워들
                           ↓
                      동일한 순서로 적용

역할 분담:

  • 리더(Leader): 모든 쓰기 요청을 받아 처리. 마스터(Master), 프라이머리(Primary)라고도 불림
  • 팔로워(Follower): 리더의 변경 사항을 복제하여 적용. 읽기 전용 복제본(Read Replica), 슬레이브(Slave), 세컨더리(Secondary)라고도 불림

장점

  • 쓰기 충돌이 발생하지 않음 (모든 쓰기가 단일 노드에서 순서화)
  • 구현이 상대적으로 단순
  • 대부분의 워크로드에 적합

단점:

  • 리더가 병목 (쓰기 확장이 어려움)
  • 리더 장애 시 failover 필요

1-2. 동기식 대 비동기식 복제

복제에서 가장 먼저 결정해야 하는 것은 "쓰기 완료를 팔로워 확인까지 기다릴 것인가?"입니다.

[동기 복제]
 클라이언트 ──▶ 리더 ──▶ 팔로워 확인 대기 ──▶ 클라이언트에 "성공" 응답
 장점: 팔로워가 항상 최신 데이터 보유
 단점: 팔로워 1대라도 응답 못하면 전체 쓰기 중단

[비동기 복제]
 클라이언트 ──▶ 리더 ──▶ 클라이언트에 즉시 "성공" 응답
                  └──▶ 팔로워에 나중에 전파 (백그라운드)
 장점: 쓰기 지연 최소화, 가용성 높음
 단점: 팔로워가 뒤처질 수 있음 (복제 지연)

반동기(Semi-Synchronous) 복제 — Facebook의 선택:

  • 팔로워 중 1대만 동기적으로 확인, 나머지는 비동기
  • 동기 팔로워가 죽으면 다른 팔로워를 동기 팔로워로 승격
  • 최소 2개 노드에 데이터가 있음을 보장하면서 성능도 확보
  • 참고: Yoshinori Matsunobu, "Semi-Synchronous Replication at Facebook," 2014

실무 포인트: 대부분의 프로덕션 시스템(MySQL, PostgreSQL 등)은 비동기 복제가 기본값입니다. 그런데 비동기 복제를 선택하는 순간, 복제 지연(Replication Lag)이 생김


1-3. 새로운 팔로워 설정

운영 중인 시스템에 새로운 팔로워를 추가할 때, 서비스를 중단하지 않고 어떻게 할 수 있을까요?

일반적인 절차:

1. 리더의 데이터베이스 스냅샷을 특정 시점에 생성
   └── 가능하면 백업 기능 활용 (잠금 없이)

2. 스냅샷을 새 팔로워 노드에 복사

3. 팔로워가 스냅샷을 로드한 후, 스냅샷 이후의 변경 사항을 리더에게 요청
   └── 스냅샷은 리더의 복제 로그에서 정확한 위치와 연결되어 있어야 함
   └── PostgreSQL: LSN (Log Sequence Number)
   └── MySQL: binlog coordinates

4. 팔로워가 밀린 로그를 모두 따라잡으면 정상 동작
   └── "caught up" 상태가 됨

PostgreSQL 예시:

-- 스냅샷 위치 확인
SELECT pg_current_wal_lsn();
-- 결과: 0/16B3748

-- 새 팔로워는 이 LSN 이후의 WAL부터 요청

1-4. 노드 중단 처리

노드 장애는 크게 두 가지로 나뉩니다: 팔로워 장애와 리더 장애.

팔로워 장애: Catch-up Recovery

팔로워 장애 발생
     ↓
복구 후 로컬 로그에서 마지막 처리한 트랜잭션 확인
     ↓
리더에게 해당 시점 이후의 변경 사항 요청
     ↓
밀린 로그 모두 적용 → 정상 동작
  • 팔로워는 자신이 마지막으로 처리한 트랜잭션을 로컬에 기록
  • 복구 후 이 시점부터 리더의 로그를 따라잡으면 됨

리더 장애: Failover

리더가 죽었을 때 팔로워를 새 리더로 승격하는 과정입니다.

1. 리더 장애 감지
   - 타임아웃 기반: N초간 하트비트 없으면 장애로 판단
   - 문제: 너무 짧으면 불필요한 failover, 너무 길면 복구 지연

2. 새 리더 선출
   - 가장 최신 데이터를 가진 팔로워 선택 (이상적)
   - 합의 알고리즘(Raft, Paxos)으로 선출

3. 시스템 재구성
   - 클라이언트의 쓰기를 새 리더로 리다이렉트
   - 이전 리더가 복구되면 팔로워로 강등

스플릿 브레인(Split Brain) — 가장 위험한 장애 시나리오:

네트워크 파티션 발생:

  ┌──────────────────┐     ┌──────────────────┐
  │  이전 리더 (살아있음)│  ✗  │  새 리더 (승격됨)   │
  │  "나도 리더다!"     │     │  "나도 리더다!"     │
  │  쓰기A 수신 중     │     │  쓰기B 수신 중     │
  └──────────────────┘     └──────────────────┘
                ↓
        두 리더에 서로 다른 데이터!
        네트워크 복구 후 어떻게 합치나?

결과: 두 리더에 서로 다른 쓰기가 발생 → 데이터 불일치 → 복구가 매우 어려움

GitHub 2012년 사고:

  • MySQL 리더 장애 → 자동 failover로 팔로워 승격
  • 이전 리더가 복구되었지만, 새 리더와 데이터가 불일치
  • 결과: 일부 데이터가 유실되고, 수동 복구에 오랜 시간 소요

펜싱(Fencing) 메커니즘:

방법 1: STONITH (Shoot The Other Node In The Head)

새 리더 선출 → 이전 리더에 전원 차단 명령 (IPMI/iLO)
→ 물리적으로 확실히 중단시킴
  • 가장 확실하지만 하드웨어 의존적
  • 클라우드 환경에서는 인스턴스 강제 종료로 대체

방법 2: 펜싱 토큰(Fencing Token)

리더 선출 시 단조 증가하는 토큰 발급:
  이전 리더: token = 33
  새 리더:   token = 34

스토리지는 token 34 이후부터 token 33의 쓰기를 거부
→ 이전 리더가 좀비 상태로 쓰기해도 무시됨

방법 3: 리스(Lease) 기반

리더가 일정 시간(예: 10초) 동안만 유효한 리더십 임대(lease) 획득
→ 갱신하지 않으면 자동 만료
→ 만료 후 다른 노드가 새 리더 임대 획득

1-5. 복제 로그 구현

리더가 팔로워에게 "무엇을 복제할 것인가"를 전달하는 방식에는 세 가지가 있습니다.

방식 1: 구문 기반(Statement-Based) 복제

리더 → 팔로워: "INSERT INTO users (name) VALUES ('Kim')"
  • 리더가 실행한 SQL 문 자체를 팔로워에 전송
  • 문제점:
    • NOW(), RAND() → 리더와 팔로워에서 다른 결과
    • AUTO_INCREMENT → 실행 순서에 따라 다른 값
    • 부수 효과가 있는 트리거, 함수 → 비결정적 결과
  • MySQL 5.1 이전의 기본 방식이었으나, 현재는 거의 사용하지 않음

방식 2: WAL(Write-Ahead Log) 기반 복제

리더 → 팔로워: "페이지 42, 오프셋 128에 바이트 0x4B696D 기록"
  • 스토리지 엔진의 물리적 변경(디스크 블록 단위)을 그대로 전송
  • PostgreSQL, Oracle이 이 방식 사용
  • 장점: 완벽하게 정확한 복제
  • 단점: 스토리지 엔진의 내부 포맷에 종속 → 버전이 다른 리더-팔로워 간 복제 불가 → 무중단 업그레이드가 어려움

방식 3: 논리적 로우 기반(Row-Based / Logical) 복제

리더 → 팔로워: "users 테이블, id=42, name='Kim' → name='Park' 변경"
  • 변경된 행의 논리적 내용을 전송
  • MySQL의 binlog (row format), PostgreSQL의 logical decoding
  • 장점:
    • 스토리지 엔진 독립 → 버전 간 호환성 좋음
    • 외부 시스템(데이터 웨어하우스, 검색 엔진)으로 변경 데이터 캡처(CDC) 가능
  • 단점: 대규모 변경 시 로그 크기가 큼

테마 1 토론

"Failover를 자동화해야 하는가, 수동으로 해야 하는가?"

토론 유도 질문:

  • 자동 failover의 위험성은 무엇인가? (스플릿 브레인, 잘못된 판단)
  • 수동 failover의 비용은 무엇인가? (장애 시간 증가, 24/7 운영 인력)
  • 어떤 상황에서 자동/수동을 선택해야 하는가?

테마 1 참고자료 상세 해설

Lindsay et al., "Notes on Distributed Databases" (IBM Research, 1979)

IBM 연구소에서 나온 분산 데이터베이스의 기초 이론 문서

  • 1979년에 작성되었지만 분산 DB의 근본 문제를 정의한 선구적 연구
  • 다루는 주제: 데이터 분산, 복제, 분산 트랜잭션, 장애 복구
  • 복제 시 발생하는 일관성 vs 가용성 트레이드오프를 최초로 체계적으로 정리
  • "분산 시스템의 어려움은 네트워크가 아니라 부분 장애(partial failure)"라는 통찰

Oracle Active Data Guard White Paper (2013)

Oracle의 물리적 대기 서버(Standby) 복제 기술 문서

  • Active Data Guard: 팔로워(Standby)에서도 읽기 쿼리를 처리 가능 → 읽기 부하 분산
  • WAL(Redo Log) 기반 물리적 복제: 블록 단위로 정확하게 복제
  • 실시간 적용(Real-Time Apply): 리더에서 Redo Log가 생성되는 즉시 팔로워에 적용
  • 자동 장애 복구(Data Guard Broker): 장애 감지 → 자동 Failover → 이전 리더 복구 시 팔로워로 재합류

Kafka Intra-Cluster Replication (ApacheCon, 2013)

Apache Kafka의 브로커 간 복제 메커니즘 발표:

  • Kafka는 로그 기반 메시지 시스템 → 복제도 로그 기반으로 자연스럽게 구현
  • ISR(In-Sync Replicas): 리더와 동기화가 된 팔로워 목록을 유지
    • 뒤처진 팔로워는 ISR에서 제거 → 따라잡으면 다시 추가
    • acks=all로 설정하면 ISR 내 모든 복제본에 기록 완료 후 응답 → 데이터 유실 방지
  • 리더 선출: ISR 중에서만 새 리더를 선출 → 데이터가 있는 노드만 리더가 될 수 있음
  • unclean.leader.election.enable=true이면 ISR 외 노드도 리더 가능 → 데이터 유실 위험 vs 가용성 트레이드오프

Yoshinori Matsunobu, "Semi-Synchronous Replication at Facebook" (2014)

Facebook의 MySQL 인프라 엔지니어가 반동기 복제 운영 경험을 공유한 발표:

  • Facebook은 수천 대의 MySQL 서버를 운영하며, 비동기 복제의 데이터 유실 위험을 해결해야 했음
  • 반동기 복제(Semi-Synchronous): 리더가 쓰기를 커밋하기 전에 최소 1대의 팔로워 확인을 대기
    • 모든 팔로워를 기다리지 않으므로 동기 복제보다 빠름
    • 최소 2곳에 데이터가 있으므로 비동기보다 안전
  • 문제: 반동기 팔로워가 느려지면? → 전체 쓰기 지연 증가
  • 해결: 타임아웃 기반 전환 — 일정 시간 내 팔로워 응답이 없으면 비동기 모드로 자동 전환

Chain Replication (van Renesse & Schneider, OSDI 2004)

전통적 리더-팔로워와 다른 체인 복제 아키텍처를 제안한 논문:

  • 노드들을 일렬 체인으로 구성: Head → N1 → N2 → ... → Tail
  • 쓰기: Head에서 시작하여 체인을 따라 순차 전파, Tail에 도달하면 커밋
  • 읽기: 항상 Tail에서만 수행 → 강한 일관성 보장
  • Microsoft Azure Storage, HDFS, Amazon EBS 등에서 변형 채택

테마 2: 복제 지연 문제 (25분)


2-1. 복제 지연 문제

비동기 복제를 선택하는 순간, 복제 지연(Replication Lag) 이라는 판도라의 상자가 열립니다.

최종적 일관성(Eventual Consistency)의 정의:

모든 쓰기가 중단되고 충분한 시간이 지나면, 모든 복제본이 결국 동일한 데이터를 가지게 됩니다.

이 정의에서 핵심 단어는 "결국(Eventually)" 입니다 — 언제인지는 보장하지 않습니다.

시간 →  t0        t1        t2        t3
리더:   [v2]      [v2]      [v2]      [v2]
팔로워A: [v1]  →  [v2]      [v2]      [v2]    (빠르게 따라잡음)
팔로워B: [v1]     [v1]  →   [v1]  →   [v2]    (느리게 따라잡음)
         ↑                   ↑
      복제 지연            이 구간에서 B를 읽으면 stale 데이터

복제 지연이 발생하는 근본 원인:

  1. 네트워크 지연: DC 간 물리적 거리, 네트워크 혼잡
  2. 팔로워 부하: 팔로워가 읽기 쿼리 처리로 바빠서 복제 스트림 적용이 느려짐
  3. 장애 복구: 팔로워가 재시작 후 밀린 로그를 따라잡는 동안
  4. 대규모 트랜잭션: 한 번에 수백만 행을 변경하는 배치 작업

Werner Vogels(Amazon CTO)는 2008년 "Eventually Consistent" 논문에서 최종적 일관성을 여러 변형으로 분류했습니다.


2-2. 자신이 쓴 내용 읽기(Read-Your-Own-Writes)

시나리오: 사용자가 프로필 사진을 변경한 직후 페이지를 새로고침하면, 아직 복제되지 않은 팔로워에서 읽어 이전 사진이 그대로 보입니다.

사용자A: "프로필 사진 변경" ──▶ 리더 (v2 저장 완료)
사용자A: "내 프로필 확인"  ──▶ 팔로워B (아직 v1) ──▶ "어? 안 바뀌었네?"
                                                        (사실은 바뀐 건데)

이것은 단순한 불편이 아닙니다. 사용자는 "내 데이터가 사라졌다"고 느끼며, 이는 서비스 신뢰도에 직결됩니다.

구현 전략:

전략 구현 방법 적합한 상황
리더 라우팅 사용자가 수정한 데이터는 항상 리더에서 읽기 수정 빈도가 낮은 데이터 (프로필 등)
타임스탬프 기반 클라이언트가 마지막 쓰기 시각을 기억 → 해당 시각 이후의 복제본에서만 읽기 범용적이지만 시계 동기화 필요
논리적 타임스탬프 물리 시계 대신 로그 시퀀스 번호(LSN) 활용 시계 스큐 문제 회피

크로스 디바이스 문제

  • 사용자가 노트북에서 쓰고 스마트폰에서 확인하면?
  • 디바이스 간 "마지막 쓰기 타임스탬프"를 공유해야 하는데, 이는 추가 인프라(세션 서버 등)를 요구합니다

2-3. 단조 읽기(Monotonic Reads)

시나리오: 사용자가 새로고침할 때마다 다른 팔로워에 라우팅되면, "있었던 댓글이 사라졌다가 다시 나타나는" 현상이 발생합니다.

첫 번째 읽기 → 팔로워A (v2: 댓글 3개 보임)
두 번째 읽기 → 팔로워B (v1: 댓글 2개만 보임)  ← "시간이 역행하는 느낌"
세 번째 읽기 → 팔로워A (v2: 다시 댓글 3개 보임)

해결: 세션 고정(Session Stickiness)

  • 동일 사용자는 항상 동일 복제본에서 읽도록 라우팅
  • 구현 방법: 사용자 ID의 해시값으로 팔로워 결정
  • 주의: 해당 팔로워가 죽으면 다른 팔로워로 전환 필요

2-4. 일관된 순서로 읽기(Consistent Prefix Reads)

시나리오: 인과성 위반 — 질문보다 답변이 먼저 보이는 현상

리더에서의 실제 순서:
  t1: Mr.Poons "Mrs. Cake, 미래를 볼 수 있다면서요?"  (파티션 1에 저장)
  t2: Mrs.Cake  "네, 아쉽게도 그래요."              (파티션 2에 저장)

관찰자가 보는 순서 (파티션 2의 복제가 더 빠른 경우):
  t1: Mrs.Cake  "네, 아쉽게도 그래요."   ← ???
  t2: Mr.Poons "Mrs. Cake, 미래를 볼 수 있다면서요?"

근본 원인: 서로 다른 파티션에 기록된 데이터의 복제 속도가 다르면, 인과적 순서가 뒤집힐 수 있습니다.

해결 방향:

  • 인과적으로 관련된 쓰기를 동일 파티션에 배치
  • 인과 관계를 명시적으로 추적(Lamport 타임스탬프, 벡터 클럭)
  • 참고: Leslie Lamport, "Time, Clocks, and the Ordering of Events" (1978) — 분산 시스템에서 인과적 순서를 정의한 기념비적 논문

2-5. 복제 지연을 위한 해결책

야구로 이해하는 일관성 모델
Douglas Terry의 "Replicated Data Consistency Explained Through Baseball" (2011) 논문에서는 야구 경기 점수판을 비유로 사용합니다.

실제 경기 상황: 방문팀 2 - 5 홈팀 (7회 끝)

각 일관성 모델에서 관찰 가능한 값:
┌────────────────────────────┬────────────────────────┐
│ 일관성 모델                 │ 볼 수 있는 점수        │
├────────────────────────────┼────────────────────────┤
│ 강한 일관성(Strong)         │ 2-5 (정확히 최신)      │
│ 최종적 일관성(Eventual)     │ 아무 과거 점수나 가능   │
│ 자신이 쓴 내용 읽기         │ 내가 마지막 본 이후 값  │
│ 단조 읽기(Monotonic)        │ 이전 읽기보다 같거나 앞 │
│ 일관된 순서(Prefix)         │ 일부 이닝까지의 정확한값│
└────────────────────────────┴────────────────────────┘

핵심 인사이트: 모든 상황에 강한 일관성이 필요한 것은 아닙니다. 야구 점수를 보는 팬에게는 약간의 지연이 괜찮지만, 공식 기록원에게는 강한 일관성이 필수입니다. 워크로드에 맞는 일관성 모델을 선택하는 것이 핵심입니다.

실무적 해결 방법들:

문제 해결책 구현 예시
자신이 쓴 내용 읽기 리더에서 읽기, LSN 기반 라우팅 MySQL WAIT_FOR_EXECUTED_GTID_SET
단조 읽기 세션 고정 로드밸런서의 sticky session
일관된 순서 읽기 동일 파티션 배치, 인과 관계 추적 Kafka의 파티션 키

운영 가시성: 복제 상태 모니터링

MySQL:  SHOW REPLICA STATUS  →  Seconds_Behind_Source
PG:     pg_stat_replication  →  replay_lag

알림 기준 예시:
  - 복제 지연 > 5초:  WARNING
  - 복제 지연 > 30초: CRITICAL
  - 복제 중단:        PAGE (on-call 호출)

테마 2 토론

"성능을 위해 일관성을 어디까지 희생할 수 있는가?"

토론 유도 질문:

  • SNS 타임라인에서 "좋아요" 수가 1~2초 뒤처지는 것은 괜찮은가?
  • 은행 잔고 조회에서 복제 지연이 허용되는가?
  • 전자상거래 재고 수량은 어떤 일관성 모델이 적절한가?

테마 2 참고자료 상세 해설

Werner Vogels, "Eventually Consistent" (ACM Queue, 2008)

Amazon CTO인 Werner Vogels가 쓴 이 글은 "최종적 일관성"이라는 용어를 업계에 대중화한 핵심 문헌입니다. 핵심 주장:

  • 일관성에는 클라이언트 측(client-side)과 서버 측(server-side) 두 가지 관점이 존재
  • 클라이언트 측 일관성 모델: 최종적 일관성, 단조 읽기, 세션 일관성, 자신이 쓴 내용 읽기 등으로 세분화됨
  • N/W/R 값 튜닝을 통해 일관성과 가용성의 균형을 조절할 수 있음

Douglas B. Terry, "Replicated Data Consistency Explained Through Baseball" (Microsoft Research, 2011)

Microsoft Research의 Terry가 작성한 이 논문은 복잡한 일관성 모델을 야구 경기 비유로 직관적으로 설명합니다:

  • 6가지 일관성 모델을 야구 점수판으로 비교
  • 같은 데이터(야구 점수)라도 역할에 따라 필요한 일관성 수준이 다름
  • 대부분의 애플리케이션은 강한 일관성 없이도 동작할 수 있음

#48: Peter Bailis et al., "Quantifying Eventual Consistency with PBS" (CACM, 2014)

PBS(Probabilistically Bounded Staleness)라는 개념을 제안한 논문:

  • "최종적 일관성"이 구체적으로 얼마나 빨리 일관성이 달성되는가?를 정량화
  • 실제 Cassandra, Riak 등의 시스템에서 측정한 결과, 대부분의 읽기는 수십 밀리초 내에 최신 값을 반환함

#54: Leslie Lamport, "Time, Clocks, and the Ordering of Events in a Distributed System" (CACM, 1978)

분산 시스템 분야에서 가장 많이 인용되는 논문 중 하나:

  • "happens-before" 관계 (→): 이벤트 A가 이벤트 B 이전에 발생했다면 A → B
  • 논리적 클럭(Logical Clock): 각 프로세스가 단조 증가하는 카운터를 유지

#61: Schwarz & Mattern, "Detecting Causal Relationships in Distributed Computations" (1994)

Lamport의 논리적 클럭을 확장하여 인과 관계를 완전하게 포착하는 방법을 연구:

  • 벡터 클럭(Vector Clock): 각 프로세스별 카운터를 벡터로 유지 → 두 이벤트가 인과 관계인지, 동시인지 정확히 판별 가능

테마 3: 다중 리더 복제 (25분)


3-1. 다중 리더 복제

다중 리더 복제(Multi-Leader Replication) 는 여러 노드가 쓰기를 받을 수 있는 구조입니다. 단일 리더의 확장성 한계를 극복하기 위한 방법이지만, 쓰기 충돌이라는 새로운 문제가 발생합니다.

          DC 서울                    DC 미국
     ┌─────────────┐           ┌─────────────┐
     │  리더 (L1)   │◀────────▶│  리더 (L2)   │
     │  팔로워 F1   │           │  팔로워 F3   │
     │  팔로워 F2   │           │  팔로워 F4   │
     └─────────────┘           └─────────────┘
      서울 사용자 →               미국 사용자 →
      L1에 쓰기 (5ms)            L2에 쓰기 (5ms)
                     ↕
              DC 간 비동기 복제 (150ms)

3-2. 다중 리더 복제의 사용 사례

상황 1: 다중 데이터센터 운영

  • 각 DC에 리더를 두면 사용자는 가까운 DC에 쓸 수 있어 지연 시간이 크게 줄어듦
  • 한 DC가 완전히 다운되어도 다른 DC에서 계속 서비스 가능

상황 2: 오프라인 작업 — 캘린더 앱

  • 비행기 안에서 일정을 수정 → 오프라인 상태의 로컬 DB가 "리더" 역할
  • 착륙 후 인터넷 연결 → 서버와 동기화
  • 각 디바이스가 사실상 독립적인 리더 → 다중 리더 토폴로지와 동일

상황 3: 실시간 협업 편집 — Google Docs, Notion

  • 여러 사용자가 동시에 같은 문서를 편집
  • 각 사용자의 편집이 즉시 로컬에 반영되고, 서버를 통해 다른 사용자에게 전파
  • 충돌이 빈번하게 발생할 수 있으며, 이를 자동으로 해소해야 함

CRDT 관련 메모:

  • 다중 쓰기에서 쓰기 충돌을 해소하는 자료구조
  • 클라이언트를 유니크 아이디로 식별 → LWW 사용
  • 이벤트의 인과 순서로 벡터 시계를 사용
  • YJS 라이브러리가 대표적인 구현체

3-3. 쓰기 충돌 다루기

쓰기 충돌이란?

사용자A (L1):  title = "A"  ──▶ L1에 커밋 ──▶ L2로 전파
사용자B (L2):  title = "B"  ──▶ L2에 커밋 ──▶ L1으로 전파
                                               ↓
                                    충돌 발생! title은 "A"? "B"?

단일 리더 시스템에서는 두 번째 쓰기가 첫 번째 이후에 순서가 정해지므로 충돌이 원천적으로 불가능합니다. 그러나 다중 리더에서는 두 쓰기가 독립적으로 성공한 후에 충돌이 감지되므로, 사용자에게 에러를 반환하기엔 이미 늦었습니다.

충돌 해소 전략 비교:

전략 1: LWW (Last Write Wins) — 최종 쓰기 승리

쓰기A: title = "A" (timestamp: 100)
쓰기B: title = "B" (timestamp: 101)
→ 결과: title = "B" (더 큰 타임스탬프 승리)
→ 쓰기A는 조용히 사라짐 (데이터 유실!)
  • Cassandra가 이 방식을 채택 (#53 "Why Cassandra Doesn't Need Vector Clocks")
  • 장점: 구현이 극도로 단순
  • 치명적 단점: 동시 쓰기 시 하나의 값이 아무런 알림 없이 유실됨
  • 시계 스큐(clock skew)가 있으면 나중에 쓴 값이 먼저로 판정될 수도 있음

전략 2: 버전 벡터(Version Vector) — 인과 관계 추적

초기 상태: {A:0, B:0} value = ∅

사용자A가 쓰기: {A:1, B:0} value = "hello"
사용자B가 쓰기: {A:0, B:1} value = "world"

비교: {A:1, B:0} vs {A:0, B:1}
→ 어느 쪽도 다른 쪽을 지배하지 않음 → "동시 쓰기"로 판정
→ 충돌을 애플리케이션에 알려 병합하도록 위임

사용자A가 두 값을 병합: {A:2, B:1} value = "hello world"
→ 이제 이 값이 두 이전 값 모두를 지배함
  • 핵심: 버전 벡터는 "누가 누구를 알고 있는가"를 추적
  • 중요: 버전 벡터 ≠ 벡터 클럭 (#60 Carlos Baquero 참고)

전략 3: CRDT (Conflict-Free Replicated Data Types)

G-Counter (성장 전용 카운터) 예시:
  노드A: {A:5, B:3}  →  전체 값 = max 병합
  노드B: {A:4, B:7}  →  전체 값 = max 병합
  병합:  {A:5, B:7}  →  총합 = 12
  → 충돌이 수학적으로 불가능!
  • 교환법칙(commutativity)과 결합법칙(associativity)을 만족하는 데이터 구조
  • 한계: 지원되는 연산이 제한적 (카운터, 집합, 레지스터 등)
  • Riak이 CRDT를 실무에 적용한 대표 사례 (#40, #55)
  • Kleppmann의 CRDT JSON (#32)은 JSON 문서 수준의 CRDT를 연구

전략 4: OT (Operational Transformation) — Google Docs의 선택

원본 텍스트: "ABC"
사용자A: insert('X', pos=1) → "AXBC"
사용자B: delete(pos=2)      → "AC"

동시 적용 시 문제:
- A의 삽입이 B의 삭제 위치에 영향을 줌
- B의 삭제 위치를 1만큼 오른쪽으로 변환(transform)해야 함

변환 후:
- A에 B 적용: "AXBC" → delete(pos=3) → "AXC"
- B에 A 적용: "AC"   → insert('X', pos=1) → "AXC"
→ 양쪽 결과 동일!
  • 연산(operation)을 상대방의 동시 연산에 맞게 변환하여 병합
  • #42 Sun & Ellis 원논문 / #31 Google Docs가 이 방식 채택
  • 장점: 텍스트 편집처럼 위치 기반 연산에 강력
  • 단점: 변환 함수 정의가 복잡, 3인 이상 동시 편집에서 정확성 보장이 어려움

3-4. 다중 리더 복제 토폴로지

[원형(Circular)]          [별형(Star)]           [전체연결(All-to-All)]
  L1 → L2                  L1 → Hub ← L3           L1 ←→ L2
  ↑     ↓                       ↓                  ↑↘  ↗↑
  L4 ← L3                      L2                  L3 ←→ L4
토폴로지 장점 단점
원형/별형 네트워크 트래픽 적음 단일 장애점, 메시지 순서 문제
전체 연결 내결함성 높음 네트워크 비용 큼, 순서 역전 가능

실무 경고 (#28): Robert Hodges는 "Multi-Master를 반드시 배포해야 한다면, 이것부터 읽어라"에서 다중 리더의 운영 복잡성을 경고합니다. 무한 루프 버그(#43 HBase 사례), 트랜잭션 지원 한계(#36 PostgreSQL BDR) 등 실무에서 마주치는 문제가 많습니다.

AWS Aurora Multi-Writer vs 전통적 다중 리더:

항목 Aurora Multi-Writer 전통적 다중 리더 (Tungsten 등)
복제 레벨 스토리지 레벨 (공유 스토리지) 애플리케이션/논리적 레벨
충돌 감지 낙관적 충돌 감지 (커밋 시점) 비동기 감지 (전파 시점)
충돌 해소 첫 번째 커밋 승리, 나머지 롤백 애플리케이션 로직 필요
사용 조건 같은 행을 동시에 쓰지 않는 워크로드 범용

Aurora Multi-Writer는 "동일 행에 대한 동시 쓰기가 드문 경우"에 최적화되어 있습니다.


테마 3 토론

"LWW 방식에서 발생하는 데이터 유실을 비즈니스적으로 어떻게 정당화할 것인가?"

토론 유도 질문:

  • 쇼핑카트에서 LWW를 쓰면 어떤 일이 발생하는가? (Amazon Dynamo 논문의 실제 사례)
  • CRDT로 해결할 수 있는 비즈니스 도메인은 무엇인가?
  • 여러분의 서비스에서 다중 리더가 필요한 상황이 있는가?

테마 3 참고자료 상세 해설

다중 마스터 복제 실무

#26: Tungsten Replicator (GitHub)

MySQL 환경에서 다중 마스터 복제를 구현하는 오픈소스 도구:

  • MySQL의 기본 복제 기능을 넘어 이기종 DB 간 복제(MySQL → PostgreSQL 등)도 지원
  • 충돌 해소를 자동으로 해주지 않음 → 애플리케이션에서 직접 충돌 해소 로직을 구현해야 함

#27: BDR 0.10.0 Documentation (PostgreSQL)

PostgreSQL을 위한 양방향 복제(Bi-Directional Replication) 확장:

  • 모든 노드가 읽기/쓰기 가능 → 다중 마스터 토폴로지
  • 충돌 감지 및 해소: last-update-wins가 기본이며, 커스텀 충돌 해소 핸들러를 작성할 수 있음

#28: Robert Hodges, "If You Must Deploy Multi-Master Replication, Read This First" (2012)

Tungsten Replicator의 개발자인 Robert Hodges가 쓴 실무 경고문:

  • 다중 마스터 복제는 "해결책"이 아니라 "새로운 문제의 시작"
  • 자주 발생하는 실무 문제들:
    • AUTO_INCREMENT 충돌: 두 마스터가 같은 ID를 생성
    • DDL(스키마 변경) 전파: ALTER TABLE이 비동기로 전파되면 스키마 불일치 발생
  • 결론: "정말 필요한 경우가 아니면 단일 마스터를 쓰라"

#43: Lars Hofhansl, "HBASE-7709: Infinite Loop in Master/Master Replication" (2013)

HBase에서 발견된 다중 마스터 복제의 무한 루프 버그:

  • Master A → Master B로 복제, Master B → Master A로 다시 복제 → 동일 변경이 무한히 순환

충돌 해소 알고리즘

#31: John Day-Richter, "What's Different About the New Google Docs" (2010)

Google Docs가 OT 기반 실시간 협업 편집을 어떻게 구현했는지 설명하는 공식 블로그:

  • 서버가 중앙 변환점 역할
  • 클라이언트 측에서도 서버 응답을 받기 전까지 로컬 예측 적용(optimistic UI)

#32: Martin Kleppmann & Beresford, "A Conflict-Free Replicated JSON Datatype" (arXiv, 2016)

DDIA 저자인 Kleppmann의 연구로, JSON 문서 전체에 대한 CRDT를 설계한 논문:

  • 중첩된 맵(map)과 리스트(list)를 포함하는 JSON 구조 전체를 CRDT로 처리
  • 이후 Automerge 라이브러리로 오픈소스 구현됨

#38: Marc Shapiro et al., "A Comprehensive Study of Convergent and Commutative Replicated Data Types" (INRIA, 2011)

CRDT의 바이블이라 불리는 종합 연구 논문:

  • CRDT를 CvRDT(상태 기반)와 CmRDT(연산 기반) 두 가지로 분류
  • 구체적 CRDT 타입 카탈로그: G-Counter, PN-Counter, G-Set, 2P-Set, OR-Set, LWW-Register, MV-Register, RGA(리스트) 등

#42: Sun & Ellis, "Operational Transformation in Real-Time Group Editors" (CSCW, 1998)

OT(Operational Transformation) 알고리즘의 원논문:

  • 핵심 속성:
    • TP1(Transformation Property 1): O1; T(O2, O1) = O2; T(O1, O2)
    • TP2: 3개 이상 동시 연산에도 수렴 보장

버전 벡터 관련

#53: Jonathan Ellis, "Why Cassandra Doesn't Need Vector Clocks" (DataStax, 2013)

Cassandra 프로젝트 리더가 LWW(Last Write Wins)를 선택한 실용적 이유를 설명한 글:

  • "대부분의 애플리케이션에서 LWW가 충분히 좋고, 데이터 유실 위험보다 구현 단순성이 더 가치 있다"
  • cell 단위(컬럼 단위) LWW → 행 전체가 아닌 각 컬럼별로 최신 값을 선택

#56: Parker et al., "Detection of Mutual Inconsistency in Distributed Systems" (IEEE, 1983)

버전 벡터(Version Vector)의 원논문:

  • 각 복제본이 [n1, n2, ..., nk] 형태의 벡터를 유지

#60: Carlos Baquero, "Version Vectors Are Not Vector Clocks" (2011)

자주 혼동되는 버전 벡터와 벡터 클럭의 차이를 명확히 정리한 글:

  • 벡터 클럭(Vector Clock): 이벤트(프로세스의 각 동작)에 부여
  • 버전 벡터(Version Vector): 데이터 객체의 버전에 부여

테마 4: 리더 없는 복제 (25분)


4-1. 리더 없는 복제

Amazon의 Dynamo 논문(2007, #37)에서 대중화된 아키텍처로, 어떤 노드든 쓰기를 직접 받을 수 있습니다.

              클라이언트
           ╱      │      ╲
         쓰기    쓰기    쓰기
         ╱        │        ╲
    ┌─────┐  ┌─────┐  ┌─────┐
    │ N1  │  │ N2  │  │ N3  │    n=3
    │ v2  │  │ v2  │  │(장애)│    w=2 → 2개 성공이면 쓰기 OK
    └─────┘  └─────┘  └─────┘

         읽기    읽기    읽기
         ╱        │        ╲
    ┌─────┐  ┌─────┐  ┌─────┐
    │ N1  │  │ N2  │  │ N3  │    r=2 → 2개 읽어서 최신 값 선택
    │ v2  │  │ v2  │  │ v1  │    (N3 복구 후에도 아직 v1)
    └─────┘  └─────┘  └─────┘
    → v2를 2개 확인 → 최신 값 v2 반환

핵심 차이점: 리더가 없으므로 장애 복구(failover)가 필요 없습니다. 노드가 죽었다 살아나면 그냥 다시 참여하면 됩니다.

정족수(Quorum) 공식: w + r > n

수학적 직관:

  • n개의 노드 중 w개에 쓰기 성공
  • n개의 노드 중 r개에서 읽기
  • w + r > n이면, 쓰기 셋과 읽기 셋이 반드시 1개 이상 겹침
  • 겹치는 노드에 최신 값이 있으므로 → 최신 값 획득 보장
n=3 일 때:

노드:      [N1]  [N2]  [N3]

w=2 쓰기:  [✓]   [✓]   [ ]     ← 2개에 기록
r=2 읽기:  [ ]   [✓]   [✓]     ← 2개에서 읽기
                  ↑
              겹치는 노드! (N2에 최신 값)

주요 설정과 그 특성:

설정 w + r 내결함성 특징
n=3, w=2, r=2 4 > 3 ✓ 1대 장애 허용 가장 일반적인 균형 설정
n=5, w=3, r=3 6 > 5 ✓ 2대 장애 허용 높은 가용성 요구 시
n=3, w=3, r=1 4 > 3 ✓ 쓰기 시 0대 장애 허용 읽기 최적화 (1대만 읽으면 됨)
n=3, w=1, r=3 4 > 3 ✓ 읽기 시 0대 장애 허용 쓰기 최적화 (1대만 쓰면 됨)
n=3, w=1, r=1 2 < 3 ✗ 높은 가용성 최신성 보장 안됨!

4-2. 노드가 다운됐을 때 데이터베이스에 쓰기

읽기 복구(Read Repair):

클라이언트가 r=2로 읽기:
  N1 → v2 (최신)
  N3 → v1 (오래됨)

클라이언트: "N3이 뒤처져 있네" → N3에 v2 기록 (배경에서)
  • 읽기 요청이 올 때마다 자동으로 복구
  • 장점: 즉시 복구, 추가 프로세스 불필요
  • 단점: 자주 읽히는 데이터만 복구됨 → 거의 안 읽히는 데이터는 방치

안티 엔트로피(Anti-Entropy):

백그라운드 프로세스가 주기적으로:
  N1의 데이터 해시 vs N2의 데이터 해시 vs N3의 데이터 해시
  → 불일치 발견 → 최신 값으로 동기화
  • 머클 트리(Merkle Tree)를 사용해 효율적으로 불일치 탐지
  • 장점: 모든 데이터를 커버
  • 단점: 동기화까지 지연 있음, CPU/네트워크 부하

4-3. 정족수 일관성의 한계

정족수 공식을 만족하더라도 다음 상황에서 stale 데이터를 읽을 수 있습니다:

Case 1: 동시 쓰기

  • 두 클라이언트가 동시에 같은 키를 쓰면, 각 노드에 서로 다른 값이 기록될 수 있음
  • w + r > n을 만족해도 "어느 값이 최신인가?"를 판단할 수 없음

Case 2: 부분적 쓰기 실패

  • w개 미만의 노드에만 기록되어 쓰기가 "실패"로 보고됨
  • 그러나 이미 기록된 노드에서 값이 남아 있어, 읽기 시 이 값이 반환될 수 있음
  • 롤백이 되지 않으므로 "실패한 쓰기의 유령"이 돌아다님

Case 3: 복구 시점 문제

  • 새 값을 가진 노드가 장애 → 복구 시 예전 값으로 복원될 수 있음

4-4. 느슨한 정족수와 암시된 핸드오프

느슨한 정족수(Sloppy Quorum):

정상 상황: 쓰기 → N1, N2, N3 중 w=2에 기록

N2, N3 장애 발생 시 (느슨한 정족수):
쓰기 → N1, N4(임시 대리), N5(임시 대리)  ← w=2 충족!
읽기 → N1, N3(복구됨)                    ← r=2 충족!
         ↑
    N4에 쓴 값을 N3은 모름 → stale 데이터!
  • 느슨한 정족수는 가용성을 높이지만 일관성은 보장하지 않음

힌트된 핸드오프(Hinted Handoff, #49):

임시 대리 노드가 원래 노드 복구 시 데이터를 전달하는 메커니즘:

  • 장애 노드 대신 다른 노드가 "힌트"(대리 기록)를 저장
  • 장애 노드가 복구되면 힌트된 데이터를 전달하여 동기화

4-5. 동시 쓰기 감지

두 이벤트 A, B의 관계는 세 가지 중 하나입니다:

1. A → B (A가 B 이전에 발생)
   A의 결과를 B가 알고 있음 → B가 A를 덮어씀

2. B → A (B가 A 이전에 발생)
   B의 결과를 A가 알고 있음 → A가 B를 덮어씀

3. A ∥ B (동시 발생 = concurrent)
   서로의 존재를 모름 → 충돌 해소 필요

구체적 알고리즘 — 서버 측 버전 번호:

1. 서버가 각 키에 버전 번호를 유지
2. 클라이언트가 읽을 때 버전 번호 포함하여 반환
3. 클라이언트가 쓸 때 이전 읽기의 버전 번호를 같이 보냄
4. 서버는 해당 버전 이하의 값을 덮어쓰고,
   동시 쓰기(더 높은 버전이 없는 값)는 "형제(sibling)"로 유지
5. 클라이언트가 다음에 읽을 때 모든 형제를 받아서 병합

테마 4 토론

"왜 모든 데이터베이스가 리더 없는 복제 방식을 선택하지 않는가?"

토론 유도 질문:

  • 리더 없는 복제에서 트랜잭션(ACID)을 지원하기 어려운 이유는?
  • w=1, r=1 설정의 유혹 — 성능은 좋지만 무엇을 잃는가?
  • Cassandra가 LWW를 선택한 실용적 이유는 무엇인가?

테마 4 참고자료 상세 해설

#37: DeCandia et al., "Dynamo: Amazon's Highly Available Key-Value Store" (SOSP, 2007)

리더 없는 복제의 바이블이자, 이 테마 전체의 기반이 되는 논문.

Amazon이 내부 쇼핑카트 등 핵심 서비스를 위해 만든 Dynamo 시스템의 설계:

  • 설계 철학: "항상 쓰기 가능(always writable)" — 가용성을 일관성보다 우선
  • 핵심 기술들의 조합:
    • 일관성 해싱(Consistent Hashing): 노드 추가/제거 시 데이터 이동 최소화
    • 정족수(Quorum): w + r > n으로 읽기 시 최신 값 획득 확률 향상
    • 벡터 클럭: 동시 쓰기 감지
    • 힌트된 핸드오프(Hinted Handoff): 장애 노드 대신 임시 노드가 쓰기를 받고, 복구 후 전달
    • 머클 트리(Merkle Tree): 안티 엔트로피 과정에서 효율적 불일치 탐지
    • 가십 프로토콜(Gossip Protocol): 멤버십/장애 감지를 분산적으로 수행
  • 쇼핑카트 충돌 해소 사례: 두 카트 버전이 동시에 존재하면 "합집합"으로 병합

#44: David K. Gifford, "Weighted Voting for Replicated Data" (SOSP, 1979)

정족수(Quorum) 개념의 원논문:

  • 복제된 데이터에 대한 읽기/쓰기 "투표" 시스템을 최초로 제안
  • 각 복제본에 가중치(weight)를 부여할 수 있음
  • 1979년 논문이지만, 40년이 넘은 지금도 모든 정족수 기반 시스템의 이론적 토대

#45: Heidi Howard et al., "Flexible Paxos: Quorum Intersection Revisited" (arXiv, 2016)

정족수 교차 요건을 완화할 수 있음을 보인 논문:

  • Phase 1(리더 선출) 정족수와 Phase 2(값 결정) 정족수의 합만 n을 초과하면 됨

#49: Jonathan Ellis, "Modern Hinted Handoff" (DataStax, 2012)

Cassandra의 힌트된 핸드오프(Hinted Handoff) 구현을 설명한 글:

  • 힌트 저장소의 크기 제한 (디스크 공간)
  • 힌트 전달 시 스로틀링 (네트워크 부하 방지)
  • 힌트 만료 정책 (너무 오래된 힌트는 안티 엔트로피로 대체)

#51: Apache Cassandra Documentation

Cassandra의 공식 문서로, 정족수 설정의 실무 가이드:

  • 일관성 수준(Consistency Level): ONE, QUORUM, ALL, LOCAL_QUORUM, EACH_QUORUM 등
  • LOCAL_QUORUM: 로컬 DC 내에서만 정족수 충족 → 다중 DC에서 지연 감소

#55: Joel Jacobson, "Riak 2.0: Data Types" (2014)

Riak 2.0에서 CRDT 기반 데이터 타입이 어떻게 사용되는지 소개:

  • 지원 타입: 카운터(Counter), 집합(Set), 맵(Map), 레지스터(Register), 플래그(Flag)
  • 맵(Map) 타입은 중첩 가능 → 복잡한 데이터 구조를 CRDT로 표현

정리: 복제 전략 선택 가이드 (10분)

의사결정 트리

Q1: 쓰기가 한 곳에서만 발생하면 충분한가?
├── Yes → 단일 리더 복제
│         (MySQL, PostgreSQL, MongoDB 기본)
│         ✓ 가장 단순, 대부분의 워크로드에 적합
│
└── No → Q2: 모든 노드가 대등해야 하는가?
          ├── No → 다중 리더 복제
          │         (Aurora Multi-Writer, CouchDB)
          │         ⚠ 충돌 해소 전략 필수
          │
          └── Yes → 리더 없는 복제
                    (Cassandra, Riak, DynamoDB)
                    ⚠ 정족수 설계 + 동시 쓰기 처리 필수

복제 모델별 비교 요약

특성 단일 리더 다중 리더 리더 없음
쓰기 충돌 없음 있음 (해소 필요) 있음 (해소 필요)
쓰기 가용성 리더 장애 시 중단 DC 장애에도 계속 노드 장애에도 계속
읽기 확장 팔로워 추가 팔로워 추가 노드 추가
쓰기 확장 불가 (리더 1대) 제한적 가능 가능
일관성 가장 강함 약함 (비동기 DC간) 설정에 따라 다름
구현 복잡도 낮음 높음 중간
대표 사용처 OLTP 범용 다중 DC, 오프라인 앱 고가용성 KV 스토어

발표 핵심 정리 — 세 가지 기억할 것

  1. 복제는 트레이드오프의 연속이다. 일관성, 가용성, 지연 시간 중 모든 것을 동시에 만족시킬 수 없습니다.
  2. 비동기 복제는 기본값이다. 대부분의 시스템이 비동기를 선택하며, 그로 인한 복제 지연 문제를 애플리케이션 레벨에서 대응해야 합니다.
  3. 충돌 해소는 비즈니스 결정이다. LWW의 데이터 유실을 허용할지, CRDT/버전 벡터의 복잡성을 감수할지는 기술이 아닌 비즈니스 요구사항에 의해 결정됩니다.

참고 문헌

  • Lindsay et al., "Notes on Distributed Databases," IBM Research, 1979
  • Oracle Active Data Guard White Paper, 2013
  • Kafka Intra-Cluster Replication, ApacheCon 2013
  • Yoshinori Matsunobu, "Semi-Synchronous Replication at Facebook," 2014
  • Chain Replication (van Renesse & Schneider), OSDI 2004
  • Werner Vogels, "Eventually Consistent," ACM Queue, 2008
  • Douglas B. Terry, "Replicated Data Consistency Explained Through Baseball," 2011

테마별 참고자료 매핑

테마 1: 단일 리더 복제 (25분)

리더-팔로워 구조의 기본 원리, 동기/비동기 복제, 새로운 팔로워 설정, 노드 중단 처리, 복제 로그 구현을 다룹니다.

관련 참고자료

# 참고자료 핵심 키워드
- Lindsay et al., "Notes on Distributed Databases" (1979) 분산 DB 기초
- Oracle Active Data Guard White Paper (2013) Oracle 복제
- Kafka Intra-Cluster Replication (ApacheCon 2013) Kafka 복제 로그
- Yoshinori Matsunobu, "Semi-Synchronous Replication at Facebook" (2014) Facebook 반동기 복제
- Chain Replication (van Renesse & Schneider, OSDI 2004) 체인 복제
29 CouchDB: The Definitive Guide CouchDB 복제 구현
35 John Daily, "Clocks Are Bad, or, Welcome to Distributed Systems" 분산 시스템 시계 문제

테마 2: 복제 지연 문제 (25분)

비동기 복제에서 발생하는 복제 지연(Replication Lag) 문제를 사용자 경험 측면에서 심도 있게 다룹니다.

관련 참고자료

# 참고자료 핵심 키워드
- Werner Vogels, "Eventually Consistent" (2008) 최종적 일관성 정의
- Douglas B. Terry, "Replicated Data Consistency Explained Through Baseball" (2011) 일관성 모델 비유 설명
48 Peter Bailis et al., "Quantifying Eventual Consistency with PBS" 일관성 정량화
54 Leslie Lamport, "Time, Clocks, and the Ordering of Events" (1978) 인과성 순서의 성경
61 Schwarz & Mattern, "Detecting Causal Relationships in Distributed Computations" 인과 관계 탐지

테마 3: 다중 리더 복제 (25분)

AWS Aurora Multi-Writer를 포함하여, 여러 곳에서 쓰기가 발생할 때의 복잡성을 다룹니다.

관련 참고자료

다중 마스터 복제

# 참고자료 핵심 키워드
26 Tungsten Replicator MySQL 다중 마스터 복제 도구
27 BDR 0.10.0 Documentation (PostgreSQL) 양방향 복제
28 Robert Hodges, "If You Must Deploy Multi-Master Replication, Read This First" 다중 마스터 실무 경고
34 Robert Hodges, "State of the Art for MySQL Multi-Master" MySQL 다중 마스터 현황
36 Riley Berton, "Is BDR in Postgres Transactional?" BDR 트랜잭션 한계
43 Lars Hofhansl, "HBASE-7709: Infinite Loop in Master/Master Replication" 다중 마스터 무한루프 버그

충돌 해소 알고리즘

# 참고자료 핵심 키워드
30 AppJet/Etherpad, "EasySync Technical Manual" 협업 편집 동기화
31 John Day-Richter, "What's Different About the New Google Docs" Google Docs OT
32 Martin Kleppmann, "A Conflict-Free Replicated JSON Datatype" CRDT JSON
33 Frazer Clement, "Eventual Consistency – Detecting Conflicts" 충돌 감지
38 Marc Shapiro et al., "Convergent and Commutative Replicated Data Types" CRDT 종합 연구
39 Sam Elliott, "CRDTs: An UPDATE" CRDT 실무
40 Russell Brown, "A Bluffers Guide to CRDTs in Riak" Riak CRDT
42 Sun & Ellis, "Operational Transformation in Real-Time Group Editors" OT 알고리즘 원논문

버전 벡터

# 참고자료 핵심 키워드
53 Jonathan Ellis, "Why Cassandra Doesn't Need Vector Clocks" Cassandra LWW 선택 이유
56 Parker et al., "Detection of Mutual Inconsistency" 버전 벡터 원논문
57 Nuno Preguiça et al., "Dotted Version Vectors" 점 버전 벡터
58 Sean Cribbs, "A Brief History of Time in Riak" Riak 시간 관리
59 Russell Brown, "Vector Clocks Revisited Part 2" 버전 벡터 실무
60 Carlos Baquero, "Version Vectors Are Not Vector Clocks" 버전벡터 ≠ 벡터클럭

테마 4: 리더 없는 복제 (25분)

아마존 다이나모(Dynamo) 스타일의 시스템이 리더 없이도 어떻게 가용성을 극대화하는지 다룹니다.

관련 참고자료

# 참고자료 핵심 키워드
37 DeCandia et al., "Dynamo: Amazon's Highly Available Key-Value Store" Dynamo 원논문 (필독)
44 David K. Gifford, "Weighted Voting for Replicated Data" (1979) 정족수 원논문
45 Heidi Howard et al., "Flexible Paxos: Quorum Intersection Revisited" 유연한 정족수
46 Joseph Blomstedt, "Absolute Consistency" Riak 일관성 논의
47 Joseph Blomstedt, "Bringing Consistency to Riak" Riak 일관성 구현
49 Jonathan Ellis, "Modern Hinted Handoff" 힌트된 핸드오프
50 Project Voldemort Wiki Voldemort 구현
51 Apache Cassandra Documentation Cassandra 정족수
52 Riak Enterprise: Multi-Datacenter Replication Riak 다중 DC
55 Joel Jacobson, "Riak 2.0: Data Types" Riak 데이터 타입

발표 준비용 필독 Top 10

  1. #37 Dynamo 논문 - 리더 없는 복제의 바이블
  2. #54 Lamport 시간/순서 논문 - 인과성의 기초
  3. #38 CRDT 종합 연구 - 충돌 해소 이론
  4. #44 Gifford 정족수 논문 - w+r>n 원리
  5. #28 Multi-Master 실무 경고 - 토론 소스
  6. #32 Kleppmann CRDT JSON - 최신 연구
  7. #57 Dotted Version Vectors - 버전 벡터 심화
  8. Facebook Semi-Sync 복제 - 실무 사례
  9. #49 Modern Hinted Handoff - 장애 복구
  10. #42 OT 알고리즘 - 협업 편집 원리

발표 시간 배분 가이드

순서 테마 시간
1 테마 1: 단일 리더 복제 25분
2 테마 2: 복제 지연 문제 25분
3 테마 3: 다중 리더 복제 25분
4 테마 4: 리더 없는 복제 25분
5 Q&A 및 복제 전략 선택 가이드 10분
  총합 110분

참고자료 출처 (번호별)

# 참고자료 링크
25 Terry Pratchett, Reaper Man (1991) ISBN: 978-0-575-04979-6
26 Tungsten Replicator github.com
27 BDR 0.10.0 Documentation bdr-project.org
28 Robert Hodges, "If You Must Deploy Multi-Master Replication, Read This First" (2012) scale-out-blog
29 CouchDB: The Definitive Guide (O'Reilly, 2010) ISBN: 978-0-596-15589-6
30 AppJet/Etherpad, "EasySync Technical Manual" (2011) github.com
31 John Day-Richter, "What's Different About the New Google Docs" (2010) drive.googleblog.com
32 Martin Kleppmann, "A Conflict-Free Replicated JSON Datatype" (2016) arXiv:1608.03960
33 Frazer Clement, "Eventual Consistency – Detecting Conflicts" (2011) messagepassing.blogspot
34 Robert Hodges, "State of the Art for MySQL Multi-Master" (Percona Live, 2013) web.archive.org
35 John Daily, "Clocks Are Bad, or, Welcome to Distributed Systems" (2013) riak.com
36 Riley Berton, "Is BDR in Postgres Transactional?" (2016) sdf.org
37 DeCandia et al., "Dynamo: Amazon's Highly Available Key-Value Store" (SOSP, 2007) allthingsdistributed.com
38 Shapiro et al., "Convergent and Commutative Replicated Data Types" (INRIA, 2011) hal.inria.fr
39 Sam Elliott, "CRDTs: An UPDATE" (RICON West, 2013) speakerdeck.com
40 Russell Brown, "A Bluffers Guide to CRDTs in Riak" (2013) gist.github.com
41 Farinier et al., "Mergeable Persistent Data Structures" (JFLA, 2015) gazagnaire.org
42 Sun & Ellis, "Operational Transformation in Real-Time Group Editors" (CSCW, 1998) citeseerx
43 Lars Hofhansl, "HBASE-7709: Infinite Loop in Master/Master Replication" (2013) issues.apache.org
44 Gifford, "Weighted Voting for Replicated Data" (SOSP, 1979) cmu.edu
45 Howard et al., "Flexible Paxos: Quorum Intersection Revisited" (2016) arXiv:1608.06696
46 Joseph Blomstedt, "Re: Absolute Consistency" (2012) web.archive.org
47 Joseph Blomstedt, "Bringing Consistency to Riak" (RICON West, 2012) vimeo.com
48 Bailis et al., "Quantifying Eventual Consistency with PBS" (CACM, 2014) bailis.org
49 Jonathan Ellis, "Modern Hinted Handoff" (DataStax, 2012) datastax.com
50 Project Voldemort Wiki github.com
51 Apache Cassandra Documentation cassandra.apache.org
52 Riak Enterprise: Multi-Datacenter Replication (Basho, 2014) web.archive.org
53 Jonathan Ellis, "Why Cassandra Doesn't Need Vector Clocks" (2013) datastax.com
54 Lamport, "Time, Clocks, and the Ordering of Events" (CACM, 1978) microsoft.com
55 Joel Jacobson, "Riak 2.0: Data Types" (2014) blog.joeljacobson.com
56 Parker et al., "Detection of Mutual Inconsistency" (IEEE, 1983) yale.edu
57 Preguiça et al., "Dotted Version Vectors" (arXiv, 2010) arXiv:1011.5808
58 Sean Cribbs, "A Brief History of Time in Riak" (RICON, 2014) speakerdeck.com
59 Russell Brown, "Vector Clocks Revisited Part 2" (Basho, 2015) riak.com
60 Carlos Baquero, "Version Vectors Are Not Vector Clocks" (2011) haslab.wordpress.com
61 Schwarz & Mattern, "Detecting Causal Relationships in Distributed Computations" (1994) ethz.ch
728x90
반응형