CAP 이론은 분산 시스템에서 중요한 세 가지 특성인 일관성(Consistency), 가용성(Availability), 분할 허용성(Partition Tolerance)을 동시에 모두 충족할 수 없다는 점을 설명한다. 이는 분산 시스템을 설계할 때 반드시 두 가지 특성을 선택하고, 나머지 하나는 포기해야 한다는 의미이다. CAP 이론을 살펴보고, 이 세 가지 특성 간의 트레이드오프와 시스템 설계 시의 선택과 집중에 대해 알아보자.
CAP 이론이란?
CAP 이론은 2000년에 Eric Brewer가 제안한 개념으로, 분산 시스템에서 다음 세 가지 특성을 정의한다.
-
일관성(Consistency): 모든 노드가 동일한 데이터를 반환한다. 즉, 어느 노드에서나 항상 동일한 데이터를 읽을 수 있어야 한다.
-
가용성(Availability): 시스템이 언제나 응답할 수 있는 상태를 유지한다. 장애가 발생해도 중단 없이 시스템에 접근할 수 있어야 한다.
-
분할 허용성(Partition Tolerance): 네트워크 분할이 발생해도 시스템이 계속 동작할 수 있다. 분할된 상태에서도 각 노드는 독립적으로 작업을 수행한다.
CAP 이론에 따르면, 이 세 가지 특성을 동시에 만족하는 시스템은 없으며, 반드시 두 가지를 선택하고 하나는 포기해야 한다.
장애와 네트워크 분할의 차이
구분 | 장애 | 네트워크 분할 |
---|
원인 | 서버, 노드, 하드웨어 고장 또는 오류 | 네트워크 연결 문제로 인해 노드 간 통신 단절 |
영향 범위 | 장애가 발생한 특정 노드만 영향을 받음 | 여러 노드가 분할된 파티션에 속하며, 파티션 간 통신 불가능 |
처리 방법 | 다른 노드가 요청을 대신 처리하여 시스템은 가용성 유지 | 각 파티션에서 독립적으로 요청 처리, 일관성은 깨질 수 있음 |
일관성에 대한 영향 | 다른 노드가 요청을 처리하여 일관성 유지 | 파티션 간 데이터 일관성 유지 어려움, 일관성이 깨질 수 있음 |
가용성에 대한 영향 | 장애가 발생한 노드를 제외하고 나머지 노드가 가용성 유지 | 일부 파티션에서 요청을 처리할 수 없어 가용성이 제한될 수 있음 |
해결 방법 | 장애 노드를 복구하거나 대체하여 해결 | 네트워크가 복구되면 분할된 파티션 간 데이터 동기화 필요 |
CAP 이론에서의 선택: CA, CP, AP
1. CA 시스템(일관성 + 가용성)
- 장애(특히 네트워크 분할)이 발생하지 않는 상황에서 일관성과 가용성을 보장할 수 있다.
- 모든 요청에 대해 항상 최신 데이터를 제공하면서, 시스템이 언제나 응답할 수 있다.
- 네트워크 분할이 발생하는 경우, CA 시스템은 가용성보다 일관성을 우선시하기 때문에, 일부 요청에 대해 응답하지 않음으로써 일관성을 유지하려고 한다.
우리가 CA 데이터베이스 유형을 마지막에 언급한 이유는 분산 시스템에서 네트워크 분할을 피할 수 없기 때문이다. 이론적으로 CA 분산 데이터베이스에 대해 논의할 수는 있지만, 현실적으로는 그런 데이터베이스가 존재하기 어렵다. 그렇다고 해서 분산 애플리케이션에서 CA 데이터베이스를 사용할 수 없다는 의미는 아니다. PostgreSQL과 같은 여러 관계형 데이터베이스는 일관성과 가용성을 제공하며, 복제를 통해 여러 노드에서 배포할 수 있다.
https://www.ibm.com/kr-ko/topics/cap-theorem
MySQL 은 CA 시스템인가?
단일 MySQL 클러스터에서 데이터는 2단계 커밋을 사용해 노드 간에 동기적으로 복제됩니다. 네트워크 분할이 발생하면, 일부 노드가 격리될 경우에도 데이터 일관성을 유지하기 위해 조정이 이루어집니다. 만약 충분한 노드가 남아 있지 않다면 클러스터는 서비스 제공을 중단합니다. 즉, CP 시스템이다.
비동기 복제를 사용하는 클러스터는 네트워크 분할 시 일관성이 저하될 수 있지만, 각 클러스터는 독립적으로 계속 작동하며 클라이언트 요청을 처리합니다. 클러스터 간에는 결국 일관성이 맞춰질 수 있지만, 분할 중에는 데이터가 일관되지 않을 수 있습니다. 즉, AP 시스템인다.
https://planet.mysql.com/entry/?id=32245
CA 시스템에서 네트워크 장애가 발생할 때, 시스템은 어떻게 동작할까?
- 단일 노드 장애 발생: 네트워크나 서버의 문제로 인해 하나의 노드가 장애를 겪으면, 해당 노드는 더 이상 요청을 처리할 수 없다. 이때, 이 노드가 처리하고 있던 데이터와 작업은 중단된다.
- 복제된 노드 또는 페일오버 활성화: CA 시스템이 가용성을 유지하려면, 다른 복제된 노드나 페일오버 기능이 활성화된다. 장애가 발생한 노드의 역할을 대신할 수 있는 다른 노드가 요청을 처리하게 되어, 시스템의 가용성을 유지한다.
- 일관성 보장: 복제된 노드가 있으면, 장애 발생 시에도 데이터를 일관되게 유지할 수 있다. 즉, 요청은 새로운 노드에서 처리되며, 데이터는 항상 최신 상태로 유지된다.
분산 시스템에서 일관성과 가용성을 동시에 보장할 수 없다
- 상황 설정: 분산 시스템에서 데이터를 관리하는 세 개의 노드(A, B, C)가 있다고 가정한다. 네트워크 분할이 발생하여 A와 B는 서로 통신할 수 있지만, C는 이들과 통신할 수 없는 상황이 발생한다.
- 선택지:
- 가용성 선택: C 노드는 요청을 받아들이고 데이터를 업데이트할 수 있지만, A와 B는 이 데이터를 알지 못한다. 즉, 가용성을 선택했지만 일관성이 깨진다.
- 일관성 선택: C 노드는 요청을 거부하고, A와 B와의 동기화가 이루어질 때까지 데이터를 업데이트하지 않는다. 즉, 일관성을 유지하지만 가용성을 포기하게 된다.
- 결론: 분산 시스템에서 네트워크 분할이 발생하면, 가용성(Availability) 또는 일관성(Consistency) 중 하나만 선택할 수 있으며, 두 가지를 동시에 보장하는 것은 불가능한다.
결론적으로, 네트워크 분할 상황에서 일관성과 가용성 둘 다 보장하는 시스템은 존재하지 않으며, 둘 중 하나를 선택하는 것이 불가피하다.
2. CP 시스템(일관성 + 분할 허용성)
- 일관성과 분할 허용성을 보장하지만, 가용성은 포기한다.
- 네트워크 분할이 발생하면 일부 노드가 요청을 처리할 수 없도록 막고, 일관성을 유지하기 위해 시스템이 부분적으로 중단된다.
- 예시: MongoDB, HBase 같은 시스템이 이에 해당한다.
CP 시스템(일관성 + 분할 허용성)에서 장애가 발생하면 어떻게 동작할까?
- 네트워크 분할 또는 노드 장애 발생: CP 시스템에서는 네트워크 분할이나 노드 장애가 발생하더라도 시스템은 일관성과 분할 허용성을 유지하는 데 초점을 맞춘다. 즉, 시스템은 통신이 불가능한 파티션 간의 데이터를 즉시 동기화하지 않더라도, 각 파티션 내에서 일관성을 보장한다.
- 가용성 포기: 네트워크 분할이 발생하면 시스템은 일부 노드에 대한 요청을 차단하거나 중단할 수 있다. 시스템이 일관성을 유지하려고 하기 때문에, 네트워크 분할 상황에서는 새로운 쓰기 요청이나 일부 읽기 요청을 거부할 수 있다. 즉, 가용성을 포기함으로써 데이터의 일관성을 유지한다.
- 일관성 유지 방법: CP 시스템은 특정 파티션에서 일관성을 유지하기 위해 일부 노드가 처리할 수 없는 요청에 대해 “응답 불가” 상태를 유지하며, 데이터를 불완전하거나 충돌된 상태로 만들지 않는다. 예를 들어, 네트워크가 복구되기 전까지는 분할된 노드 간에 데이터를 동기화하지 않고, 일관성을 깨뜨리지 않도록 조치한다.
- 네트워크 복구 시: 네트워크가 복구되면, 시스템은 분할된 노드들 간의 데이터를 다시 동기화하여 완전한 일관성을 유지하고, 가용성이 회복된다. 그동안 중단된 작업은 일관된 상태에서 처리될 수 있다.
3. AP 시스템(가용성 + 분할 허용성)
- 가용성과 분할 허용성을 보장하지만, 일관성은 포기한다.
- 네트워크 분할이 발생해도 시스템은 계속 작동하며 요청을 처리할 수 있지만, 각 파티션에서 반환하는 데이터는 다를 수 있다. 즉, 일관성이 깨질 수 있다.
- 예시: Cassandra, DynamoDB 같은 NoSQL 데이터베이스 시스템이 이에 해당한다.
AP 시스템에서 네트워크 분할이 발생하면 어떻게 동작할까?
- 네트워크 분할 또는 노드 장애 발생: AP 시스템은 가용성과 분할 허용성을 유지하는 데 초점을 맞춘다. 네트워크 분할이 발생하면, 시스템은 각 파티션이 독립적으로 작동하며, 사용자 요청에 응답한다. 가용성을 유지하기 위해 분할된 상태에서도 모든 노드는 계속해서 요청을 처리할 수 있다.
- 일관성 포기: AP 시스템은 일관성을 포기하고, 네트워크가 분할된 상태에서 각 파티션에서 독립적으로 작업을 진행한다. 이로 인해 데이터의 일관성이 깨질 수 있으며, 각 파티션에서 서로 다른 데이터를 반환할 가능성이 있다. 예를 들어, 하나의 파티션에서 데이터가 업데이트되더라도 다른 파티션에서는 이를 알지 못해 서로 다른 데이터를 처리할 수 있다.
- 가용성 유지 방법: AP 시스템은 가용성을 우선시하기 때문에, 네트워크 분할 상황에서도 모든 노드는 계속해서 읽기 및 쓰기 요청을 처리한다. 이러한 방식으로 시스템의 가용성을 유지하며, 시스템이 중단 없이 계속 작동하도록 한다. 이는 특히 사용자 경험이 중요한 서비스에서 매우 유용할 수 있다.
- 네트워크 복구 후 동작: 네트워크 분할이 해결되면, AP 시스템은 각 파티션 간의 데이터를 동기화하여 일관성을 회복한다. 하지만 이 과정에서 충돌이 발생할 수 있으며, 이를 해결하기 위해 시스템은 최신 데이터로 덮어쓰거나 애플리케이션 레벨에서 충돌 해결 로직을 사용해야 한다. DynamoDB 같은 시스템은 이를 위해 벡터 클락과 같은 기술을 사용하여 데이터를 병합하거나 최신 쓰기 우선 정책을 적용할 수 있다.
AP 시스템에서 네트워크 분할이 해결된 후 데이터 동기화는 어떻게 이루어질까?
- 벡터 클락(Vector Clocks): 벡터 클락은 각 노드에서 데이터를 변경할 때마다 각 노드의 변경 이력을 추적하는 타임스탬프를 기록한다. 네트워크가 복구되면, 각 노드는 벡터 클락을 비교하여 충돌을 감지하고 동시성 문제를 해결한다. 벡터 클락은 각 노드의 데이터 변경 순서를 파악하여 병합 가능한지 확인하며, 경우에 따라 충돌을 감지해 애플리케이션이 이를 처리하도록 도울 수 있다. 이는 단순히 최신 데이터를 덮어쓰는 방식이 아니라, 충돌을 세밀하게 관리하는 방식이다.
- 최신 쓰기 우선(Last-Write-Wins): 이 방법은 네트워크 분할 중 발생한 충돌을 해결할 때 가장 최근에 작성된 데이터를 우선적으로 적용하는 방식이다. 데이터가 동기화될 때 타임스탬프를 기준으로 최신 데이터가 덮어쓰여 일관성이 회복된다.
- 쿼럼(Quorum): 각 파티션의 노드들 중 일정 수 이상의 노드(쿼럼)에 대한 쓰기 작업이 성공적으로 완료된 데이터를 기준으로 동기화를 진행할 수 있다.
- 멀티 버전 동시성 제어(MVCC): 이 방법에서는 각 데이터의 버전을 관리하며, 네트워크 분할 동안 발생한 모든 변경사항을 기록한다. 분할이 해결되면 각 버전을 비교하여 가장 적합한 버전으로 데이터를 동기화하거나 충돌을 해결하는 방법을 선택한다.
- 사용자 정의 충돌 해결 로직: 애플리케이션 레벨에서 충돌을 처리할 수 있는 로직을 정의하는 방식이다. 예를 들어, 특정 비즈니스 규칙에 따라 데이터를 병합하거나 우선 순위를 지정하여 충돌을 해결할 수 있다.
DynamoDB에서 벡터 클락을 사용하는 방법
1. D1 ([Sx, 1]): 첫 번째 데이터 작성은 노드 Sx에서 이루어졌으며, 이때 벡터 클락은 [Sx, 1]로 기록된다. 이는 노드 Sx에서 첫 번째 버전임을 의미한다.
2. D2 ([Sx, 2]): 두 번째 작성 또한 노드 Sx에서 발생하며, 벡터 클락은 [Sx, 2]로 갱신된다. 이는 Sx에서 두 번째 버전임을 나타낸다.
3. D3 ([Sx, 2], [Sy, 1]): 그 후, 노드 Sy에서 데이터가 업데이트된다. Sy는 벡터 클락에서 자신의 변경 사항을 기록하며, 결과적으로 벡터 클락은 [Sx, 2], [Sy, 1]로 변한다. 이는 Sx의 두 번째 버전 이후 Sy에서 첫 번째 변경이 이루어졌음을 의미한다.
4. D4 ([Sx, 2], [Sz, 1]): 동시에, 노드 Sz에서도 데이터 변경이 발생하며, 벡터 클락에 Sz의 첫 번째 변경 사항이 기록된다. 따라서 벡터 클락은 [Sx, 2], [Sz, 1]로 변한다.
5. D5 ([Sx, 3], [Sy, 1], [Sz, 1]): 네트워크가 복구된 후, 노드 Sx는 두 개의 다른 데이터 버전(D3과 D4)을 받게 된다. 이때, Sx는 두 버전을 병합하고, 새로운 버전으로 [Sx, 3], [Sy, 1], [Sz, 1]을 기록한다. 이는 Sx에서 세 번째 변경이 이루어졌고, Sy와 Sz에서도 각각 한 번씩 변경되었음을 나타낸다.
DynamoDB에서 충돌이 발생했을 때, 각 버전이 서로 더 최신이라고 할 수 없는 경우, 시스템은 충돌한 두 버전을 클라이언트에게 전달한다. 이후 클라이언트는 해당 버전을 기반으로 충돌을 해결하는 업데이트를 진행할 수 있으며, 이 업데이트는 시스템에 의해 최종적으로 병합된다. 클라이언트는 도메인 특화 지식을 활용하여 어느 버전을 유지할지 결정하거나, 두 버전의 일부를 조건부로 병합할 수 있다.
CAP 이론이 주는 교훈
CAP 이론은 분산 시스템 설계에서 중요한 교훈을 준다. 일관성, 가용성, 분할 허용성 중 두 가지를 선택하고 하나를 포기하는 트레이드오프는 시스템의 목적에 따라 결정된다. 실시간 응답이 중요한 시스템은 가용성과 분할 허용성을 우선시할 수 있고, 금융 시스템처럼 데이터의 일관성이 중요한 경우는 일관성과 분할 허용성을 선택할 수 있다.
결론적으로, CAP 이론은 분산 시스템 설계에서 목표와 우선순위를 설정하는 데 중요한 기준이 된다. 네트워크가 분할될 때 어떤 특성을 우선할지 미리 결정하는 것이 시스템의 성능과 안정성에 큰 영향을 미친다.
References