콘텐츠로 이동

분산 시스템 기초 (CAP & Consistency)

분류: Layer 9 - 아키텍처 & 설계 패턴

분산 시스템 기초 (CAP & Consistency)

섹션 제목: “분산 시스템 기초 (CAP & Consistency)”

분산 시스템은 네트워크로 연결된 여러 노드가 협력하여 하나의 서비스처럼 동작하는 시스템이며, CAP 정리는 네트워크 장애 시 일관성(Consistency)과 가용성(Availability) 중 하나를 포기해야 한다는 근본적 제약이다.


프론트엔드 브릿지: 브라우저 캐시에서 stale 데이터를 보여주는 경험을 한 적 있을 것이다. Cache-Control: max-age=3600으로 캐싱된 HTML이 서버에서 이미 갱신되었는데도 1시간 동안 구버전을 보여주는 현상이다. 이것이 분산 시스템에서 말하는 Eventually Consistent 데이터와 동일한 원리다. 클라이언트(브라우저)와 서버 간 데이터 일관성 문제가 서버 노드들 사이에서도 그대로 발생한다.

BackOps 엔지니어로 성장하면서 이 지식이 필요한 이유:

  • AWS 서비스 선택 근거 설명: “왜 이 데이터는 DynamoDB에, 저 데이터는 Aurora에 넣었나?”를 CAP/PACELC로 설명할 수 있어야 한다.
  • 장애 원인 분석: Write 후 Read 시 데이터가 없는 현상이 버그인지, Eventual Consistency 특성인지 구별해야 한다.
  • 시니어 대화 가능: 시스템 설계 리뷰에서 “이 서비스는 AP 시스템인가 CP 시스템인가”라는 질문에 답해야 한다.

2000년 Eric Brewer가 제안하고 2002년 Gilbert & Lynch가 수학적으로 증명한 정리. 분산 시스템은 아래 세 속성 중 최대 두 가지만 동시에 보장할 수 있다.

속성약어의미
ConsistencyC모든 노드가 동시에 동일한 데이터를 본다. 읽기는 항상 최신 쓰기 결과를 반환한다.
AvailabilityA모든 요청이 (최신 데이터 보장 없이) 반드시 응답을 받는다. 노드가 살아있으면 응답한다.
Partition ToleranceP네트워크 파티션(노드 간 통신 단절)이 발생해도 시스템이 계속 동작한다.

왜 셋 중 둘만 선택 가능한가:

[노드 A] ─────────────── [노드 B]
쓰기 완료 네트워크 단절
x = 10 x = 5 (구버전)
클라이언트가 노드 B에 읽기 요청:
- 응답하면(Availability 보장): 구버전 x=5 반환 → Consistency 위반
- 거부하면(Consistency 보장): 요청 실패 응답 → Availability 위반

네트워크 파티션은 분산 시스템에서 회피 불가능하다. 물리 케이블은 끊어지고, AWS AZ 간 통신 지연은 반드시 발생한다. 따라서 실질적 선택은 P가 발생했을 때 C와 A 중 무엇을 포기하느냐다.

비유:

  • CP 선택 = 은행 ATM. 네트워크 단절 시 “현재 서비스 불가” 안내를 하지만 잔액 불일치는 절대 허용하지 않는다.
  • AP 선택 = 소셜미디어 좋아요 수. 일시적으로 노드마다 다른 숫자를 보여줘도 괜찮다. 결국엔 맞춰진다.

CP 시스템 (Consistency + Partition Tolerance)

섹션 제목: “CP 시스템 (Consistency + Partition Tolerance)”

파티션 발생 시 일관성을 위해 가용성을 포기한다. 일부 요청은 오류를 반환하지만 반환하는 데이터는 항상 최신이다.

CP 시스템 동작:
네트워크 파티션 발생
일관성 확인 불가 → 요청 거부 (Error 반환)
✓ 데이터 정확성 보장
✗ 일시적 서비스 중단
시스템특징
ZooKeeper분산 조율 서비스. Leader 선출 중 요청 거부. 과반수 노드 동의 후에만 쓰기 허용
HBaseHDFS 위의 CP 스토어. 리전 서버 장애 시 해당 리전 읽기/쓰기 중단
etcdKubernetes 클러스터 상태 저장소. Raft 합의 알고리즘으로 강한 일관성
Aurora (MySQL/PostgreSQL)6개 복제본 중 4개 이상 확인 후 쓰기 커밋. Read Replica 지연 있음
티켓팅 시스템같은 좌석을 두 사람이 예매하는 오버부킹을 절대 허용 불가

AP 시스템 (Availability + Partition Tolerance)

섹션 제목: “AP 시스템 (Availability + Partition Tolerance)”

파티션 발생 시 가용성을 위해 일관성을 포기한다. 구버전 데이터를 반환할 수 있지만 요청은 항상 처리한다.

AP 시스템 동작:
네트워크 파티션 발생
가능한 노드로 요청 처리 → 응답 반환 (구버전일 수 있음)
✓ 서비스 지속성 보장
✗ 데이터 일시적 불일치 허용
시스템특징
CassandraPeer-to-peer 구조. 어느 노드에나 쓰기 가능. Netflix 추천 엔진에 사용
DynamoDB기본적으로 AP. Eventually Consistent Read가 기본값
CouchDBMVCC 기반. 충돌은 애플리케이션이 해결
DNS레코드 갱신 후 전파 지연(TTL). 전 세계 가용성 우선
쇼핑몰 장바구니네트워크 장애 중에도 장바구니 담기 가능. 나중에 동기화

파티션을 허용하지 않는다는 뜻으로, 실제로는 단일 노드 또는 단일 데이터센터 시스템이다. 네트워크 파티션이 발생하면 시스템 자체가 동작 불가다.

시스템특징
단일 노드 RDB (MySQL, PostgreSQL)파티션 자체가 없어서 CA 가능
단일 AZ 배포AZ 장애 = 전체 장애 감수

실무에서 “CA 시스템을 쓰겠다”는 말은 “분산 배포를 포기하겠다”는 뜻이다. 고가용성이 필요하면 CA는 선택지가 아니다.


CAP 정리는 네트워크 파티션이 발생했을 때만 다룬다. 하지만 실제 시스템은 파티션이 없는 정상 상태에서도 성능(지연)과 일관성 간의 트레이드오프가 존재한다. 2012년 Daniel Abadi가 PACELC로 이를 보완했다.

PACELC 공식:
if Partition:
→ Availability vs Consistency 선택
Else (정상 동작):
→ Latency vs Consistency 선택
분류의미대표 시스템선택 이유
PA/EL파티션 시 가용성, 평상시 낮은 지연 우선DynamoDB(기본), Cassandra, Riak글로벌 서비스, 높은 처리량 필요
PA/EC파티션 시 가용성, 평상시 일관성 우선Cosmos DB (일부 설정)가용성은 필수이나 정확성도 중요
PC/EL파티션 시 일관성, 평상시 낮은 지연 우선Yahoo! PNUTS드문 조합
PC/EC파티션 시 일관성, 평상시 일관성 우선ZooKeeper, etcd, CockroachDB금융, 설정 관리 등 정확성 최우선

Aurora의 PACELC 위치:

  • Partition 시: CP → 일관성 우선
  • Else: Multi-AZ 동기 복제로 EC(일관성 우선), 단 쓰기 지연이 약간 있음
  • Read Replica 사용 시: EL(낮은 지연)로 설정 가능하나 복제 지연(lag) 허용 필요
DynamoDB (PA/EL):
정상 상태: 클라이언트 → 가장 가까운 노드 → 즉시 응답 (EL: 낮은 지연)
파티션 시: 클라이언트 → 살아있는 노드 → 구버전 응답 (PA: 가용성)
ZooKeeper (PC/EC):
정상 상태: 클라이언트 → Leader → 과반수 동의 → 응답 (EC: 일관성, 지연 있음)
파티션 시: 과반수 달성 불가 → 요청 거부 (PC: 일관성)

“일관성”이라는 단어는 강도에 따라 여러 모델로 나뉜다. 강할수록 성능 비용이 크다.

강한 일관성 ◄────────────────────────────────► 약한 일관성
│ │
Linearizable Sequential Read-Your-Writes Eventual
│ │ │ │
최강 순서 보장 내 쓰기 보장 결국 수렴

가장 강한 일관성. 모든 읽기는 가장 최근에 완료된 쓰기 결과를 반환한다. 시스템 전체가 단일 CPU처럼 동작하는 것처럼 보인다.

  • 사용 사례: ZooKeeper의 Znode, etcd의 분산 락
  • 비용: 모든 노드 동기화 대기 → 높은 지연
Write(x=10) 완료
Read(x) → 반드시 10 반환 (어느 노드에서 읽어도)

각 프로세스의 연산 순서는 보장하되, 전역 실시간 순서는 보장하지 않는다. 내 관점에서의 순서는 맞지만 다른 노드와 실시간 동기화는 아니다.

  • 사용 사례: 멀티코어 CPU 메모리 모델

Read-Your-Writes (자신의 쓰기 읽기 보장)

섹션 제목: “Read-Your-Writes (자신의 쓰기 읽기 보장)”

내가 쓴 데이터는 내가 반드시 읽을 수 있다. 다른 클라이언트는 구버전을 볼 수 있어도, 쓴 사람은 자신의 최신 값을 본다.

  • 사용 사례: 소셜미디어 프로필 업데이트 (내가 바꾼 프로필을 나는 즉시 볼 수 있어야 함)
  • 구현: Session Token을 활용해 동일 레플리카에 라우팅
클라이언트 A: Write(profile="새 이름") → 성공
클라이언트 A: Read(profile) → "새 이름" 반환 ✓ (Read-Your-Writes 보장)
클라이언트 B: Read(profile) → "구 이름" 반환 가능 (다른 레플리카)

충분한 시간이 지나면 모든 노드가 동일한 값으로 수렴한다. 수렴 전까지는 노드마다 다른 값을 반환할 수 있다.

  • 사용 사례: DNS 전파, S3 (2020년 이전), Cassandra 기본 설정
  • 장점: 높은 가용성, 낮은 지연, 수평 확장 용이
Write(x=10) → 노드 A에 반영
├─ 노드 A: Read → 10 ✓
├─ 노드 B: Read → 5 (아직 복제 중) ← Eventual Consistency
└─ 노드 C: Read → 5 (아직 복제 중)
[복제 완료 후]
├─ 노드 A: Read → 10 ✓
├─ 노드 B: Read → 10 ✓
└─ 노드 C: Read → 10 ✓

Writer Instance ──── 6개 복제본 (3 AZ × 2)
└── 쓰기: 4/6 복제본 확인 후 커밋 (강한 일관성)
읽기: Writer에서 직접 → 항상 최신
읽기: Read Replica → 복제 지연 가능 (수 ms~수 초)
  • CAP: CP — 파티션 시 쓰기 중단 (최소 4/6 복제본 필요)
  • Consistency: 기본적으로 Strong (Writer 직접 읽기), Read Replica는 Eventual
  • 선택 기준: 트랜잭션 ACID 보장 필요, 복잡한 JOIN, 금융/주문 데이터
DynamoDB Table
├── Eventually Consistent Read (기본)
│ → 최근 완료된 쓰기가 반영 안 될 수 있음
│ → 읽기 용량 유닛 1 소비
└── Strongly Consistent Read (옵션)
→ 반드시 최신 값 반환
→ 읽기 용량 유닛 2 소비 (2배 비용)
  • CAP: AP — 파티션 시 가용성 유지, 구버전 데이터 허용
  • Consistency: 기본 Eventual, 옵션으로 Strong (2배 비용)
  • 선택 기준: 높은 처리량(초당 수만 TPS), 글로벌 테이블, 세션/게임 상태
2020년 12월 이전: Eventual Consistency
PUT object → 즉시 GET → 구버전 반환 가능
DELETE object → 즉시 GET → 객체 여전히 반환 가능
2020년 12월 이후: Strong Consistency (추가 비용 없음)
PUT/DELETE 이후 GET → 항상 최신 상태 반환
  • AWS가 내부 아키텍처를 개선하여 성능 저하 없이 강한 일관성 달성
  • 단, S3 Replication(Cross-Region)은 여전히 Eventually Consistent
Redis Cluster Mode:
Primary ──복제──► Replica
Primary 장애 시: Replica가 Primary로 승격
승격 전 기간(수 초): 읽기는 Replica에서 구버전 반환
  • CAP: AP — 레플리카에서 읽기 허용, 구버전 데이터 가능
  • Consistency: Eventual (Primary → Replica 비동기 복제)
  • 선택 기준: 세션 캐시, 빈번한 읽기 캐싱, 속도 최우선
서비스CAPPACELC기본 Consistency강한 일관성
Aurora (Writer)CPPC/ECStrong항상
Aurora (Read Replica)CPPA/ELEventual설정 불가
DynamoDBAPPA/ELEventual옵션 (2배 비용)
S3APPA/ECStrong (2020~)기본 제공
ElastiCacheAPPA/ELEventual미지원
RDS Multi-AZCPPC/ECStrong항상

”어떤 데이터베이스를 선택할까?” 체크리스트

섹션 제목: “”어떤 데이터베이스를 선택할까?” 체크리스트”
Step 1: 이 데이터에 ACID 트랜잭션이 필요한가?
YES → Aurora / RDS (CP 시스템)
NO → Step 2로
Step 2: 초당 요청 수가 10,000 TPS 이상인가?
YES → DynamoDB (AP, 무제한 수평 확장)
NO → Step 3으로
Step 3: 데이터 불일치가 비즈니스에 치명적인가?
YES (금융, 재고, 예약) → Aurora CP 선택
NO (소셜, 로그, 캐시) → DynamoDB AP 선택
시나리오선택이유
결제 처리, 잔액 차감Aurora (CP)이중 차감 절대 불가, ACID 필수
사용자 세션 관리DynamoDB (AP)세션 만료 시 재로그인 허용, 높은 TPS
상품 재고 (판매 중)Aurora (CP)오버셀링 방지
상품 조회 (카탈로그)DynamoDB (AP)읽기 많고 약간의 지연 허용
알림/이벤트 로그DynamoDB (AP)순서 느슨, 높은 쓰기 처리량
글로벌 사용자 프로필DynamoDB Global Tables (AP)멀티 리전, 낮은 지연 우선
분산 락 (선착순 이벤트)Redis (또는 DynamoDB Conditional Write)원자적 연산

NestJS API + Aurora + DynamoDB를 함께 쓰는 경우의 아키텍처 판단:

[NestJS API]
├── 트랜잭션 필요한 데이터 → Aurora (CP)
│ ├── 주문 (order)
│ ├── 결제 (payment)
│ └── 재고 (inventory)
└── 높은 처리량 / 유연한 스키마 → DynamoDB (AP)
├── 사용자 세션
├── 이벤트 로그
└── 타임라인 데이터
// Aurora Read Replica에서 읽을 때 — 복제 지연 인지 필수
// 주문 생성 직후 주문 목록 조회는 Writer에서 해야 함
// 잘못된 패턴:
await orderRepository.create(orderData); // Writer에 쓰기
return await orderReadRepo.findAll(); // Read Replica에서 조회 → 새 주문 없을 수 있음
// 올바른 패턴:
await orderRepository.create(orderData); // Writer에 쓰기
return await orderRepository.findAll(); // Writer에서 조회 → 항상 최신
// 기본: Eventually Consistent (빠름, 저렴)
const result = await dynamoClient
.get({
TableName: "sessions",
Key: { userId },
})
.promise();
// 강한 일관성이 필요할 때 (2배 비용)
const result = await dynamoClient
.get({
TableName: "sessions",
Key: { userId },
ConsistentRead: true, // 읽기 용량 2배 소비
})
.promise();
// 판단 기준:
// - 로그인 직후 권한 확인 → ConsistentRead: true
// - 일반 프로필 조회 → 기본값 (Eventually Consistent)

  • CAP 정리에서 P(Partition Tolerance)가 왜 실질적으로 포기 불가능한지 설명할 수 있다
  • ZooKeeper가 CP인 이유와 파티션 발생 시 어떤 동작을 하는지 설명할 수 있다
  • DynamoDB의 기본 읽기가 Eventually Consistent인 이유와 Strongly Consistent Read와의 차이를 설명할 수 있다
  • PACELC에서 “Else” 부분(파티션 없을 때)의 Latency vs Consistency 트레이드오프를 설명할 수 있다
  • Aurora Write 후 Read Replica에서 읽을 때 데이터가 없을 수 있는 이유를 설명할 수 있다
  • “이 서비스는 AP인가 CP인가”라는 질문에 선택 근거와 함께 답할 수 있다
  • Strong Consistency와 Linearizable의 차이를 설명할 수 있다

트러블슈팅 1: Write 후 바로 Read 시 데이터가 없음 (Eventual Consistency 이해 부재)

섹션 제목: “트러블슈팅 1: Write 후 바로 Read 시 데이터가 없음 (Eventual Consistency 이해 부재)”

증상:

POST /orders → 201 Created
GET /orders → 방금 생성한 주문이 목록에 없음

원인:

  • DynamoDB의 기본 읽기는 Eventually Consistent
  • Write는 특정 노드에 완료되었으나 다른 레플리카로 전파 전에 Read가 발생
  • 복제 지연은 보통 수십 ms~수 초

해결:

// 방법 1: Strongly Consistent Read 사용
const result = await dynamoClient
.get({
Key: { orderId },
ConsistentRead: true, // 쓰기 직후 읽기 보장
})
.promise();
// 방법 2: Write 응답값을 그대로 반환 (Read 생략)
const created = await orderService.create(dto);
return created; // DB 재조회 불필요
// 방법 3: 동일 레플리카로 라우팅 (Read-Your-Writes)
// Session 기반 sticky routing 활용

예방:

  • API 설계 시 Create 후 Redirect to GET 패턴을 쓸 경우 ConsistentRead 필수
  • 단순 생성 응답은 DB 재조회 대신 생성된 객체 직접 반환

트러블슈팅 2: DynamoDB Strongly Consistent Read 비용 폭증

섹션 제목: “트러블슈팅 2: DynamoDB Strongly Consistent Read 비용 폭증”

증상:

DynamoDB 비용이 예상의 2배 청구
CloudWatch: ConsumedReadCapacityUnits 급증

원인:

  • ConsistentRead: true는 읽기 용량 유닛(RCU)을 2배 소비
  • Eventually Consistent Read: 1 RCU per 4KB
  • Strongly Consistent Read: 2 RCU per 4KB (동일 데이터에 2배 비용)
  • 전체 API에 ConsistentRead를 일괄 적용한 경우 발생

해결:

// 비용 최적화: 필요한 경우에만 ConsistentRead 사용
class OrderRepository {
// 주문 생성 직후 확인 - Strong 필요
async findAfterCreate(orderId: string) {
return this.get(orderId, { ConsistentRead: true });
}
// 일반 목록 조회 - Eventual 충분
async list(userId: string) {
return this.query(userId, { ConsistentRead: false }); // 기본값
}
}

판단 기준:

  • 금융 트랜잭션 직후 확인 → Strong 필수
  • 대시보드, 통계, 목록 조회 → Eventual 충분 (비용 절감)
  • 2배 비용이 부담되면 Aurora 전환 고려 (쓰기 후 바로 읽기가 잦은 패턴)

트러블슈팅 3: Aurora Read Replica 지연으로 인한 데이터 불일치

섹션 제목: “트러블슈팅 3: Aurora Read Replica 지연으로 인한 데이터 불일치”

증상:

사용자가 프로필을 수정하고 새로고침 → 이전 데이터가 보임
주문 완료 후 주문 목록 → 새 주문 없음

원인:

  • Aurora Read Replica는 Writer와 비동기 복제
  • 일반적으로 수 ms 지연이지만 부하 시 수 초까지 증가 가능
  • replica_lag 모니터링 항목으로 확인 가능

해결:

// TypeORM 예시: 읽기 전략 선택
@Injectable()
class OrderService {
constructor(
@InjectRepository(Order) private repo: Repository<Order>,
@InjectDataSource("reader") private readerConn: DataSource,
) {}
// 쓰기 직후 조회 → Writer 사용
async createAndGet(dto: CreateOrderDto) {
const order = await this.repo.save(dto);
return this.repo.findOne({ where: { id: order.id } }); // Writer
}
// 일반 목록 조회 → Reader 사용 가능
async list(userId: string) {
return this.readerConn.getRepository(Order).find({ where: { userId } }); // Reader Replica
}
}

모니터링:

-- Aurora Read Replica 지연 확인
SHOW SLAVE STATUS\G
-- Seconds_Behind_Master 값이 0~1 이면 정상
-- 5 이상이면 부하 증가 또는 네트워크 문제
-- CloudWatch 지표
-- AuroraReplicaLag (ms)
-- AuroraReplicaLagMaximum

예방:

  • 쓰기 직후 읽기가 필요한 API는 Writer 엔드포인트 고정
  • Read Replica는 리포트, 검색, 집계 쿼리에만 사용
  • AuroraReplicaLag CloudWatch 알람 설정 (임계값: 2000ms)

이 문서를 이해했다면 다음 주제로 이어진다:

  1. 분산 트랜잭션 (Saga 패턴): AP 시스템에서 트랜잭션 보장하는 방법 → MSA Patterns 문서 참고
  2. Consensus 알고리즘 (Raft, Paxos): CP 시스템이 내부적으로 일관성을 유지하는 방법
  3. CRDT (Conflict-free Replicated Data Types): Eventual Consistency에서 충돌 자동 해결
  4. Vector Clock / Versioning: DynamoDB Conditional Write로 충돌 감지
  5. 분산 락: Redis SETNX, DynamoDB Conditional Write로 선착순 처리

  1. CAP Theorem Explained - AlgoMaster — 도식과 실사례가 풍부한 CAP 입문서
  2. PACELC Theorem - Wikipedia — 원 제안자 Daniel Abadi의 논리 원문 포함
  3. Amazon S3 Strong Consistency (AWS 공식) — S3가 2020년 강한 일관성으로 전환한 배경 설명
  4. Consistency and Partition Tolerance: CAP vs PACELC - ByteByteGo — 시각적 다이어그램으로 비교
  5. Why Strong Consistency? - Marc Brooker (AWS) — AWS 수석 엔지니어가 쓴 Strong Consistency의 실용적 가치

시나리오 1: DynamoDB Eventual Consistency 재현

섹션 제목: “시나리오 1: DynamoDB Eventual Consistency 재현”
// 테스트: Write 직후 Eventual Consistent Read
async function demonstrateEventualConsistency() {
const userId = "user-123";
// Write: 세션 생성
await dynamoClient
.put({
TableName: "UserSessions",
Item: { userId, status: "active", updatedAt: Date.now() },
})
.promise();
// Read (Eventually Consistent - 기본값)
const result1 = await dynamoClient
.get({
TableName: "UserSessions",
Key: { userId },
// ConsistentRead: false (기본값)
})
.promise();
// 실제 발생하는 동작:
// - 90% 이상의 경우: result1.Item.status === 'active' (운 좋게 최신 노드 할당)
// - 드물게: result1.Item === undefined (구버전 노드 할당, 아직 복제 안 됨)
// - 복제 지연이 길수록 undefined 발생 빈도 증가
console.log("Eventually Consistent Read:", result1.Item);
// Read (Strongly Consistent)
const result2 = await dynamoClient
.get({
TableName: "UserSessions",
Key: { userId },
ConsistentRead: true,
})
.promise();
// 항상 보장되는 동작:
// - result2.Item.status === 'active' (최신 쓰기 반영 보장)
console.log("Strongly Consistent Read:", result2.Item);
}

실제 발생하는 동작 설명:

  • ConsistentRead: false(기본): DynamoDB가 임의의 레플리카에서 읽는다. 쓰기 직후라면 새 값이 아직 전파 안 된 레플리카에서 읽힐 수 있다.
  • ConsistentRead: true: DynamoDB가 쓰기 완료를 확인한 노드들에서 읽는다. 항상 최신 값을 반환하지만 RCU 2배 소비.

시나리오 2: Aurora Write/Read 분리 패턴

섹션 제목: “시나리오 2: Aurora Write/Read 분리 패턴”
// Aurora Multi-AZ: Writer는 항상 최신, Reader는 지연 가능
@Injectable()
class ProductService {
// 재고 차감 (CP 필요) → Writer
async decrementInventory(productId: string, qty: number) {
return this.writerDataSource.transaction(async (em) => {
const product = await em.findOne(Product, {
where: { id: productId },
lock: { mode: "pessimistic_write" }, // 비관적 락
});
if (product.stock < qty) {
throw new BadRequestException("재고 부족");
}
product.stock -= qty;
return em.save(product);
});
}
// 상품 목록 조회 (AP 허용) → Reader
async listProducts(categoryId: string) {
// Read Replica 사용 - 수 ms 지연 허용
return this.readerDataSource
.getRepository(Product)
.find({ where: { categoryId, isActive: true } });
// 실제 발생: 재고가 실시간보다 수 ms 지연될 수 있음
// 허용 가능: 상품 목록은 약간의 stale 데이터 무방
}
}

실제 발생하는 동작 설명:

  • writerDataSource: Aurora Writer 엔드포인트. 모든 쓰기와 정확성이 중요한 읽기에 사용. 항상 최신 데이터.
  • readerDataSource: Aurora Reader 엔드포인트(Read Replica). 수 ms~수 초의 복제 지연 존재. 목록 조회, 검색 등 stale 데이터가 허용되는 곳에 사용.

개념핵심 한 줄
CAP 정리분산 시스템에서 네트워크 장애(P) 시 일관성(C)과 가용성(A) 중 하나를 포기해야 한다
CP 시스템장애 시 응답 거부, 데이터는 항상 정확. ZooKeeper, etcd, Aurora
AP 시스템장애 시도 응답, 구버전 데이터 허용. Cassandra, DynamoDB, ElastiCache
PACELCCAP를 확장: 정상 상태에서도 지연(Latency)과 일관성(Consistency) 트레이드오프 존재
Eventual Consistency시간이 지나면 수렴 보장, 즉시는 아님. DynamoDB 기본값
Strong Consistency쓰기 직후 읽기 항상 최신값. Aurora Writer, DynamoDB ConsistentRead
실무 선택ACID+복잡한 쿼리 → Aurora, 높은 TPS+유연한 스키마 → DynamoDB
핵심 함정Write 후 바로 Read Replica/DynamoDB 기본 읽기 → Eventual Consistency로 인한 불일치 주의