Data & Platform/Event Streaming
Kafka - 02. topic and partition
topic과 partition — 메시지를 어디에, 어떻게 쌓을 것인가
쇼핑몰에서 주문이 들어온다. 이 주문 데이터를 어디에 쌓을까? Kafka에선 topic이라는 곳에 넣는다. "주문" topic, "클릭 로그" topic, "결제" topic처럼 용도별로 topic을 나눠 메시지를 분류한다. 그런데 주문이 초당 수만 건씩 쏟아지면 topic 하나로는 감당이 안 된다 — 그래서 topic을 여러 조각으로 쪼개는데, 그 조각이 partition이다.
여기서 대부분이 처음 만나는 함정이 하나 있다. partition 수는 나중에 늘릴 수 있지만, 늘리는 순간 같은 key의 메시지가 다른 partition으로 흩어진다. "사용자 A의 주문은 항상 같은 partition에 있을 것"이라는 가정이 한 번에 깨진다. 이 함정 하나가 topic과 partition을 단순한 "데이터 그릇"이 아니라, 순서·병렬성·운영 비용이 얽힌 설계 결정으로 만든다. topic이 무엇인지, partition이 왜 필요한지, key가 어떤 역할을 하는지, 그리고 partition을 늘렸을 때 벌어지는 일까지를 한 호흡으로 추적한다.
topic — 용도별 메시지를 가르는 이름표
topic은 가장 단순하게 말하면 "메시지를 담는, 이름 붙인 상자(또는 카테고리)"다. 데이터베이스의 테이블이나 파일시스템의 폴더와 비슷하다 — 용도별로 나눠 놓는 구분선.
| 비유 | topic에 대응 |
|---|---|
| 우체국의 수신처란(주문/청구/문의) | topic 이름(orders / clicks / payments) |
| 회사의 사서함 번호 | topic 이름 — 메시지가 여기로 배달됨 |
| 데이터베이스의 테이블 | topic — 한 종류의 데이터를 담는 그릇 |
topic의 구체 예
실제 서비스에선 이렇게 topic을 나눈다:
orders— 주문 이벤트 (주문 생성, 취소, 상태 변경)user-clicks— 사용자 클릭 로그 (UX 분석용)payments— 결제 요청/완료shipping-events— 배송 상태__consumer_offsets— (내부용) consumer가 어디까지 읽었나
topic 이름은 용도를 드러내게 짓는 게 관례다. t1, test 같은 이름은 운영에서 혼란을 만든다. 더불어 환경(dev/stage/prod)을 prefix로 붙이는 팀도 있지만, 환경이 바뀔 때마다 consumer 설정이 바뀌어야 하므로 환경별 클러스터를 분리하는 쪽이 더 흔하다.
topic은 로그다 — 소비해도 남는다
topic은 로그(log)다 — 메시지가 들어온 순서대로 계속 append되고, consumer가 읽어도 지워지지 않는다(retention 정책이 닿기 전까지). 그래서 여러 consumer가 같은 topic을 각자 따로 읽을 수 있고, 나중에 다시 읽을(replay) 수도 있다. 이게 일반 "큐"(소비하면 사라짐)와 topic의 결정적 차이다.
쇼핑몰 orders topic이 실제로 돌아가는 법
추상 정의만으론 감이 안 온다. 쇼핑몰의 orders topic이 실제로 어떻게 쓰이는지 보자.
flowchart LR
P1[주문 API 서버] -->|주문 이벤트 produce| T["orders topic"]
P2[모바일 앱] -->|주문 이벤트 produce| T
T -->|consume| C1[주문 처리 서비스<br/>재고 차감·결제]
T -->|consume| C2[분석 파이프라인<br/>일별 매출 집계]
T -->|consume| C3[알림 서비스<br/>주문 확인 이메일]
이 시나리오가 topic의 가치를 보여준다:
- 여러 곳에서 쓴다(multi-producer): 주문 API 서버와 모바일 앱이 모두
orderstopic에 주문 이벤트를 쓴다. 어디서 왔든 같은 topic에 쌓인다. - 여러 곳에서 읽는다(multi-consumer): 주문 처리 서비스(재고 차감), 분석 파이프라인(매출 집계), 알림 서비스(이메일)가 각자 독립적으로 같은
orderstopic을 읽는다. 한 consumer가 느려져도 다른 consumer는 영향 안 받는다. - 나중에 다시 읽을 수 있다(replay): 분석에서 버그를 발견하면, 지난주 주문 데이터를
orderstopic에서 다시 읽어 재처리할 수 있다(메시지가 남아있으므로).
이게 topic을 단순 "메시지 큐"가 아니라 이벤트의 영속 저장소로 쓰는 방식이다. 서비스들이 topic을 사이에 두고 느슨하게 연결되는 구조(이벤트 기반 아키텍처)의 기반이 된다.
topic을 만들 때:
bin/kafka-topics.sh --create --topic orders --partitions 3 --replication-factor 1 --bootstrap-server localhost:9092. 여기서--partitions 3이 바로 다음에 볼 partition이다.
topic 하나로 충분한가 — 왜 partition이 필요한가
주문이 초당 10건이면 topic 하나(partition 1개)로 충분하다. 하지만 주문이 초당 수만 건으로 늘면? topic을 하나의 줄(로그)로만 처리하면:
- 쓰기가 한 곳에 몰림 — 한 broker만 바쁘고, 다른 broker는 한가함.
- 읽기도 한 줄 — consumer를 여럿 띄워도 한 줄을 순서대로 읽어야 하니 병렬 처리가 안 됨.
해법: topic을 여러 조각(partition)으로 쪼개 각 조각을 다른 broker에 두고, consumer도 각 조각을 나눠 읽는다. 이게 partition의 탄생 동기다. "topic은 논리적 분류, partition은 물리적 분할"이라고 한 줄로 요약할 수 있다.
partition — topic을 쪼갠 물리적 병렬 단위
partition은 topic을 물리적으로 나눈 조각이다. topic orders에 partition 3개를 두면:
- partition 0, partition 1, partition 2 — 각각 독립된 append-only 로그.
- 메시지는 (key 유무에 따라) 어느 partition으로 갈지 정해져 들어간다.
- 각 partition은 (복제본 제외) 단일 broker에 저장되어 부하가 분산된다.
flowchart TB
T["topic: orders<br/>(논리적 분류)"] --> P0["partition 0<br/>(물리적 로그)"]
T --> P1["partition 1"]
T --> P2["partition 2"]
P0 --> B0["broker 0"]
P1 --> B1["broker 1"]
P2 --> B2["broker 2"]
partition은 세 가지의 최소 단위다
partition은 Kafka에서 세 가지 의미의 최소 단위를 동시에 뜻한다:
- 데이터 분할 단위 — 각 partition은 단일 broker에 저장. topic 전체 데이터가 partition 수만큼 분산.
- 병렬성 단위 — consumer group 내에서 partition 1개당 최대 consumer 1개가 병렬 소비. 즉 partition 수 = consumer 병렬성의 상한.
- 순서 보장 단위 — partition 내에서만 쓴 순서대로 읽힌다. topic 전체 순서 보장은 없다.
(basic-kafka-operations.md): partition 수가 "데이터를 몇 개 로그로 샤딩할지"와 "consumer 최대 병렬성"을 결정한다.
이 셋이 한 몸이라는 게 핵심이다. 병렬성을 늘리려 partition을 늘리면 순서 보장 범위가 쪼개진다 — partition 수 선택은 병렬성 vs 순서 보장 범위의 트레이드오프다.
key가 partition을 고정한다 — 같은 key는 같은 partition으로
producer가 메시지에 key를 주면, 같은 key는 항상 같은 partition으로 간다. 왜 필요한가 — 같은 사용자의 주문이 여러 partition에 흩어지면 순서가 꼬인다. "사용자 A의 주문"이 항상 같은 partition에 있어야 그 사용자 이벤트를 순서대로 처리할 수 있다.
구체 예:
key = "userA"인 메시지 → 항상 partition 1로 감(예). "userA"의 모든 주문이 partition 1에 순서대로 쌓임.key = "userB"→ 항상 partition 0으로 감(예).- key 없음(
null) → sticky: 한 batch를 같은 partition에 몰아넣어 효율을 높임. key 기반 순서가 필요 없는 로그에 적합.
어떻게 partition이 정해지나 — key를 해시해서 partition 수로 나눈다(자세한 공식은 심화 절에서). 핵심은 같은 key → 항상 같은 partition이라는 보장이다.
partition이 정해지는 방식을 모르면 "key를 줬는데 왜 어떤 사용자는 빨리 처리되고 어떤 사용자는 늦지?" 같은 현상의 원인(partition 쏠림)을 못 찾는다.
key가 있어도 쏠릴 수 있다 — cardinality 함정
key가 같으면 같은 partition이라는 보장은 있지만, key 종류가 적으면 partition이 쏠린다. 예를 들어 key가 사용자 등급(vip, normal) 단 두 가지라면, partition이 10개여도 실제로 쓰이는 partition은 2개뿐이다. 나머지 8개는 놀게 된다 — 병렬성을 partition 수만큼 확보한 줄 알았는데, key cardinality가 병목이 되는 셈이다.
이 문제를 피하려면 key를 높은 cardinality를 갖는 값(사용자 ID, 주문 ID)으로 잡거나, 순서 보장이 필요 없는 경우 key를 아예 안 쓰고 sticky partitioning에 맡기는 것이 낫다. key 선택은 "무엇의 순서를 보장할 것인가"와 "병렬성을 얼마나 활용할 것인가"의 트레이드오프를 가르는 설계 결정이다.
사용자 정의 partitioner — 기본 해시가 안 맞을 때
murmur2 % numPartitions가 요구사항을 만족하지 못하면 producer에 사용자 정의 Partitioner를 구현해 끼울 수 있다(partitioner.class 설정). 예를 들어 "VIP 사용자는 전용 partition으로, 일반 사용자는 해시 분산"을 강제하거나, 지역 기반 colocation을 위해 특정 partition으로 라우팅하는 식이다. 단, 사용자 정의 partitioner를 쓰면 "같은 key → 같은 partition" 규칙을 내가 책임져야 하고, partition 수가 변할 때의 동작도 직접 설계해야 한다 — 기본 partitioner가 주던 자동 보장을 포기하는 대가다.
partition 수를 늘리면 같은 key가 다른 partition으로 간다
이제 위에서 쌓은 기초가 필요한 부분이다. topic을 만들 때 partition 3개로 잡았다. 처리량이 부족해 5로 늘리기로 했다. "빈 공간이 두 개 더 생기겠지"라고 생각한다면 — 위험하다.
partition을 늘리는 순간, 기존에 특정 partition에 가던 key가 다른 partition으로 갈 수 있다. key가 "userA"라 partition 1에 가던 메시지가, partition이 5개가 되면 partition 3으로 갈 수 있다. 같은 key의 메시지가 partition 경계에서 순서가 끊기는 것이다.
flowchart LR
A["partition 3개<br/>key 'userA' → partition 1"] -->|alter --partitions 5| B["partition 5개"]
B --> C["key 'userA' → partition 3<br/>(매핑 변화)"]
C --> D["key 기반 순서 보장 파손<br/>(기존 메시지는 옮겨지지 않음)"]
왜? partition 결정이 hash(key) % partition수라서, partition수가 바뀌면 결과가 달라지기 때문이다. 공식 문서가 명시하는 부작용 (basic-kafka-operations.md):
- key 분포 변화: Kafka Streams 등 key 기반 상태를 쓰는 앱의 순서·상태 가정이 깨짐.
- consumer 데이터 누락 위험:
auto.offset.reset=latest인 consumer가 새 partition을 인지 못하는 찰나에 메시지를 놓칠 수 있음. - 메타데이터 전파 지연: 클러스터 전체에 새 partition 정보가 퍼지는 데 시간차.
주의: partition을 늘려도 기존 메시지는 옮겨지지 않는다. userA의 과거 메시지는 partition 1에 그대로 있고, 새 메시지는 partition 3으로 간다.
절대 금지: 내부 topic(
__consumer_offsets,__transaction_state,__cluster_metadata)의 partition을 수동으로 늘리면 시스템 장애. 이들은 Kafka가 스스로 관리한다.
partition은 왜 줄일 수 없는가
"그럼 모자라면 늘리고, 너무 많으면 줄이면 되겠지?" — 줄일 수 없다. Kafka는 partition 감소를 지원하지 않는다. 이유:
- 메시지는 이미 특정 partition에 영속됐다. 합치려면 offset을 다시 매겨야 하는데, 이미 commit된 consumer offset과 어긋난다.
- 두 partition의 메시지 사이엔 정의된 전체 순서가 없었으므로(그게 partition의 전제), 합쳐서 시간순으로 다시 엮는 게 불가능하다.
- ISR 복제본들도 같은 재구성을 동시에 해야 한다.
그래서 줄이려면 새 topic을 만들고 데이터를 이주(migrate)하는 수밖에 없다. 설계 단계에서 넉넉히 잡되, key 매핑 깨짐을 감수할 수 없다면 partition 수를 사실상 고정으로 설계해야 한다.
줄이기 불가능이 만드는 설계 압박
이 제약이 실제 프로젝트에서 만드는 압박을 구체적으로 보자. 팀이 "일단 partition 6개로 시작하자, 나중에 늘리면 되지"라고 결정했다고 하자. 3개월 뒤 처리량이 2배로 늘어 partition을 12로 늘려야 한다면:
- key 매핑이 깨진다 — 같은 사용자의 과거 주문과 신규 주문이 다른 partition에 흩어진다.
- consumer는 이전 partition의 마지막 offset과 새 partition의 시작 offset 사이의 관계를 알지 못한다.
- Kafka Streams 같은 key 기반 상태 앱은 changelog를 재구축해야 한다(시간·리소스 비용).
그래서 실무에선 partition 수를 "현재 필요량 × 여유(1.5~2)"로 잡되, 향후 확장을 위해 별도 topic으로 분리하거나 key 설계를 partition 수 증가에 견디게 하는 패턴을 쓴다. 예를 들어 사용자 ID를 key로 쓰되, partition 수 변화에 대비해 key 공간을 미리 고정할 수 없다면, 차라리 partition 수를 처음부터 크게 잡는 게 나을 수 있다.
Kafka Streams가 key-매핑 안정성에 의존하는 이유
Kafka Streams(장 11)는 key 기반 상태(state store)를 partition에 묶어 둔다 — "key X의 집계값은 항상 partition P에 있는 state store에 있다"는 가정. partition 수가 변하면 이 가정이 깨진다 — Streams는 changelog를 새 partition 매핑에 맞춰 재분배(restore)해야 한다. 이 과정은 자동이지만, 상태가 크면 시간이 오래 걸리고 그동안 해당 partition의 처리가 멈춘다.
그래서 Streams 앱을 쓰는 토픽은 partition 수를 처음부터 신중하게 잡는 게 거의 필수다. 늘리는 게 기술적으로 가능하지만, 운영적으로 비용이 크다. "partition은 늘리기만 가능하다"는 말이 단순한 제약이 아니라, key 기반 처리를 하는 모든 downstream(Streams, connect sink의 key 기반 분할 등)에 연쇄 영향을 준다는 점을 기억해야 한다.
partition 수는 어떻게 정하나
공식 문서는 절대 권장값을 명시하지 않는다. 다음 기준으로 산정한다:
| 기준 | 관계 |
|---|---|
| 처리량 | partition ↑ → 병렬 쓰기/읽기 ↑ (broker 한계까지) |
| consumer 병렬성 | consumer 수 ≤ partition 수 (초과분은 idle) |
| broker 부하 | partition ↑ → 파일 수·메모리 ↑ |
| 장애 복구 | partition ↑ → 복구 시간 ↑ |
| 순서 보장 | partition ↑ → key 순서 보장 범위 세분화 |
사이징 워크스루(수치는 가정, 실측 필수):
- 목표: 초당 100MB 처리.
- 실측: 단일 partition에서 producer throughput ~10MB/s, consumer 처리 ~8MB/s 측정.
- consumer 병렬성 상한 = partition 수. 100MB/s ÷ 8MB/s ≈ 13개 consumer 필요 → partition ≥ 13.
- broker당 partition 파일 핸들·메모리 비용 고려: partition 1개당 대략 수십 KB~수백 KB의 오버헤드(열린 파일·인덱스). broker당 수만 partition까지는 문서가 허용하나, 장애 복구 시간이 선형으로 늘어난다.
- 확장 여유 1.5~2배 → 20 partition으로 시작.
- consumer를 나중에 20까지 늘릴 수 있는 여유 확보.
이 계산에서 자주 틀리는 지점이 두 곳이다. 첫째, "consumer 수 = partition 수"를 맞추면 최대 병렬성이긴 하지만, broker 부하가 같이 오른다는 걸 간과한다. 둘째, partition 수를 미리 크게 잡으면 "나중에 늘릴 필요 없지 않나"라고 생각하지만, 늘리면 key 매핑이 깨지므로 처음부터 필요한 만큼만 잡는 게 정석이다. 늘리는 건 비용(순서 보장 파손)을 치르는 마지막 수단이지, 사전 설계의 대체재가 아니다.
"많을수록 좋다"가 아니다 — partition당 파일 핸들·메모리가 들고, broker 장애 시 복구가 느려진다.
leader 균형 — partition이 한쪽 broker로 쏠리면
partition마다 leader가 있고(장 06), leader broker가 모든 쓰기·읽기를 받는다. 그래서 partition leader가 한 broker에 몰리면 그 broker만 바쁘고 나머지는 한가한 핫스팟이 생긴다. Kafka는 이를 막기 위해 preferred replica election이라는 자동 균형 메커니즘을 둔다 — Replica 목록의 첫 번째 복제본(preferred leader)이 leader가 아니면, controller가 이를 다시 leader로 선출해 분산시킨다.
# Kafka 4.3, KRaft 단일 노드
# leader 불균형이 의심될 때 수동 균형 트리거(기본 자동 실행)
bin/kafka-leader-election.sh --bootstrap-server localhost:9092 \
--election-type preferred --all-topic-partitions
단일 노드 학습 환경에선 leader가 항상 그 한 broker이므로 의미가 없지만, 다중 broker 환경에서 partition 수를 늘릴 때마다 leader 분산이 따라가는지 확인하는 습관이 필요하다. leader 쏠림은 처리량 저하·broker 과부하의 흔한 원인이다.
Kafka 4.3 실습 — 직접 확인하기
사전: KRaft 단일 노드 기동.
topic 만들고 메시지 넣기
# Kafka 4.3, KRaft 단일 노드
bin/kafka-topics.sh --create --topic part-demo --partitions 3 --replication-factor 1 --bootstrap-server localhost:9092
# key:value 형태로 produce (key가 partition 결정)
bin/kafka-console-producer.sh --topic part-demo --property "parse.key=true" --property "key.separator=:" --bootstrap-server localhost:9092
# 입력 예:
# userA:evt1
# userA:evt2
# userB:evt3
확인할 것: 같은 key(userA)는 항상 같은 partition에 기록되는가.
bin/kafka-console-consumer.sh --topic part-demo --property "print.key=true" --property "print.partition=true" --from-beginning --bootstrap-server localhost:9092
partition: 1, key: userA, value: evt1
partition: 1, key: userA, value: evt2
partition: 2, key: userB, value: evt3
실제 partition 번호는 해시 결과에 따라 달라진다. 핵심은 같은 key → 같은 partition.
partition 추가와 key 매핑 변화 관찰
bin/kafka-topics.sh --alter --topic part-demo --partitions 5 --bootstrap-server localhost:9092
bin/kafka-console-producer.sh --topic part-demo --property "parse.key=true" --property "key.separator=:" --bootstrap-server localhost:9092
# userA:evt4 (새로 입력)
bin/kafka-console-consumer.sh --topic part-demo --property "print.key=true" --property "print.partition=true" --from-beginning --bootstrap-server localhost:9092
확인할 것: userA의 evt1/evt2는 partition 1에 있었지만, evt4는 partition이 바뀔 수 있다 → 같은 key의 순서가 partition 경계에서 끊긴다.
describe로 partition 상태 보기
bin/kafka-topics.sh --describe --topic part-demo --bootstrap-server localhost:9092
PartitionCount/ReplicationFactor: topic 전체 설정.Leader/Replicas/Isr: 각 partition의 복제 상태(단일 노드에선 모두 같음; 복제는 장 06).Leader값이 모든 partition에서 같은 broker 번호면 단일 노드이므로 정상. 다중 broker에선 leader가 분산돼야(preferred replica election, 본문 참조).- partition 수를 alter로 늘린 뒤에도 같은 명령으로
PartitionCount증가를 확인할 수 있다.
흔히 묻는 것, 흔히 틀리는 것
| 오해 | 정정 |
|---|---|
| "topic은 메시지 큐라서 소비하면 사라진다" | 아니다. topic은 로그. 소비해도 retention 전엔 남음(장 01) |
| "partition 많을수록 항상 빠르다" | broker당 파일 핸들·메모리 한계. 과도하면 장애 복구 지연 |
| "partition을 줄일 수 있다" | 불가. 늘리기만. 줄이려면 새 topic으로 이주 |
| "key 순서는 영원히 보장된다" | partition 수가 변하지 않는 한 보장. partition 증가 순간 깨짐 |
| "partition 수 = consumer 수로 맞추면 된다" | consumer 병렬성 상한일 뿐. 처리량·broker 부하도 함께 고려 |
| "topic 생성 후 기본값(partition 1)으로 둬도 된다" | 프로덕션에선 거의 항상 부족. 명시적 --partitions 필수 |
| "partition 늘리면 기존 메시지도 옮겨진다" | 아니다. 과거는 그대로, 새 메시지만 새 매핑 → key 순서 끊김 |
| "key 종류가 적어도 partition만 많으면 병렬성이 오른다" | 아니다. key cardinality가 partition 사용 수의 상한. 낮으면 partition이 쏠림 |
| "partition 수 변경은 기존 consumer에 영향이 없다" | 있다. auto.offset.reset=latest인 consumer가 새 partition 인지 찰나에 메시지 누락 가능 |
더 깊이 — partition은 어떻게 정해지나 (murmur2)
위에서 "key를 해시해서 partition 수로 나눈다"고만 했다. 정확한 공식이 궁금한 사람을 위해:
key != null:toPositive(murmur2(key)) % numPartitions. 같은 key는 항상 같은 partition(결정적).- BuiltInPartitioner.java를 보면
murmur2해시를 쓰고, 그걸 partition 수로 나눈다(모듈로).
왜 consistent hash가 아닌가 — partition 확장에 취약한 이유
Kafka 파티셔너가 consistent hash를 쓴다고 생각하는 경우가 많다. 아니다. consistent hash라면 partition 수가 변해도 대부분 key-매핑이 유지되지만, 모듈로 방식은 partition 수가 변하면 거의 모든 key의 매핑이 바뀐다. 바로 이것이 위 "partition 늘리면 key 매핑이 깨진다"의 원인이다.
murmur2는 비암호학적 해시다 — 속도가 빠르고 분산이 고른 것이 목적이지, 보안이 아니다. toPositive는 murmur2의 signed(음수 가능) 결과를 양수로 바꾸는 래퍼(음수 해시에 모듈로를 쓰면 partition 번호가 음수가 되므로).
partition 수 변화가 매핑을 얼마나 흔드는가 — 실제 계산 감
partition 3개에서 key "userA"의 해시값(가정)이 toPositive(murmur2("userA")) = 7이라 하자. 7 % 3 = 1 → partition 1. partition을 5로 늘리면 7 % 5 = 2 → partition 2. partition을 10으로 늘리면 7 % 10 = 7 → partition 7. 모듈로 방식은 partition 수가 변하면 거의 모든 key의 매핑이 바뀐다 — 이것이 consistent hash가 아닌 모듈로 파티셔닝의 결정적 약점이다.
key 기반 상태(changelog, state store)를 쓰는 Kafka Streams 앱은 "key X는 항상 partition P에 있다"를 전제로 동작한다. partition 수가 변하면 이 전제가 깨져 상태 재구성이 일어난다.
요약 — 이 글의 결론
- topic = 메시지를 담는 이름 붙은 상자(카테고리). 용도별로 나눔(orders, clicks...). 로그라 소비해도 남고, 여러 consumer가 따로 읽고, replay 가능.
- topic 사용: multi-producer(여러 곳에서 씀) + multi-consumer(여러 서비스가 따로 읽음). 이벤트 기반 아키텍처의 기반.
- partition = topic을 물리적으로 쪼갠 조각. topic 하나의 부하를 여러 broker로 분산.
- partition 세 의미: 데이터 분할 + 병렬성(=consumer 병렬성 상한) + 순서 보장(partition 내만).
- key → 같은 partition: 같은 key는 항상 같은 partition. 같은 사용자 이벤트 순서 처리에 필수. 단 key cardinality가 낮으면 partition이 쏠려 병렬성이 무의미해진다.
- partition은 늘리기만 가능(줄이기 불가). 늘리면 key 매핑이 깨져 순서 가정 파손. Streams 같은 key 기반 상태 앱은 changelog 재분배 비용을 치른다.
- 내부 topic partition 변경 절대 금지 → 시스템 장애.
- partition 수 산정은 처리량·컨슈머 병렬성·broker 부하·복구의 균형. "많을수록 좋다"가 아니다. 설계 단계에서 신중하게 잡는 게 늘리는 비용보다 싸다.
- leader 균형(preferred replica election): partition leader가 한 broker에 쏠리지 않게 controller가 자동 분산. 다중 broker 환경에서 핫스팟 방지.
생각해 볼 문제
- topic을 "메시지 큐"가 아니라 "로그"로 부르는 것이 어떤 차이를 만드는가? (소비 후 삭제 vs 남음)
- 쇼핑몰에서
orderstopic 하나를 주문 처리·분석·알림 서비스가 따로 읽는 것이 가능한 이유는? - topic 하나(partition 1개)로 초당 수만 건을 처리하기 어려운 이유는? partition이 어떻게 해결하는가?
- partition 6개인 topic에 consumer 4개인 그룹이 있다. 각 consumer는 몇 partition을 소유하는가? consumer를 8개로 늘리면?
- partition을 3→5로 늘리면 같은 key의 메시지 순서가 왜 끊기는가?
- partition을 줄일 수 없는 이유는? 줄여야 한다면 어떻게 해야 하는가?
- key 없이 produce하는데 cleanup.policy=compact인 topic에서 무슨 일이 벌어지는가?
- key로 사용자 등급(
vip/normal)만 쓰는 서비스가 partition 20개로 늘렸는데 처리량이 오르지 않는다. 원인은? - partition 수를 처음부터 크게 잡는 것과, 작게 시작해 나중에 늘리는 것의 실무적 trade-off를 설명하라.
참고
- Basic Operations — Adding/Modifying topics - 접근 2026-07-09 (partition 증가 부작용, 내부 topic 금지, preferred replica election)
- Topic configurations - 접근 2026-07-09 (partition 수, replication.factor, cleanup.policy)
- Introduction — Partitioning - 접근 2026-07-09 (topic/partition/offset 개념, multi-producer/multi-consumer)
- BuiltInPartitioner (murmur2) - 접근 2026-07-09 (sticky partitioning, key 해시)
- Partitioner interface (사용자 정의) - 접근 2026-07-09 (사용자 정의 partitioner 구현 시 참조)
'Data & Platform > Event Streaming' 카테고리의 다른 글
| Kafka - 06. replication (0) | 2026.07.09 |
|---|---|
| Kafka - 05. consumer group (0) | 2026.07.09 |
| Kafka - 04. consumer (0) | 2026.07.09 |
| Kafka - 03. producer (0) | 2026.07.09 |
| Kafka - 01. architecture (0) | 2026.07.09 |