일관성과 합의
- 9.1 일관성 보장
- 9.2 선형성
- 9.3 순서화 보장
- 9.4 분산 트랜잭션과 합의
분산 시스템의 혼돈 속에서 질서를 세우는 방법은 결국 합의 — 여러 노드가 하나에 동의하는 것으로 귀결돼. 리더 선출, 원자적 커밋, 멤버십 — 전부 합의 문제야.
대부분의 복제 DB가 제공하는 최종적 일관성은 약한 보장이야. "결국" 모든 복제 서버가 같은 값을 가지게 된다는 건데, 그 "결국"이 언제인지 모르고 그 전까지는 뭐든 읽힐 수 있거든. 더 강한 보장이 필요하면 선형성이 있어 — 시스템이 데이터 복사본을 하나만 가진 것처럼 보이고, 모든 연산이 원자적인 것처럼 보이는 거야. 리더 선출, 유일성 제약 같은 곳에서 필요하지. 하지만 CAP 정리에 의해 네트워크 파티션이 발생하면 일관성과 가용성 중 하나를 택해야 하고, 파티션이 없을 때도 많은 시스템이 성능 때문에 선형성을 포기해. 선형성은 느려 — 네트워크 지연에 비례하는 응답 시간을 가진다는 게 증명된 사실이거든.
그래서 인과적 일관성이 중요해져. 인과적으로 관련된 연산만 순서를 보장하고 무관한 건 병렬 처리 가능한, 네트워크 지연 없이 제공할 수 있는 가장 강한 일관성 모델이야. 램포트 타임스탬프로 인과적 순서와 일치하는 전체 순서를 만들 수 있지만, 모든 연산을 수집한 후에야 비교 가능해서 실시간 결정에는 부족해. 전체 순서 브로드캐스트 — 모든 노드에 같은 순서로 메시지를 전달하는 프로토콜 — 가 이 갭을 메워주고, 이건 선형성과 등가 변환이 가능해.
실전에서의 합의 구현을 보면, 2단계 커밋(2PC) 은 여러 노드에 걸친 트랜잭션을 원자적으로 만들어주지만 코디네이터 장애에 취약해 — 참여자가 "예"라고 답한 후 코디네이터가 죽으면 의심 상태로 잠금이 걸린 채 기다려야 하거든. 진짜 합의 알고리즘인 Paxos, Raft, Zab은 일치, 무결성, 유효성, 종결을 보장하면서 이 문제를 해결해. 대부분 내부적으로 리더를 선출하고 리더가 결정을 제안하는 방식으로 동작하지. 직접 합의 알고리즘을 구현하는 건 매우 어렵기 때문에, 주키퍼나 etcd 같은 코디네이션 서비스에 합의를 아웃소싱하는 게 현실적인 선택이야.
정리
9장 읽고 기억할 거:
- 선형성은 가장 강한 일관성이지만 비용이 크다. 네트워크 지연에 비례하는 성능 저하. 인과적 일관성이 성능 손해 없이 달성 가능한 가장 강한 모델이다
- 합의는 분산 시스템의 근본 문제다. 리더 선출, 원자적 커밋 — 결국 "여러 노드가 하나에 동의하기"로 귀결된다. 2PC는 코디네이터 장애에 취약하고, Raft나 Paxos가 이를 해결한다
- 주키퍼 같은 코디네이션 서비스는 합의의 아웃소싱이다. 직접 합의 알고리즘을 구현하는 건 매우 어렵고, 대부분 주키퍼나 etcd로 위임한다