메세지 브로커/Kafka

[Kafka] 클러스터 구조와 파티션 설계 — 트랜잭셔널 프로듀서부터 토픽 분리 기준까지

Joonfluence 2026. 7. 12.

1. 문서 제목

  • Kafka 클러스터 구조와 파티션 설계 — 트랜잭셔널 프로듀서부터 토픽 분리 기준까지

2. 기술 개요 요약

Kafka 클러스터는 "파티션 단위로 데이터를 나누는 샤딩"과 "파티션마다 리더-팔로워로 복제하는 replication"이 동시에 적용된 구조다. 이 구조를 이해하면 파티션 수를 늘릴 때의 비용, 토픽을 나누는 기준, 여러 파티션·토픽에 걸친 쓰기를 원자적으로 처리하는 트랜잭셔널 프로듀서, 브로커 장애 시의 대응까지 하나의 그림으로 연결할 수 있다.

3. 핵심 개념 정리

개념 설명 실무 포인트
클러스터 구조 파티션은 샤딩(데이터 분할), 파티션 내 리더+팔로워 복제는 replication(Redis Master-Replica와 동일 개념) 브로커 하나가 죽으면 그 브로커가 리더였던 파티션들에 대해서만 새 리더가 선출됨(failover)
idempotent producer vs transactional producer idempotent producer(enable.idempotence=true)는 같은 파티션 내 재시도 중복 쓰기만 방지. transactional producer여러 파티션/토픽에 걸친 쓰기를 하나의 원자적 단위로 묶음 컨슈머는 isolation.level=read_committed로 설정해야 커밋 안 된(aborted) 메시지를 걸러낼 수 있음. Kafka 내부 쓰기끼리의 원자성이지 외부 DB/API 호출까지 묶어주진 않음 — DB와 함께 원자적으로 다루려면 Outbox 패턴 필요
파티션 수 산정 파티션이 많을수록 병렬성은 늘지만 브로커의 파일 핸들·메모리 오버헤드, 장애 시 리더 재선출 작업량, 컨트롤러 fail-over 시 메타데이터 로딩 시간이 함께 증가 Kafka는 파티션 삭제(축소)를 지원하지 않음. 파티션 수를 늘리면 partition = hash(key) % N에서 N이 바뀌므로, 기존에 저장된 데이터가 재배치되는 것이 아니라 앞으로 들어오는 같은 키의 새 메시지가 다른 파티션으로 라우팅되어 그 키의 신-구 메시지 간 순서 보장이 깨질 수 있음. 순서 보장이 중요한 토픽은 초기 설계 시 넉넉하게 산정
토픽 분리 기준 ① 이벤트가 나타내는 비즈니스적 사실(fact)의 종류가 다른가(의미 단위) ② 실제로 소비하는 서비스/팀이 다른가(소비자 관심사) 같은 엔티티의 상태 변화(주문 생성/취소 등)는 오히려 한 토픽에 묶고 엔티티 ID를 파티션 키로 잡아 순서를 보장하는 것이 유리 — "분리 기준"과 반대 방향의 기준임을 함께 기억
클러스터 간 통신 리전 간 재해 복구, 서로 다른 팀이 운영하는 클러스터 사이의 이벤트 공유는 MirrorMaker 2 같은 도구로 토픽을 다른 클러스터로 복제 동기 복제가 아니므로 클러스터 간에는 최종적 일관성만 기대 가능. 지연·순서 재배열 가능성을 감안해야 함

4. 사용 예시 및 코드 스니펫

클러스터 구조 시각화 (브로커 3대, 파티션 3개, replication factor 3):

                브로커 1              브로커 2              브로커 3
              ┌───────────┐        ┌───────────┐        ┌───────────┐
파티션 0       │ P0 LEADER │───────▶│ P0 팔로워   │───────▶│ P0 팔로워   │
파티션 1       │ P1 팔로워  │◀─────── │ P1 LEADER │───────▶│ P1 팔로워   │
파티션 2       │ P2 팔로워  │◀─────── │ P2 팔로워   │◀───────│ P2 LEADER │
             └───────────┘        └───────────┘        └───────────┘

Redis Cluster와 Kafka 클러스터 구조 비교:

  Redis Cluster Kafka 클러스터
분산 단위(샤드) 16384개 고정 해시 슬롯 토픽 생성 시 지정한 파티션 수
복제 단위 슬롯(마스터)당 레플리카 N개 파티션당 팔로워 N개(replication factor)
failover 마스터 죽으면 레플리카 중 승격 리더 죽으면 팔로워(ISR) 중 승격

트랜잭셔널 프로듀서 사용 흐름:

producer.initTransactions()
producer.beginTransaction()
producer.send(record1)   // topic A
producer.send(record2)   // topic B
producer.commitTransaction()   // 또는 abortTransaction()

5. 실제 사용 시 주의점 / Best Practice

  • 파티션 수를 "공짜로 늘어나는 병렬성"으로 생각하지 말 것. 파일 핸들·메모리 같은 고정비용과, 장애 시 리더 재선출·메타데이터 로딩 같은 장애 복구 시간이 함께 늘어나는 트레이드오프다. 
  • 트랜잭셔널 프로듀서Kafka 내부 쓰기끼리만 원자성을 보장한다. DB 업데이트나 외부 API 호출까지 같은 트랜잭션으로 묶고 싶다면 Outbox 패턴을 별도로 적용해야 한다. 
  • 토픽을 나눌지 합칠지 결정할 때 "의미 단위가 다른가"와 "소비자 관심사가 다른가"를 먼저 따지고, 순서 보장이 필요한 케이스는 반대로 하나의 토픽 + 엔티티 ID 파티션 키로 묶는다. 
  • 클러스터 간 복제(MirrorMaker 2)는 동기 복제가 아니므로, 재해복구 설계 시 RPO(복구 시점 목표)에 지연 시간을 반드시 반영해야 한다.

6. 참고자료 / 공식 문서 출처

반응형

댓글