Distributed Messaging & Event Streaming
시스템 간 비동기 결합을 위한 메시지 큐와 대규모 데이터의 흐름을 처리하는 이벤트 스트리밍 기술의 작동 물리 및 보장 수준을 다루는 학습 노드입니다.
Article
M
Me
hyunyoun's Blog
network-communicationnetworkcommunicationdistributed-messagingevent-streamingmessage-queuesbroker-physicslearning9 min read
1. Overview
분산 메시징 및 이벤트 스트리밍(Distributed Messaging & Event Streaming, DMS)은 현대 소프트웨어 시스템이 수직적 명령 구조(Request-Response)를 벗어나, 사건(Event) 기반으로 실시간 소통하며 비동기적으로 결합(Decoupling)하는 물리적 토대를 다룹니다.
데이터는 더 이상 "원할 때 꺼내보는" 정적인 상태가 아니라, 끊임없이 생성되고 흐르는 '통나무(Log)'의 형태를 띱니다. 학습자는 주문 서비스가 결제 서비스의 응답을 기다리지 않고 메시지만 던져두고(Fire-and-Forget) 가는 비동기 큐(RabbitMQ 등)의 작동 원리를 익히고, 수백만 건의 이벤트를 순서대로 하드디스크에 기록하며 무한대로 확장하는 분산 이벤트 스트리밍(Kafka 등)의 본질적 차이를 배웁니다. 이를 통해 장애 발생 시에도 데이터를 잃어버리지 않는(Exactly-once 보장) 대규모 실시간 파이프라인 아키텍트의 능력을 기릅니다.
2. Scope & Boundaries
In-Scope
- 메시징 기초 (Messaging Models): P2P(Point-to-Point) 큐와 Pub/Sub(Publish/Subscribe) 토픽 모델의 구조적 차이, 생산자(Producer)와 소비자(Consumer)의 탈결합.
- 분산 로그 역학 (Event Logging): 순차적 쓰기(Append-only Log), 오프셋(Offset) 커밋, O(1) 디스크 I/O 최적화 물리.
- 전송 보장 (Delivery Semantics): At-most-once(최대 한 번), At-least-once(최소 한 번), Exactly-once(정확히 한 번)의 논리적 한계와 극복 방법.
- 확장성과 고가용성 (Scalability & HA): 파티셔닝(Partitioning), 소비자 그룹(Consumer Group) 리밸런싱, 브로커 간 리더-팔로워 복제(Replication).
Out-of-Scope
- 스트림 데이터 분석 로직: Flink나 Spark Streaming을 이용한 복잡한 윈도우 조인(Window Join) 및 SQL 처리 로직 06. Data & Information Management 영역으로 위임.
- 분산 트랜잭션의 DB 락(Lock) 처리: 메시지가 아닌 RDBMS 내부의 2PC(Two-Phase Commit)나 분산 락 06. Data & Information Management 영역으로 위임.
Boundaries
- DMS vs. Web Protocols (08-04): WAP(08-04)이 HTTP나 gRPC처럼 '당장 대답을 들어야 직성이 풀리는' 동기(Synchronous) 통신에 가깝다면, DMS는 '나는 메시지 던졌으니 퇴근할게, 나중에 네가 알아서 처리해'라는 비동기(Asynchronous) 통신과 그 메시지를 중간에서 보관해 주는 브로커(Broker)의 영속성에 집중합니다.
3. Counterexample
- 동기 호출의 연쇄 붕괴 (Synchronous Fallacy): '회원가입' 버튼을 눌렀을 때, 백엔드가 [DB 저장 환영 이메일 발송 쿠폰 발급]을 HTTP 동기 통신으로 순차 처리하게 짜놓은 구조. 이메일 서버가 3초간 지연되면 회원가입 자체가 3초간 먹통이 되고, 쿠폰 서버가 죽으면 회원가입 로직 전체가 롤백(Rollback)됩니다. 현대 시스템은 가입 완료(Event)만 **메시지 큐(Message Queue)**에 던져두고 즉시 유저에게 성공 화면을 보여주며, 이메일과 쿠폰 서버는 나중에 큐에서 메시지를 꺼내어(Pull) 천천히 처리하는 비동기 역학(Event-Driven)을 적용해야 합니다.
- "카프카는 그저 무적의 큐"라는 오해 (Queue vs Log Fallacy): 기존의 ActiveMQ, RabbitMQ 같은 전통적인 큐는 소비자가 메시지를 읽어 가면 큐에서 그 메시지를 '삭제(Delete)'하지만, 카프카(Kafka)는 며칠이고 디스크에 메시지를 그대로 '보존(Retention)'합니다. 이 물리적 차이를 이해하지 못하고 카프카를 단순 큐처럼 쓰며 "왜 디스크 용량이 꽉 차지?"라고 묻거나, 과거의 이벤트를 다시 재생(Replay)할 수 있는 스트리밍의 무기를 버리는 것은 시스템 아키텍처의 재앙입니다.
4. Prerequisites
- 네트워크 계층 및 전송 프로토콜 (Basic): 소켓 통신에서 ACK(확인 응답)를 받고 재전송하는 TCP의 신뢰성 메커니즘을 알아야 브로커의 전달 보장 물리를 이해할 수 있습니다. (08-02. TCP/UDP)
- 운영체제 파일 I/O (Recommended): 디스크 암순차 쓰기(Sequential Write)와 페이지 캐시(Page Cache)의 원리를 알아야 카프카의 압도적 속도를 이해합니다. (03-04. Storage Mechanics)
5. Learning Map
6. Learning Topics
Basic
Core Topic 01: 비동기 메시징과 디커플링 (Async Messaging)
- Why to Learn: 한 대의 서버가 죽더라도 전체 시스템이 마비되지 않고, 쏟아지는 트래픽을 안전하게 담아두는 댐(Buffer)을 만들기 위함입니다.
- What to Learn:
- Concepts: 동기(Sync) vs 비동기(Async), 결합도(Coupling) 완화, 생산자(Producer)와 소비자(Consumer), 브로커(Broker).
- Skills: Point-to-Point (Queue) 모델, 배압(Backpressure) 통제, 피크 트래픽의 평탄화(Load Leveling).
- Tools: RabbitMQ, Amazon SQS, Redis Pub/Sub.
- Trade-offs: 시스템의 응답 속도가 비약적으로 빨라지고 유연해지는 강력함 vs 비동기로 흘러간 메시지가 실패했을 때 이를 추적하고 디버깅하기가 지옥처럼 어려워지는 복잡성(Observability 부재).
- How to Learn:
- 1단계: 초당 1,000건의 주문이 들어오지만 결제 서버는 초당 100건밖에 처리하지 못할 때, 중간에 Message Queue를 두어 900건이 큐에 쌓이면서 서서히 소화되는 버퍼링 과정을 도식화합니다.
- 2단계: 소비자가 메시지를 성공적으로 처리한 후 브로커에게 "다 썼으니 지워"라고 보내는 확인 응답(ACK) 과정에서, 소비자 프로세스를 강제로
kill했을 때 메시지가 다시 큐로 돌아가는 장애 복구 메커니즘을 분석합니다.
- Implement: 파이썬 환경에서 Redis나 RabbitMQ를 이용해, 이미지 업로드(Producer) 후 백그라운드 썸네일 생성(Consumer) 작업을 비동기로 처리하는 작업자 모델 구축.
Recommended
Core Topic 02: Pub/Sub 모델과 이벤트 라우팅 (Pub/Sub & Routing)
- Why to Learn: 이벤트 하나가 터졌을 때(예: 유저 회원가입), 이 소식을 알 필요가 있는 수십 개의 부서(마케팅, 정산, 알림)에 코드를 수정하지 않고 방송(Broadcast)하기 위해서입니다.
- What to Learn:
- Concepts: Publish-Subscribe (Pub/Sub) 모델, 토픽(Topic), 라우팅 키(Routing Key), 팬아웃(Fan-out).
- Skills: 주제 기반 메시지 라우팅 설계, 브로커 내부의 익스체인지(Exchange) 로직(Direct, Topic, Fanout).
- Tools: RabbitMQ Exchanges, AWS SNS.
- Trade-offs: 새로운 시스템이 추가될 때 기존 생산자 코드를 전혀 건드리지 않아도 되는 완벽한 확장의 자유 vs 아무도 구독하지 않는 쓸데없는 이벤트가 네트워크에 계속 뿌려져 인프라 비용을 낭비하는 스팸성 트래픽 문제.
- How to Learn:
- 1단계: RabbitMQ 환경에서 생산자가 이벤트를
Exchange라는 라우터에 던지고, 이 라우터가 '로그.에러'라는 라우팅 키를 보고 알맞은 큐(Queue)로 분배하는 토폴로지를 스케치합니다. - 2단계: '회원가입'이라는 1개의 이벤트를 AWS SNS(팬아웃)에 쏘면, 연결된 3개의 SQS 큐(포인트, 이메일, 환영 패키지)로 동시에 복제되어 전달되는 병렬 처리 역학을 시뮬레이션합니다.
- 1단계: RabbitMQ 환경에서 생산자가 이벤트를
- Implement: 특정 이커머스 도메인의 이벤트(주문 생성, 주문 취소, 결제 완료 등)에 대해, 시스템 간 의존성을 제거한 Pub/Sub 메시지 토픽/라우팅 설계 다이어그램 작성.
Practical
Core Topic 03: 분산 이벤트 스트리밍 물리 (Event Streaming & Kafka)
- Why to Learn: 큐에서 메시지를 읽고 지우는 일회성 소비를 넘어, 과거의 모든 기록을 디스크에 영구히 저장하고 언제든 타임머신처럼 과거로 돌아가 데이터를 재처리하기 위함입니다.
- What to Learn:
- Concepts: 분산 커밋 로그(Distributed Commit Log), Append-only 파일 시스템, 카프카(Kafka) 아키텍처.
- Skills: 파티션(Partition)을 통한 수평 확장, 소비자 그룹(Consumer Group)의 역할 분담, 오프셋(Offset) 커밋 정책.
- Tools: Apache Kafka, AWS Kinesis.
- Trade-offs: 디스크에만 순차적으로 쓰기(O(1)) 때문에 메모리에 올리는 큐보다 압도적으로 많은 트래픽을 처리할 수 있는 속도 vs 카프카 클러스터를 유지하고 파티션 리밸런싱을 관리하는 살인적인 데브옵스(DevOps) 난이도.
- How to Learn:
- 1단계: 카프카의 토픽이 3개의 '파티션(Partition)'으로 나뉘고, 소비자 그룹의 워커(Worker) 3대가 각 파티션을 하나씩 맡아 병렬 처리 속도를 3배로 끌어올리는 물리적 스케일링 구조를 매핑합니다.
- 2단계: 워커 하나가 죽으면, 카프카 클러스터가 이를 감지하여 남은 2대의 워커에게 3개의 파티션을 재분배(Rebalancing)하고, 죽은 워커가 마지막으로 읽었던 '오프셋 번호(Offset 105)'부터 다시 읽게 하여 유실을 막는 복구 과정을 추적합니다.
- Implement: 초당 1만 건의 클릭 로그 스트림이 들어올 때, 파티션 개수 산정과 컨슈머 그룹 설정을 통해 병목을 해결하는 카프카 프로비저닝 스크립트 작성.
Advanced
Core Topic 04: 전송 보장과 이벤트 소싱 (Delivery Semantics & Sourcing)
- Why to Learn: 은행 시스템처럼 "절대 데이터가 2번 결제되어서도 안 되고, 누락되어서도 안 되는" 무결성의 극한을 비동기 환경에서 보장하기 위해서입니다.
- What to Learn:
- Concepts: 전송 보장 레벨(At-most-once, At-least-once, Exactly-once), 멱등성(Idempotency), 트랜잭셔널 아웃박스(Transactional Outbox) 패턴.
- Skills: 카프카의 트랜잭션 API 적용, 이벤트 소싱(Event Sourcing) 설계, CQRS(명령/조회 책임 분리).
- Tools: Kafka Transactions, Debezium (CDC).
- Trade-offs: "결제 100원 완료"라는 이벤트를 브로커에 확실하게 박아 넣는(Exactly-once) 완벽한 데이터 정합성 vs 이 보장을 위해 트랜잭션 코디네이터가 개입하면서 시스템 처리량(Throughput)이 반토막 나는 심각한 성능 저하.
- How to Learn:
- 1단계: 프로듀서가 메시지를 보냈는데 네트워크 타임아웃이 나서 '다시 보냄(재시도)'을 수행했을 때, 컨슈머가 이 메시지를 두 번 처리하여 돈이 두 번 빠져나가는 사고(At-least-once의 한계)를 파악합니다.
- 2단계: 이를 막기 위해 메시지 자체에 고유 식별자(UUID)를 부여하고 컨슈머의 DB 처리 로직을 멱등하게(Idempotent, 몇 번을 실행해도 결과가 같게) 튜닝하거나, 카프카의 Exactly-once 설정(PID와 Epoch 이용) 물리를 뜯어봅니다.
- Implement: 데이터베이스 변경 사항을 캡처(CDC)하여 카프카 스트림으로 흘려보내고, 다른 마이크로서비스에서 이를 수신해 자신의 로컬 DB 상태를 최신화하는 '최종적 일관성(Eventual Consistency)' 데이터 파이프라인 설계도.
7. Terminology
8. References
Primary References
- [P2] SWEBOK v4.0 - Software Construction/Distributed Systems — Event-based logic.
- [P5] SFIA - Systems Integration / Data Engineering — Messaging pipeline skills.
Secondary References
- [Designing Data-Intensive Applications] Martin Kleppmann — Best chapter on logs and messaging.
- [Kafka: The Definitive Guide] Gwen Shapira — Industrial standard for streaming.
Industry References
- [RabbitMQ: AMQP Protocol] — Messaging broker standard.
- [Apache Kafka Documentation] — The architecture of distributed logs.
9. Final Checklist
Primary Checklist
- 동기식 호출(RPC/REST)과 비동기식 메시징의 물리적 레이턴시 및 가용성 측면에서의 트레이드오프를 설명 가능한가? (P2)
- 메시지 브로커가 일시적으로 다운되었을 때, 생산자의 데이터 유실을 방지하기 위한 물리적 전략(Buffer, Retry)을 제시할 수 있는는가? (P2)
Secondary Checklist
- 큐에 쌓인 메시지가 처리 속도보다 빠르게 증가할 때(Backpressure), 시스템 전체의 안정성을 위한 조절 매커니즘을 이해하는가?
- 토픽의 파티션 개수와 컨슈머 그룹의 인스턴스 개수 사이의 상관관계와 병목 발생 원인을 식별 가능한가?
Industry Checklist
- 실무 서비스에서 결제 완료 이벤트를 처리할 때, '정확히 한 번' 처리를 위해 데이터베이스 트랜잭션과 메시지 오프셋 관리를 어떻게 연동할지 설계 가능한가? (SFIA)
- 대용량 로그 수집 시스템 설계 시, RabbitMQ와 Kafka의 보관 방식(Delete on ACK vs Log Retention) 차이에 근거하여 적절한 도구를 선택할 수 있는가?