← 문제로

9. 질문 — CAP 정리와 분산 트랜잭션 (Saga, 2PC)

난이도 최상
내 답안
모범답안

모범답안 — CAP 정리와 분산 트랜잭션 (Saga / 2PC)

난이도: 최상

핵심 답변

CAP: 네트워크 분단(P)이 발생하면 일관성(C)과 가용성(A)을 동시에 만족할 수 없다 — 분단 중엔 "오래된 답이라도 줄지(A)" "응답을 거부하고 일관성을 지킬지(C)" 택해야 한다. 분산에서 분단은 언제든 일어나므로 P는 필수, 결국 CP냐 AP냐의 선택이다. 재화처럼 정확성이 생명인 데이터는 CP(강한 일관성), 채팅·랭킹처럼 잠깐 어긋나도 되는 건 AP(최종 일관성). 교차 트랜잭션은 2PC(강하지만 느리고 블로킹) 또는 **Saga(보상 트랜잭션으로 최종 일관성)**로 처리한다.

깊이 있는 설명

CAP 정리

  • C(일관성): 모든 노드가 같은 최신 데이터를 본다.
  • A(가용성): 모든 요청이 (성공이든) 응답을 받는다.
  • P(분단 내성): 노드 간 메시지가 끊겨도 시스템이 동작.
  • 분단이 없을 땐 C와 A 둘 다 가능. 분단이 나면 둘 중 하나를 포기해야 한다. 실무에선 "분단 시 어느 쪽을 택하느냐"로 이해하는 게 정확(PACELC로 확장: 분단이 없을 땐 지연 vs 일관성 트레이드오프).

강한 vs 최종 일관성

  • 강한 일관성: 항상 최신값. 대신 지연·가용성 비용(합의·락).
  • 최종 일관성: 잠시 어긋나도 결국 수렴. 빠르고 가용하지만 "방금 산 아이템이 잠깐 안 보임" 같은 현상.
  • 게임 매핑: 재화·결제·아이템=강한 일관성, 랭킹·통계·채팅·존재감(presence)=최종 일관성 허용.

2PC vs Saga

  • 2PC: 코디네이터가 모든 참여자에게 prepare→commit. 원자성은 강하지만 블로킹(코디네이터 장애 시 참여자가 락을 잡고 대기), 지연·확장성 약함. 게임 핫패스엔 부적합, 드문 정합성 작업에 제한적.
  • Saga: 큰 트랜잭션을 로컬 트랜잭션들의 시퀀스로 쪼개고, 중간 실패 시 보상(compensating) 트랜잭션으로 되돌린다. 예: 골드 차감(로컬) → 아이템 지급(로컬), 실패하면 골드 환불. 최종 일관성·비블로킹·확장성↑. 단 중간 상태가 잠깐 노출되고, 보상 로직을 직접 설계해야 함.

분산 exactly-once 근사

  • 각 단계에 멱등 키(거래ID) 부여 → 재시도해도 한 번만 반영(DB UNIQUE·dedup).
  • 차감/지급을 로컬 트랜잭션 + 아웃박스(outbox) 로 묶어 "DB 커밋과 이벤트 발행"을 원자화, 소비자는 멱등.
  • 외부 펜싱 토큰/버전으로 stale 노드의 중복 처리 차단.

응용/실무 연결

  • 교차 서버 거래: Saga + 에스크로(중간 보관) + 멱등 키. 양쪽이 commit/ack 전까지 아이템을 "잠금" 상태로.
  • 결제 → 재화 지급: 아웃박스 패턴으로 결제 DB 커밋과 지급 이벤트를 원자화, 지급 소비는 멱등.
  • 랭킹: AP로 두고 주기적 수렴(약간의 지연 허용).

흔한 오답·함정

  • "CAP에서 셋 다 포기 못 하니 하나 고른다" 식의 단순화 — 정확히는 분단 시 C/A 중 택. 평상시엔 둘 다 가능.
  • 게임 전체에 강한 일관성 강제 → 지연·가용성 폭탄. 데이터별로 차등 적용.
  • 2PC를 일반 트랜잭션처럼 남용 → 블로킹·장애 확산. 대부분 Saga가 현실적.

꼬리질문 대비

  • Q. 아웃박스 패턴이란? 비즈니스 DB 트랜잭션 안에서 "보낼 이벤트"를 같은 DB의 outbox 테이블에 함께 기록 → 별도 릴레이가 읽어 큐로 발행. DB 커밋과 발행의 원자성을 확보.
  • Q. Saga의 보상이 또 실패하면? 재시도 + 수동 개입 큐(DLQ) + 멱등 보상. 보상도 멱등이어야 함.
  • Q. 강한 일관성을 분산에서 구현하는 합의 알고리즘? Raft/Paxos(리더 선출·로그 복제). etcd/ZooKeeper가 이를 제공.