Kafka를 “메시지 큐”로만 알면 절반만 아는 거다. Kafka의 본질은 분산된, 영속적인, append-only 로그다. 메시지를 소비해도 사라지지 않고, 디스크에 순차적으로 쌓이며, 파티션으로 나뉘어 병렬 처리된다.
이 단순한 로그 구조가 두 가지를 동시에 푼다. 하나는 압도적인 처리량, 다른 하나는 서비스 간 데이터 통합이다.
append-only 로그가 왜 빠른가
디스크가 느리다는 건 랜덤 액세스 얘기다. 순차 쓰기는 메모리 못지않게 빠르다. Kafka는 로그를 끝에 덧붙이기만 하고, OS page cache에 맡기고, 파티션으로 병렬화한다. 그래서 단일 브로커도 적절히 튜닝하면 1만 TPS를 넘긴다.
쓰기만 빠른 게 아니다. 컨슈머에게 보낼 때는 sendfile()로 zero-copy 전송을 해서 page cache의 데이터를 JVM 힙을 거치지 않고 커널에서 바로 소켓으로 내보낸다. 순차 쓰기·page cache·zero-copy가 맞물려 읽기·쓰기 양쪽이 빠르다. 구체적인 동작과 튜닝은 single-broker 글에서 다룬다.
처리량을 결정하는 건 파티션 수(병렬도), 프로듀서 배치(batch.size/linger.ms), acks와 fsync 정책, JVM 힙과 page cache의 균형이다. 이걸 측정하고 튜닝하는 게 Kafka 운영의 기본기다.
로그가 왜 데이터 통합의 중심이 되나
같은 로그를 여러 컨슈머가 각자의 속도로 읽을 수 있다는 점이 핵심이다. 주문 DB의 변경을 로그에 흘려보내면, 검색·캐시·정산·추천이 각자 그 로그를 구독해 따라간다. 서비스들이 서로를 직접 호출하지 않고 로그를 통해 느슨하게 연결된다.
이걸 가능하게 하는 게 Kafka Connect와 CDC다. Debezium이 MySQL binlog를 읽어 변경을 로그로 만들고(Source), 다른 쪽에서 그 로그를 외부 시스템으로 흘려보낸다(Sink). Connector/Task/Worker 구조, offset 관리, snapshot, DDL 변경 대응이 운영 포인트다.
→ Kafka Connect — Source/Sink 내부 동작과 실전 운영
로그와 트랜잭션이 만나는 곳 — Outbox
“DB에 쓰고 Kafka에 발행”을 따로 하면 둘 중 하나가 실패해 데이터가 어긋난다. 이 문제를 로그의 특성으로 푸는 게 Outbox 패턴이다. DB 트랜잭션 안에서 outbox 테이블에 쓰고, CDC가 그걸 로그로 발행한다. 분산 트랜잭션 없이 일관성을 맞춘다.
그래서 언제 Kafka인가 — 대안과 비교
“메시지 보낼 거면 RabbitMQ도 있는데 왜 Kafka냐”에 답할 수 있어야 한다.
- vs RabbitMQ: RabbitMQ는 전통적 브로커다. 브로커가 라우팅을 책임지고(exchange/queue), 소비하면 메시지가 사라지며, 복잡한 라우팅·작업 큐(태스크 분배)에 강하다. Kafka는 로그라 소비해도 보존되고 여러 컨슈머가 독립적으로 재생·재처리하며 처리량이 높다. **작업 큐(RPC식 태스크 분배·낮은 지연 단건)**이면 RabbitMQ, 이벤트 로그·파이프라인·높은 처리량·재처리면 Kafka.
- vs SQS/Kinesis(매니지드): 운영 부담을 줄이고 AWS에 묶여도 되면 매니지드. SQS는 단순 큐(순서·재생 약함), Kinesis는 Kafka와 유사(샤드=파티션)하나 보존·생태계(Connect)·온프렘 유연성은 Kafka가 앞선다. 운영 인력이 있고 생태계·이식성이 필요하면 Kafka.
- vs Redis Streams: 가벼운 스트림이면 Redis Streams로 충분하다. 대규모 영속·파티션 확장·CDC 생태계가 필요하면 Kafka.
안 맞는 경우: 메시지량이 적고 단순 작업 분배뿐이거나, 요청-응답·즉시 일관성이 필요하거나, 운영 인력 없이 소규모면 Kafka는 오버킬이다. 클러스터·KRaft·파티션 설계의 운영 비용을 감당할 만큼 처리량·통합 요구가 클 때 의미가 있다.
면접에서 이 그림이 유용한 이유
“이벤트 드리븐 아키텍처를 설명하라”를 받으면 로그라는 본질에서 풀 수 있다. “Kafka는 append-only 로그라 순차 쓰기로 빠르고, 같은 로그를 여러 컨슈머가 독립적으로 읽어 서비스를 분리한다. 그래서 처리량(단일 브로커 튜닝)과 데이터 통합(CDC/Connect)을 동시에 얻는다.” 여기에 순서 보장(파티션 키), 정확히 한 번(at-least-once + 멱등 컨슈머), 컨슈머 랙·리밸런싱 같은 실전 이슈를 붙이면 깊이가 산다.