
1. CAP 정리
CAP 정리는 분산 시스템에서 일관성, 가용성, 파티션 내성을 동시에 완벽히 만족할 수 없다는 원칙입니다.
일관성은 모든 사용자가 같은 데이터를 보는 것입니다. 가용성은 요청하면 항상 응답하는 것입니다. 파티션 내성은 네트워크 장애가 발생해도 시스템이 계속 동작하는 능력입니다.
예를 들어 전국 여러 서버에 회원 정보를 저장하는 서비스가 있다고 하겠습니다. 서울 서버와 부산 서버 간 네트워크가 끊겼을 때, 두 서버가 서로 다른 회원 정보를 가지고 있을 수 있습니다. 이때 시스템은 “정확한 데이터만 보여줄 것인가”, 아니면 “조금 늦게 맞춰지더라도 서비스는 계속 열어둘 것인가”를 선택해야 합니다.
사례로는 Cassandra, DynamoDB 같은 시스템이 있습니다. 이들은 강한 일관성보다 높은 가용성과 확장성을 우선하는 경우가 많습니다.
2. PACELC 모델
PACELC는 CAP 정리를 확장한 개념입니다. 장애가 있을 때는 일관성 vs 가용성을 선택하고, 장애가 없을 때도 지연시간 vs 일관성을 선택해야 한다는 뜻입니다.
즉, 시스템은 장애 상황에서만 선택을 하는 것이 아닙니다. 정상 상황에서도 빠른 응답을 위해 데이터 정확성을 조금 늦게 맞출 것인지, 아니면 정확성을 위해 응답 속도를 희생할 것인지 결정해야 합니다.
예를 들어 글로벌 쇼핑몰에서 한국 사용자가 미국 서버의 재고 데이터를 조회하면 시간이 오래 걸릴 수 있습니다. 그래서 가까운 캐시 서버에 저장된 재고 정보를 보여주면 빠르지만, 실제 재고와 약간 차이가 날 수 있습니다.
3. 대략적 용량 산정
Back-of-the-Envelope Estimation은 시스템을 만들기 전에 대략적인 트래픽, 저장공간, 서버 수, 네트워크 대역폭을 빠르게 계산하는 방법입니다.
예를 들어 하루 방문자 100만 명, 사용자당 평균 요청 20회라면 하루 요청 수는 2,000만 건입니다. 초당 평균 요청 수는 약 231건이고, 피크 시간에는 10배로 잡아 초당 2,300건 이상을 처리해야 할 수 있습니다.
이 계산을 통해 서버 1대가 초당 500건을 안정적으로 처리한다면 최소 5대 이상이 필요하다는 판단을 할 수 있습니다.
4. 로드 밸런싱
로드 밸런싱은 여러 서버에 트래픽을 분산하여 특정 서버 하나가 과부하되지 않도록 하는 방식입니다.
예를 들어 사용자 10만 명이 동시에 로그인하면 하나의 웹서버만으로는 감당하기 어렵습니다. 이때 ALB, Nginx, HAProxy 같은 로드밸런서가 요청을 여러 서버로 나눠 보냅니다.
대표 방식은 라운드로빈, 최소 연결 수, IP 해시 방식입니다. AWS에서는 Application Load Balancer를 사용해 웹 요청을 여러 EC2 인스턴스로 분산할 수 있습니다.
5. 캐싱 전략
캐싱은 자주 사용하는 데이터를 빠른 저장소에 보관해 응답 속도를 높이는 방법입니다.
예를 들어 로그인한 사용자의 세션 정보, 상품 목록, 게시판 인기글, 인증서 검색 결과는 매번 DB에서 조회하지 않고 Redis나 Memcached에 저장해둘 수 있습니다.
사례로 인증서 조회 시스템에서 “인증번호 검색 결과”를 Redis에 5분간 저장하면 DB 부하를 크게 줄일 수 있습니다. 단, 캐시는 오래된 데이터를 보여줄 위험이 있으므로 만료시간과 갱신 정책이 중요합니다.
6. 데이터베이스 샤딩
샤딩은 큰 데이터를 여러 데이터베이스에 나누어 저장하는 방식입니다.
예를 들어 회원이 1억 명인 서비스에서 모든 회원 데이터를 하나의 DB에 넣으면 조회와 쓰기가 느려집니다. 이때 회원 ID 기준으로 1번 DB에는 11,000만 명, 2번 DB에는 1,000만2,000만 명을 저장하는 식으로 나눌 수 있습니다.
쇼핑몰에서는 주문 데이터를 지역별, 고객 ID별, 날짜별로 샤딩할 수 있습니다. 단점은 여러 샤드에 걸친 검색이나 통계 처리가 어려워진다는 점입니다.
7. 복제 모델
Replication은 데이터를 여러 서버에 복사해 장애에 대비하는 방식입니다.
예를 들어 메인 DB가 장애가 나도 복제 DB가 있으면 서비스를 계속 운영할 수 있습니다. 읽기 요청은 복제 DB에서 처리하고, 쓰기 요청은 주 DB에서 처리하는 구조도 가능합니다.
대표 구조는 Master-Slave, Leader-Follower, Multi-Leader 방식입니다. MySQL에서는 Primary-Replica 구조로 읽기 부하를 분산할 수 있습니다.
8. 서킷 브레이커 패턴
서킷 브레이커는 장애가 발생한 외부 서비스 호출을 계속 시도하지 않고 일정 시간 차단하는 패턴입니다.
예를 들어 결제 API가 장애 상태인데 주문 서비스가 계속 결제 요청을 보내면 전체 시스템이 느려질 수 있습니다. 이때 서킷 브레이커가 “결제 시스템 장애 상태”라고 판단하고 잠시 호출을 중단합니다.
마이크로서비스 환경에서 매우 중요합니다. 하나의 서비스 장애가 전체 장애로 확산되는 것을 막아줍니다.
9. 재시도 패턴
Retry Pattern은 실패한 요청을 다시 시도하는 방식입니다.
예를 들어 네트워크 순간 오류로 이메일 발송이 실패했을 때 1초 후, 2초 후, 4초 후 다시 시도할 수 있습니다. 이를 지수 백오프라고 합니다.
주의할 점은 무조건 재시도하면 오히려 시스템을 더 망가뜨릴 수 있다는 것입니다. 결제 요청을 잘못 재시도하면 중복 결제가 발생할 수 있으므로 멱등성과 함께 설계해야 합니다.
10. 레이트 리미팅
Rate Limiting은 사용자의 요청 횟수를 제한하는 방식입니다.
예를 들어 로그인 API에 대해 한 IP에서 1분에 10회 이상 요청하지 못하게 하면 무차별 대입 공격을 줄일 수 있습니다. 또한 무료 API 사용자는 분당 100회, 유료 사용자는 분당 1,000회로 제한할 수도 있습니다.
보안 측면에서는 DDoS, 크롤링, 스팸 요청 방어에 효과적입니다.
11. 이벤트 기반 설계
Event-Driven Architecture는 서비스 간 직접 호출을 줄이고 이벤트로 통신하는 방식입니다.
예를 들어 주문이 완료되면 주문 서비스가 “OrderCompleted” 이벤트를 발행합니다. 그러면 재고 서비스, 배송 서비스, 알림 서비스가 각자 필요한 작업을 처리합니다.
이 방식은 서비스 간 결합도를 낮추고 확장성을 높입니다. Kafka, RabbitMQ, AWS SNS/SQS 등이 많이 사용됩니다.
12. CQRS 패턴
CQRS는 명령과 조회를 분리하는 패턴입니다. 쉽게 말해 쓰기용 모델과 읽기용 모델을 따로 둔다는 뜻입니다.
예를 들어 주문 생성, 결제, 취소 같은 작업은 쓰기 DB에서 처리하고, 주문 조회 화면은 읽기 전용 DB나 검색 엔진에서 처리합니다.
대규모 서비스에서는 조회 트래픽이 쓰기 트래픽보다 훨씬 많습니다. 이때 읽기 모델을 별도로 최적화하면 성능을 크게 높일 수 있습니다.
13. 사가 패턴
Saga Pattern은 분산 트랜잭션을 여러 단계로 나누고, 실패 시 보상 작업을 실행하는 방식입니다.
예를 들어 쇼핑몰 주문 과정은 주문 생성, 결제 승인, 재고 차감, 배송 요청으로 이루어집니다. 만약 배송 요청이 실패하면 결제 취소와 재고 복구를 해야 합니다.
이처럼 여러 서비스가 관련된 작업에서 전체 롤백 대신 단계별 보상 트랜잭션을 사용합니다.
14. 멱등성
Idempotency는 같은 요청이 여러 번 실행되어도 결과가 한 번 실행한 것과 같도록 만드는 원칙입니다.
예를 들어 사용자가 결제 버튼을 두 번 눌러도 실제 결제는 한 번만 되어야 합니다. 이를 위해 결제 요청마다 고유한 idempotency key를 부여합니다.
API, 결제, 메시지 큐, 배치 작업에서 매우 중요합니다. 재시도 패턴과 함께 사용하면 안정성이 크게 높아집니다.
15. 벌크헤드 패턴
Bulkhead Pattern은 시스템 자원을 분리해 하나의 장애가 전체로 번지지 않게 하는 방식입니다.
선박의 격벽처럼, 한 칸에 물이 들어와도 배 전체가 침몰하지 않게 하는 개념입니다.
예를 들어 관리자 서비스, 사용자 서비스, 결제 서비스가 같은 DB 커넥션 풀을 공유하면 하나의 서비스 과부하가 전체 장애를 만들 수 있습니다. 그래서 서비스별로 커넥션 풀, 스레드 풀, 서버 자원을 분리합니다.
16. 리더 선출
Leader Election은 여러 노드 중 하나를 리더로 선택하는 방식입니다.
예를 들어 여러 서버가 동시에 배치 작업을 실행하면 중복 처리가 발생할 수 있습니다. 이때 하나의 서버만 리더가 되어 작업을 수행하게 합니다.
ZooKeeper, etcd, Consul 같은 도구가 리더 선출에 사용됩니다. 분산 락, 클러스터 관리, 스케줄러 시스템에서 자주 쓰입니다.
17. 고십 프로토콜
Gossip Protocol은 노드들이 서로 상태 정보를 조금씩 주고받으며 전체 클러스터 상태를 공유하는 방식입니다.
소문이 사람들 사이에 퍼지는 방식과 비슷합니다. 한 노드가 모든 노드에 직접 알리지 않아도, 여러 노드를 거치며 정보가 퍼집니다.
Cassandra, Consul 같은 분산 시스템에서 노드 상태 전파에 사용됩니다. 대규모 클러스터에서 효율적으로 상태를 동기화할 수 있습니다.
18. 일관된 해싱
Consistent Hashing은 서버가 추가되거나 제거될 때 데이터 재배치를 최소화하는 기법입니다.
예를 들어 캐시 서버가 3대 있다가 4대로 늘어나면 일반 해싱은 대부분의 데이터 위치가 바뀔 수 있습니다. 하지만 일관된 해싱을 사용하면 일부 데이터만 이동합니다.
Redis Cluster, Cassandra, CDN, 분산 캐시 시스템에서 많이 사용됩니다. 확장성과 안정성을 동시에 높여줍니다.
19. Write-Through 캐싱
Write-Through Caching은 데이터를 쓸 때 캐시와 DB를 동시에 갱신하는 방식입니다.
예를 들어 사용자가 프로필을 수정하면 DB뿐 아니라 Redis 캐시도 함께 업데이트합니다. 그러면 다음 조회 때 오래된 캐시를 보여줄 가능성이 줄어듭니다.
장점은 데이터 일관성이 높다는 점이고, 단점은 쓰기 속도가 느려질 수 있다는 점입니다. 금융, 회원정보, 인증정보처럼 정확성이 중요한 곳에 적합합니다.
20. 이벤트 소싱
Event Sourcing은 현재 상태만 저장하지 않고 상태 변화의 모든 이벤트를 저장하는 방식입니다.
예를 들어 은행 계좌에 현재 잔액 100만 원만 저장하는 것이 아니라, 입금 50만 원, 출금 10만 원, 입금 60만 원 같은 모든 거래 이력을 저장합니다.
이 방식은 감사 추적, 장애 복구, 히스토리 재생에 강합니다. 금융, 회계, 감사 로그, 인증심사 이력 관리 시스템에 매우 적합합니다.
핵심 정리
이 20개 개념은 단순한 이론이 아니라 장애를 줄이고, 성능을 높이고, 확장 가능한 서비스를 만드는 실전 설계 원칙입니다.
작은 시스템에서는 캐싱, 로드밸런싱, 재시도, 멱등성부터 적용하고, 중대형 시스템에서는 이벤트 기반 설계, CQRS, 사가 패턴, 샤딩, 복제, 이벤트 소싱까지 확장하면 좋습니다.
— 이춘곤(Mark) · ISC.studio · ISC출판 도서 안내
이 글은 저자의 Facebook에 처음 게시한 글입니다. Facebook 원문 보기
💬 댓글 (0)