CAP 이론은 주로 분산 데이터베이스와 같은 분산 시스템의 설계 및 구현에 사용되는 개념이다. (분산 데이터베이스는 방대한 데이터를 다루기에 유용한 시스템이다. 분산 데이터 베이스는 수평 확장할 수 있기 때문에 트래픽이 증가하더라도 낮은 지연 시간을 유지할 수 있고 일부 노드 장애에 적절히 대응할 수 있다.)
CAP 이론은 분산 시스템에서 동시에 충족할 수 있는 세 가지 속성을 명확하게 정의함으로써, 시스템 설계자가 이 세 가지 속성 사이의 trade-off를 이해하고 특정 어플리케이션의 요구 사항에 가장 잘 맞는 DBMS를 선택하고 시스템을 설계하는 데에 도움을 준다.

우선 CAP이론이 무엇인지 이해하기 위해서는 C,A,P가 각각 무엇을 의미하는지를 이해해야한다.
모든 노드가 같은 시간에 같은 데이터를 보게 된다. 즉, 읽기 작업이 항상 가장 최신의 쓰기 작업을 반영하며 이는 모든 노드에 일관적으로 적용된다.
즉, 내가 업데이트한 정보가 노드A의 DBMS에 반영이 되었더라도, 이는 변경사항은 바로 노드B에 있는 DB에도 반영이 되어야한다. (모든 복제본에 변경사항이 반영되어야함)
그러나 시스템이 모든 인스턴스에 변경 내용을 즉각 반영하는 것은 사실상 불가능에 가깝다. 따라서 일관성의 목표는 데이터의 동기화가 충분히 빨라서 사용상의 문제가 없도록 하는 것이다.
일관성은 금융이나 개인정보 같이 모든 사용자가 일관성 있는 데이터를 조회해야할 때 중요하다. 예를 들어 금융 앱을 이용할 때 PC나 스마트폰, 태블릿 또는 어디에서 보든지 같은 잔고를 확인할 수 있어야 한다.
예를 들어, 이사를 해서 집주소가 변경되었고 이를 통신사에 알려야하는 상황이라고 하자. 전화를 해서 상담원A에게 새로운 집주소를 알려주고 전화를 끊었다. 그러고 몇초 뒤, 집 호수를 잘못 말했다는 것을 깨닫고 회사에 다시 전화를 걸었다. 이 때는 상담원B가 전화를 받았는데, 상담원B도 내가 방금 변경한 내역을 알고 있다. 상담원A와 B가 같은 정보를 공유하고 있다는 것을 일관성이라고 한다.
모든 요청은 성공 혹은 실패 여부와 무관하게 응답을 받는다. 즉, 모든 요청은 유효한 데이터를 읽거나 쓸 수 있어야한다.
클러스터의 일부 노드에서 장애가 발생하더라도(네트워크 장애같은) read, write 동작은 항상 성공적으로 리턴되어야 한다는 것이다. 즉 시스템이 중단되는 일 없이 언제든지 사용 가능한 상태여야한다.
참고: 스마트폰 은행 앱으로 본 잔고와 PC에서 본 통장 잔고가 다르다고 하더라도(즉, 일관성은 지켜지지 않더라도) 언제든지 잔고를 확인할수 있다면 이는 가용성이 지켜진 케이스이다.
예를 들면, 통신사 고객센터는 업무 시간이라면 언제든 연락 가능하고, 고객은 필요한 정보를 고객센터를 통해 언제든지 알아낼 수 있다는 점을 가용성이라고 할 수 있다.
네트워크 분할이 발생하더라도 시스템은 계속 작동해야한다. 네트워크 분할이란 일부 노드가 다른 노드와 통신하지 못하게 하는 네트워크 오류를 의미한다.
한 노드가 다른 노드와 통신을 할 수 없을 때, 다른 복제 노드가 사용자 요청에 응답할 수 있어야한다. 이는 데이터의 복제본을 여러 다른 노드에 저장하여 처리하는 것을 의미한다. 따라서 분할이 생기더라도 복제본으로부터 데이터를 조회할 수 있다. 분할 허용성은 분산 데이터베이스 시스템에서 필수적이다.
*참고:
예를 들어 요금제를 변경하기 위해서 통신사에 전화를 한다고 하자. 고객센터에 전화를 걸어서 변경하고 싶은 요금제를 전달하였다. 그런데 고객센터에서는 센터 내 전산 문제 때문에 본사와 통신 할 수 없다고 한다. 하지만 고객센터는 정상적으로 운영되며 통신이 복구될 때까지 잠시 기다리거나, 변경 사항을 적용하되 다른 상담원은 잠시동안 예전 정보를 알고 있을 수도 있다고 한다. 이를 분할 허용성이라고 한다.
CAP 이론이란 분산 데이터베이스 시스템에서는 CAP 3가지가 다 지켜지지 않으며 셋 중 하나는 희생해야 한다는 것을 의미한다.
분산 데이터베이스 시스템은 반드시 네트워크 장애나 여러 이유들로 인해 장애가 발생할 수밖에 없다. 그러므로 분산 데이터베이스 시스템은 반드시 분할 허용성을 가지고 있어야 하며 일관성과 가용성 중 하나를 선택해야한다. (다른 말로 하면, P는 네트워크 장애가 있을 수 있느냐를 인정하느냐 마느냐의 문제이고 이는 인정할 수밖에 없는 문제이므로 즉 네트워크 문제는 반드시 발생하므로 처음부터 선택되어 있는 것이다. 결국 CAP 이론이 내포하고 있는 의미는 분산시스템에서 네트워크 장애 상황일 때 일관성과 가용성 중 많아도 하나만 선택할 수 있다는 것이다.)
예를 들어 두 노드로 이루어진 분산 시스템에서 분할이 생겼을 때 데이터의 일관성을 보장하는 것은 불가능하다. 그러므로 분할이 생겼더라도 정상적으로 요청을 처리해서 가용성을 높이거나(AP), 잠시 요청 처리를 중단하고 네트워크 분할이 해결될 때까지 기다려서 가용성을 희생하고 일관성을 지키는 방법(CP) 중 하나를 선택하게 된다.
따라서 NoSQL DB는 CP 또는 AP 시스템을 가지고 있다. CA 시스템은 일반적으로 하나의 노드에서 동작하는 DBMS를 의미한다.
mysql은 RDBMS로, 일반적으로 단일 노드에서 작동하므로 기본적으로 CA 시스템이다. 그러나 분산 시스템으로 구성할 수도 있으며 이 경우 CP 시스템으로 동작한다.
일관성: Mysql은 ACID 트랜잭션을 지원하므로, 이를 통해 데이터 일관성을 보장한다. 즉, 모든 트랜잭션은 데이터베이스에 일관된 상태를 남긴다. 또한, 모든 읽기 작업은 가장 최신의 쓰기 작업을 반영한다. 하지만 Mysql을 분산 시스템으로 구성하는 경우 일관성을 보장하는 것은 더 복잡해질 수 있다. 예를 들어 복제(replication)을 사용할 때, 마스터 노드에서 슬레이브 노드로의 변경 사항 복제에는 약간의 지연이 있을 수 있어, 이로 인해 일시적인 불일치가 발생할 수 있다.
가용성: Mysql은 일반적으로 높은 가용성을 제공하도록 설계되었다. 예를 들어, 복제 기능을 사용하면 여러 노드에 데이터를 복제하여 단일 노드 장애가 전체 시스템의 가용성을 저하시키지 않도록 할 수 있다. 하지만 이러한 방식은 데이터 일관성 유지에 더 많은 노력이 필요할 수 있다.
분할 허용성: Mysql은 네트워크 분할에 대한 처리가 제한적이다. 일반적인 Mysql 구성에서 네트워크 분할이 발생하면, 분할된 영역에서 작동하는 노드는 다른 노드와의 동기화를 잃게 되므로 일관성 문제가 발생할 수 있다. 따라서 Mysql은 기본적으로는 CAP이 CP 모델을 따르지 않는다.
이렇기 때문에 일반적인 Mysql 설정에서는 CA 모델을 따르게 된다.
이런 문제를 극복하기 위해 분산 Mysql 설정(cluster 설정)이 설계되었다.
이러한 설정에서는 네트워크 분할시에도 일관성을 유지하는 방법으로 설계되어 CAP 중 CP 시스템을 따르게 된다.

MongoDB는 데이터를 하나 혹은 여러 개의 프라이머리 노드에 이진 JSON 형태로 저장한다. 각 프라이머리 노드는 로그를 이용해 비동기적으로 업데이트 되는 복제본을 가진 여러 개의 세컨더리 노드를 가진다. 각 노드는 다른 모든 노드와 통신하여 서로의 상태를 확인한다. 만약 몇 초 동안 응답을 받지 못하면 해당 노드는 접근 불가능한 상태로 지정된다.
일관성: MongoDB는 기본적으로 "최종 일관성" 모델을 따르게 된다. 이는 데이터 복제가 일어나는 분산 시스템에서 모든 복제본이 즉시 동기화 되지 않을 수 있음을 의미한다. 따라서 일시적으로 일부 클라이언트가 다른 클라이언트와 다른 데이터를 보는 상황이 발생할 수 있다. 하지만 시간이 지나면 모든 변경 사항이 모든 복제본에 동기화되므로, 시스템은 최종적으로 일관성을 가지게 된다.
가용성: 몽고디비는 클러스터 내에 여러 복제본을 유지함으로써 한 노드가 실패하더라도 서비스는 계속될 수 있다. 즉 프라이머리 노드가 실패하면 세컨더리 노드 중 하나가 프라이머리 노드 역할을 대신한다. 그런데 프라이머리 노드가 중단 되었다면 세컨더리 노드 중 하나가 프라이머리 노드로 승격 되어야 한다. 새로운 프라이머리 노드가 선출되는 동안 시스템은 모든 쓰기 작업은 잠시 사용 불가능(가용성 지원X)한 상태가 된다. 따라서 MongoDB는 CP 시스템으로 분류된다.
분할 허용성: MongoDB는 네트워크 분할 상황이 발생하면 복사본의 프라이머리 노드가 다수의 컨더리 노드들과 연결이 끊기게 될 수 있다. 이런 경우 연결이 끊긴 세컨더리 노드들은 주 노드를 선출하여 서비스를 계속하게 된다. (위에서 설명했듯이 이로 인해 가용성을 포기하게 되었다.)
CAP 이론에 맞게 완벽하게 CP, AP인 시스템은 없고, 대부분 CP와 AP 중간쯤 존재한다고 한다.
(예시로, 이 블로그글을 작성하려고 조사를 하는 과정에서 몽고디비가 일시적으로 일관되지 않은 데이터를 볼 수 있고 복제본 노드를 이용해 가용성 지킨다는 점에서 이를 AP 시스템으로 설명한 글도 보았는데 이도 틀린 말은 아닌 것 같다. 하지만 CP로 생각하는 사람이 더 많은 것 같아 CP로 소개하였다. 몽고디비도 CP와 AP 사이에 걸쳐있는 시스템이라고 보는 게 더 맞을 것 같다.)
위에서 언급했다 싶이, CAP가 내포한 의미는 네트워크 장애는 발생할 수밖에 없는 문제이기 때문에 P는 반드시 지원되어야 하고 장애가 발생한 상황에서 C, A 중 하나는 포기하고 하나만 지원할 수 있다는 것이라고 하였다. 그렇기에 이 이론은 정상 상황일 때의 선택에 대해 서술하지 못한다. 그래서 정상상황일 때와 장애상황일 때를 나누어 설명하는 이론이 있는데 바로 PACELC이다. 이 이론에 대한 설명은 여기서 확인할 수 있다.
프로젝트를 하다보면 분산 데이터베이스를 쓰게 될 것이고, 그 때 어떤 DB를 선택할지 고려할 때 CAP를 고려하게 될 것 같다.
우선 돈과 관련된 커머스 분야에서는 AP보다는 CP가 잘 지원되는 DB를 쓰는 것이 좋을 것 같다는 생각을 하였다.
그럼 AP를 지원하는 DB는 언제 쓰는게 좋은걸까..
동기화가 그렇게 중요하지 않고 빠른 응답을 요구하는 서비스가 뭐가 있으려나..?
게시판에 글 같은거 올릴 때?? 남이 올린 글이 A 노드에 저장됐고 내가 올린 글이 B 노드에 저장됐는데 A, B 사이에 네트워크 분할이 생겼다면 일관성을 위해 굳이 기다릴 필요는 없을 것 같다. 그냥 사용자한텐 자신의 글이 빨리 올라가는 걸 보여주고 동기화는 나중에 해도 되지 않을까? 생각해보았다.
이 글을 보니, 내가 생각한 내용이 대충 맞다는 생각이 들었다. CP는 쇼핑몰 같은 곳에(재고 상황, 잔액 등이 동기화 돼야함), AP는 게시판에 더 적절하다고 한다. 게시판은 남의 글이 반드시 보이게 하는 동기화보다는 서버가 안죽었다는 느낌을 주는 것이 더 중요하다고 한다.