백엔드 데이터 인프라 83편. Kafka Design Motivation — Kafka 가 왜 이렇게 설계됐나. LinkedIn 의 데이터 파이프라인 문제·기존 메시지 큐의 한계·high throughput·large backlog·low latency·partitioned distributed processing·fault-tolerance 5가지 설계 동인을 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 130편 중 83편이에요. 82편 까지 Kafka 의 정체성·활용·hands-on 을 잡았다면, 이번 83편부터는 Part 5-2 — Design (7편) 으로 들어가요. Kafka 의 핵심 설계 결정을 깊이 풀어 가는 영역이고, 첫 글이 Motivation — 왜 이렇게 설계됐는가 입니다.
Design Motivation이 어렵게 느껴지는 이유
설계 동인은 추상적이라 처음 보면 코드와 바로 연결되지 않아요.
첫째, 2010년대 초 LinkedIn 의 문제 상황이 지금 회사 환경과 다릅니다. 당시 LinkedIn 이 어떤 데이터 파이프라인 문제로 막혔는지가 잡혀야 Kafka 의 모든 선택이 이해돼요.
둘째, 기존 메시지 큐의 한계가 추상적입니다. ActiveMQ (Java 기반 전통 메시지 브로커)·RabbitMQ (AMQP 표준 메시지 브로커) 같은 시스템이 왜 부족했는지 — 처리량·재처리·여러 consumer 같은 문제 — 가 명시적으로 잡혀야 하고요.
이 글에서는 Kafka 설계의 5가지 핵심 동인과, 데이터베이스 로그 모델에서 영감을 받은 설계 철학까지 풀어 가요.
시작점 — LinkedIn 의 데이터 파이프라인 문제
2010년 LinkedIn 의 상황:
- 수억 사용자 의 활동 데이터 (페이지 뷰·검색·클릭·로그인) 수십억 이벤트/일
- 수십 개 시스템 이 이 데이터를 필요로 함 — 추천 엔진·검색 인덱스·실시간 알림·통계 대시보드·data warehouse (분석용 통합 데이터베이스)·ML 학습 등
- 각 시스템마다 별도 데이터 파이프라인 = N × M 복잡도 폭증
N개 데이터 source M개 데이터 destination
──────────────── ─────────────────────
Web Server ─┐ ┌─ Recommendation
Mobile App ├──── N × M 직접 연결 ───┤── Search Index
Backend API │ (혼돈) ├── Hadoop
DB Change ─┘ └─ Analytics
N=10, M=20 이면 200개 직접 연결이 생겨요. 연결마다 프로토콜·포맷·실패 처리가 따로 붙고, 새 시스템 하나 추가할 때 비용도 만만치 않고요. (Hadoop — 대용량 분산 batch 처리 플랫폼.)
해법 — 중앙 stream 시스템
Source ──┐ ┌── Destination
├── 단일 Stream Hub ────┤
Source ──┘ └── Destination
모든 데이터가 한 곳을 통과하면 복잡도가 N + M 으로 떨어져요. 새 source 또는 destination 을 더할 때도 한 곳에만 연결하면 되고, Kafka 가 바로 그 Stream Hub 자리에요.
여기서 시험 함정이 하나 있어요 — Kafka 는 큐를 만든 게 아니라 통합 플랫폼을 만들려 한 시스템. 대량 처리·영구 저장·재처리·여러 consumer 가 동시에 필요했던 큰 문제를 한 도구로 풀자는 출발이에요.
5가지 설계 동인
설계 동인을 공식 문서 그대로 5가지로 정리해 봐요.
(1) High Throughput
high volume event stream 처리예요. 수십억 이벤트/일 규모의 LinkedIn 활동 데이터.
→ Kafka 의 선택:
- 디스크 sequential I/O 를 메모리처럼 사용 (84편)
- Zero-copy (커널 버퍼에서 네트워크로 바로 전송) + Batch 압축 (85편)
- Partition 으로 병렬 처리 — 단일 broker 가 아닌 cluster 분산
(2) Large Data Backlog
"offline 시스템 (Hadoop) 의 주기적 batch load" — 1일 1회 dump 받아 다음 단계 처리. 데이터가 며칠 쌓여도 안전하게 처리할 수 있어야 해요.
→ Kafka 의 선택:
- 디스크 1급 저장 (메모리만 의존 X)
- 시간·크기 기반 retention — 며칠~몇 달 데이터 보존
- consumer 가 늦어져도 데이터 손실 없음
(3) Low Latency
전통 메시지 큐 영역이에요 — 결제·알림처럼 수 ms 단위 응답.
→ Kafka 의 선택:
- ms 단위 publish/consume
- zero-copy + sendfile (커널 파일을 소켓으로 바로 보내는 syscall) 로 OS 레벨 최적화
- batch 모드와 즉시 모드 둘 다 지원
(4) Partitioned, Distributed, Real-time Processing
"새 derived feed 만들기" — raw 활동 데이터에서 집계·필터·조인으로 유도된 stream 을 만드는 일이에요. 마이크로배치가 아닌 실시간.
→ Kafka 의 선택:
- Partition 모델 — topic 을 N개 partition 으로 쪼개 병렬 처리가 자연스러워져요
- Consumer Group — 같은 그룹 안에서 partition 분담
- Stream Processing API (Kafka Streams — Kafka 안에서 도는 stream 처리 라이브러리) — Kafka 안에서 직접 처리 가능
(5) Fault-Tolerance
"stream 이 다른 데이터 시스템 으로 흘러갈 때 — 머신 고장 안전성 보장". broker 한 대 죽어도 데이터 손실 없이 계속 동작해야 해요.
→ Kafka 의 선택:
- Replication — partition 을 N copy
- Leader-Follower 자동 failover — leader 죽으면 replica 가 자동 promote
- ACK 메커니즘 (ACK — 수신 확인 응답) — producer 가 복제까지 확인 후 응답받는 옵션
설계 영감 — 메시지 시스템보다 데이터베이스 로그에 가까움
이 절이 정말 중요해요. 공식 문서의 핵심 문장:
"Supporting these uses led us to a design with a number of unique elements, more akin to a database log than a traditional messaging system."
전통 메시지 큐 (RabbitMQ·ActiveMQ 등):
- 큐 모델 — consume 시 메시지 제거
- 복잡한 라우팅 (exchange·routing key·binding)
- 각 메시지 = 별도 처리 단위
- 영구 보존 X
데이터베이스 로그 (write-ahead log — 변경을 디스크에 먼저 쓰는 기록, transaction log — 트랜잭션 변경 기록):
- append-only 순차 기록
- 오래 보존
- 순서 보장
- 재처리·복구 가능
Kafka 는 후자에 가까워요. 각 partition 이 하나의 영속 로그가 되고, consumer 는 그 로그를 따라가는 reader 로 동작하면서 저장된 offset (로그 내 읽기 위치 포인터) 으로 자기 자리를 추적해요.
이 모델이 가져온 결정적 차이 4가지:
- 재처리 가능 — consumer 가 offset 되감기로 과거 메시지 재처리
- 여러 consumer 가 독립적 — 각자 자기 offset 만 추적
- 영구 보존 — retention 안에서는 언제든 다시 읽기
- 상태 복구 — 새 consumer 가 처음부터 모든 메시지 재생해 상태 재구성
운영적 함의 — 왜 Kafka 가 무겁나
Kafka 가 강력한 이유가 그대로 운영 복잡도가 큰 이유이기도 해요.
- 분산 시스템 본질 — 단일 인스턴스 모드는 개발용만
- 디스크 1급 — 데이터 크기 폭증 가능, 디스크 관리 필요
- Partition 재분배 — 노드 추가·제거 시 대량 데이터 이동
- Replication 모니터링 — ISR (in-sync replicas) 추적
- Consumer Group 관리 — lag·rebalancing
- 모든 클라이언트가 Kafka-aware — 단순 HTTP API 가 아님
이 부담을 cloud managed Kafka (AWS MSK·Confluent Cloud 등) 가 줄여주기 때문에, 처음 도입하는 환경에서 자주 선택받아요.
비교 — Kafka 가 부적합한 자리
설계 동인을 반대로 뒤집어 보면, Kafka 가 잘 안 어울리는 자리도 보여요:
- 소량 처리 + 복잡 라우팅 — RabbitMQ
- 요청-응답 RPC 모델 — gRPC·REST
- 순서 보장이 partition 너머 필요 — Kafka 한계
- 트랜잭션 across topics + DB — 까다로움 (transaction 지원 있지만 복잡)
- 운영 인력 부족 — Cloud Managed 안 쓰면 부담 큼
시험 직전 한 번 더 — Kafka Design Motivation 함정 압축 노트
- 시작점 = 2010년 LinkedIn 의 N×M 데이터 파이프라인 폭증 문제
- 해법 = 중앙 stream hub → N+M 단순화
- Kafka = 단순 큐가 아닌 통합 데이터 플랫폼
- 5가지 설계 동인 = High Throughput · Large Backlogs · Low Latency · Partitioned Distributed Processing · Fault Tolerance
- High Throughput = 디스크 sequential I/O + zero-copy + partition 병렬
- Large Backlogs = 디스크 1급 저장, 시간·크기 retention, 며칠~몇 달 보존
- Low Latency = ms 단위, zero-copy·sendfile, batch + 즉시 모드
- Partitioned Processing = Topic 의 N개 partition + Consumer Group + Kafka Streams
- Fault Tolerance = Replication factor N + Leader-Follower 자동 failover + ACK
- 설계 영감 = 전통 메시지 큐가 아닌 DB log 모델
- DB log 모델 결과 4가지 = 재처리 가능·여러 consumer 독립·영구 보존·상태 복구
- Partition = 하나의 영속 로그, consumer = offset 따라가는 reader
- 운영 복잡도 = Kafka 의 강력함의 비용
- 분산 본질·디스크 관리·partition 재분배·replication 모니터링·consumer group 관리 등
- Cloud Managed (MSK·Confluent Cloud) 가 부담 완화
- 부적합 자리 — 소량+복잡 라우팅 (RabbitMQ) · 요청-응답 (gRPC/REST) · partition 너머 순서 보장 · 운영 인력 부족
공식 문서: Kafka Design — Motivation 에서 자세한 설계 결정을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 78편 — Redis Client 라이브러리 종합
- 79편 — Java Redis Client (Jedis vs Lettuce 깊이)
- 80편 — Apache Kafka란 + 이벤트 스트리밍의 표준
- 81편 — Kafka 활용 영역 7가지 (메시징·활동 추적·로그·이벤트 소싱)
- 82편 — Kafka Quickstart (5분 hands-on · topic·producer·consumer)
다음 글: