데이터 일관성, 가용성에 대해 고민하기
CAP 정리
「가상 면접 사례로 읽는 대규모 시스템 설계」 책을 보면 CAP 정리에 대한 내용이 나온다.
CAP 정리는 데이터 일관성(consistency), 가용성(availability), 파티션 감내(partition tolerance)라는 세 가지 요구사항을 동시에 만족하는 분산 시스템을 설계하는 것은 불가능하다는 정리다.
세 가지 요구사항의 명확한 의미는 아래와 같다.
1. 일관성(consistency): 분산 시스템의 모든 노드가 항상 동일한 데이터를 본다는 것
2. 가용성(availability): 분산 시스템에 접속하는 클라이언트는 일부 노드에 장애가 발생하더라도 항상 응답을 받을 수 있어야 한다는 것
3. partition tolerance: 네트워크가 끊겨도 시스템은 계속 동작해야 한다는 것
CAP 정리에서 partition tolerance는 당연히 지켜져야 하는 부분이기 때문에(이게 안 지켜지면 분산 시스템이 아님) 결국 중요한 포인트는 일관성을 중요하게 고려할 것이냐, 가용성을 중요하게 고려할 것인가에 있다.
만약 일관성에 더 초점을 둔다면 특정 노드에 장애가 발생했을 때 다른 노드에 대한 쓰기 연산을 중단시켜야 하고, 시스템이 복구될 때 까지 오류를 반환하거나 하는 식으로 대응해야 한다.
반면, 가용성을 선택한다면 데이터의 최신성은 잠시 포기하더라도 계속 읽기 연산을 허용해야 한다.
서비스의 성격, API의 성격에 따라 어떤 요구사항을 더 중요하게 생각할 것이냐는 달라질 것으로 보이는데,
결제와 같은 데이터의 정합성, 트랜잭션의 무결성이 중요하다면 당연히 일관성이 가장 중요하겠고
데이터의 정합성보다는 실시간성과 빠른 응답, 클라이언트와의 상호작용이 중요한 서비스라면 가용성이 더 중요할 것 같다.
PACELC 정리
CAP 정리는 네트워크 장애가 발생했을 때 상황만 가정한다.
PACELC 정리는 장애 상황에서는 CAP 정리 개념을 차용하고, 실제 운영 상황에서는 L(Latency), C(Consistency) 사이에서의 선택을 다룬다.
장애 상황에서 일관성이 중요한 시스템은 당연히 중요하지만, 그 시스템이 장애가 아닌 일반 운영 상황에서도 일관성만 고집하면 응답 속도가 느려서 서비스가 제대로 안 돌아간다는 것이다.
일관성 모델
일관성에도 여러 모델이 있다. 크게 두 가지를 알아둬야 할 것 같은데,
1) 최종 일관성(Eventual Consistency)은 당장은 데이터가 달라도 시간이 지나면 결국 같아진다는 것
2) 강한 일관성(Strong Consistency)은 모든 읽기 연산은 가장 최근에 갱신된 결과를 반환한다는 것이다.
개발을 하면서
개발을 하다보면 큰 단위의 최종 일관성 + 작은 단위의 강한 일관성을 추구할 때가 많다.
트랜잭션을 적절히 묶는 것이나, Redis가 연산을 원자적으로 처리한다거나 하는 등의 내용은 강한 일관성을 추구하기 위한 노력의 일환같고
Kafka 같은 메시지 큐로 이벤트 발행하고, Transaction outbox 패턴 등을 써서 결국 최종적인 데이터의 완결성/멱등성을 보장하는 것은 최종 일관성을 유지하기 위한 노력인 것 같다.
때로는 강한 일관성을 추구하기 위한 개발이 오버 엔지니어링이 될 때가 있고
한 발 물러나 최종 일관성만 유지하면 된다고 생각했던 것이 장애의 포인트가 되는 경우도 있다.
결국 개발을 하다보면 작게 작게는 강한 일관성을 추구하고, 크게는 최종 일관성을 생각하는 경향이 있고 대부분 여기에는 어떤 식으로든 트레이드 오프가 존재한다.
운영하고 있는 시스템마다 허용 가능한 데이터 오차의 범위와 가용성이 다르고
일관성과 가용성을 달성하기 위한 개발 비용(자원, 기술 스택, 비즈니스 로직의 한계)이 전부 다르다는 것을 인지하고
나름의 논리와 고민을 가지고 개발을 하는게 최선이겠다는 생각이 든다.