에듀테크 프로젝트 대시보드
CAP 정리 (CAP Theorem)
여러 대의 서버가 데이터를 복제하며 협력하는 분산 시스템에서, 네트워크가 끊기는 순간 시스템은 "옛날 값이라도 응답할까(가용성)" 대 "틀린 값을 줄 바엔 에러를 낼까(일관성)" 중 하나를 반드시 포기해야 한다.
노드 3개가 값 v를 복제한다. 왼쪽 클라이언트가 리더(N1)에 쓰고, 오른쪽 클라이언트가 소수파(N3)에서 읽는다. "네트워크 분단"을 켜면 링크가 끊긴다. 그 상태에서 쓰기·읽기를 해 보고, CP / AP 모드에 따라 결과가 어떻게 갈리는지 관찰하자.
노드 G1, G2가 값을 복제한다. 둘 사이 네트워크가 끊겼다(P는 선택이 아니라 현실이다 — 케이블은 언젠가 끊긴다). 이제 클라이언트가 G1에 v=5를 쓴다. G1은 G2에게 전달할 수 없다. 곧이어 다른 클라이언트가 G2에서 읽는다.
v=0을 준다 → 일관성 깨짐.분단이 발생한 그 순간, 어느 쪽도 포기하지 않는 제3의 선택지는 존재하지 않는다. 그래서 CAP은 실무에서 "분단이 생겼을 때 CP냐 AP냐"의 문제로 읽는다. 분단이 없을 땐 C와 A를 모두 누릴 수 있다.
| 선택 | 분단 시 동작 | 대표 예시 | 어울리는 곳 |
|---|---|---|---|
| CP | 소수파 노드는 읽기·쓰기를 거부. 과반수(quorum)만 서비스. | ZooKeeper, etcd, HBase, 은행 원장, Raft 기반 저장소 | 잔액·재고·예약 — 틀린 값이 치명적인 곳 |
| AP | 모든 노드가 계속 응답. 값이 갈라졌다가 나중에 수렴(eventual consistency). | Cassandra, DynamoDB(기본), 장바구니, DNS, CDN | SNS 좋아요 수, 게시글 조회수 — 잠깐 어긋나도 되는 곳 |
CAP은 "분단이 있을 때"만 말한다. PACELC는 여기에 한 줄을 더한다: Partition이면 A 또는 C, Else(정상일 때)엔 Latency(지연) 또는 Consistency.
즉 일관성의 대가는 분단 때는 가용성, 평소엔 속도다. 관련: 트랜잭션과 ACID, 일관된 해싱.
노드 N개 중 쓰기에 W개, 읽기에 R개의 확인을 요구한다. W + R > N이면 읽기 집합과 쓰기 집합이 반드시 겹쳐 최신 값을 본다(CP 성향). 조건을 깨면 더 잘 뚫리지만 옛 값을 읽을 수 있다(AP 성향).
# N=3 복제. W=2, R=2 → W+R=4 > 3 → 강한 일관성 def write(key, value, nodes, W): acks = 0 for node in nodes: if node.try_put(key, value, version=now()): # 도달 가능한 노드만 acks += 1 if acks >= W: return "OK" # W개 확인 → 성공 raise Unavailable("정족수 미달 — 분단 소수파일 가능성") def read(key, nodes, R): replies = [n.get(key) for n in reachable(nodes)][:R] if len(replies) < R: raise Unavailable("정족수 미달") # CP: 거부 return max(replies, key=lambda r: r.version) # 가장 최신 버전 채택
W=3을 요구하는 쓰기는 3노드 쪽에서만 성공한다. 2노드 쪽은 스스로 "나는 소수파"임을 알고 쓰기를 거부한다. 이렇게 한쪽만 진행시켜 데이터가 두 갈래로 갈라지는 split-brain을 막는다.