LLM WikiAccess-protected knowledge portal
← 스터디 홈
2편 · 약 24분

Kafka 운영 심화: partition sizing, consumer lag, rebalance, retention

운영 현실에서 Kafka가 어려운 이유

Kafka는 아키텍처 자체는 단순하다. 하지만 운영에 들어가면 세 가지 문제가 반복적으로 나타난다. 파티션이 부족해서 소비가 따라가지 못하고, consumer lag이 쌓여서 SLA를 놓치고, rebalance가 일어날 때마다 처리가 멈춘다. 여기에 retention 설정을 잘못 잡으면 lag이 누적된 컨슈머가 삭제된 오프셋을 참조해 에러가 난다.

이 장은 파티션 설계부터 lag 모니터링, rebalance 최소화, retention 정책까지 Kafka 운영의 핵심 결정을 다룬다.


1. Partition Sizing: 얼마나 쪼갤 것인가

파티션이 결정하는 것

Kafka에서 파티션 수는 최대 병렬 소비 단위다. 한 컨슈머 인스턴스는 동시에 최대 하나의 파티션만 담당한다. 10개의 파티션이 있으면 한 컨슈머 그룹에서 최대 10개의 인스턴스가 동시에 읽을 수 있다. 11번째 인스턴스는 idle 상태로 대기한다.

Topic: user-events (파티션 4개)
Partition 0
Partition 1
Partition 2
Partition 3
컨슈머 2개 (과소)
Consumer 1
P0 + P1
Consumer 2
P2 + P3
각 컨슈머가 2개씩 담당 → 처리 부하 높음
컨슈머 4개 (적정)
C1→P0
C2→P1
C3→P2
C4→P3
1:1 매핑으로 최대 병렬성
컨슈머 6개 (과잉)
C1→P0
C2→P1
C3→P2
C4→P3
C5 idle
C6 idle
파티션보다 많은 컨슈머는 idle — 리소스 낭비
파티션 수와 소비 병렬성

처리량 기반 파티션 수 산정

파티션 수 결정의 기본 공식은 다음과 같다:

파티션 수 = max(필요 처리량 / 프로듀서 파티션당 처리량,
               필요 처리량 / 컨슈머 파티션당 처리량)

실무에서 보수적으로 쓰이는 값:

  • 파티션당 프로듀서 처리량: ~20–50 MB/s (복제 포함)
  • 파티션당 컨슈머 처리량: 소비 로직에 따라 1–50 MB/s로 편차 큼

예시: 목표 처리량 150 MB/s, 소비 처리량이 병목(파티션당 15 MB/s)이면:

파티션 수 ≈ 150 / 15 = 10개
→ 스파이크·리밸런스 여유 고려해 15–20개로 설정

파티션 수 늘릴 때 주의점

파티션 수를 줄이는 것은 지원하지 않는다. 늘리는 것은 가능하지만 부작용이 있다:

  • 키 기반 라우팅 변경: 기존 userId % N 분배가 깨져서 같은 키의 이벤트가 다른 파티션으로 흩어진다. 순서 보장이 필요한 경우 파티션 수 변경은 위험하다.
  • Rebalance 유발: 파티션 추가 즉시 컨슈머 그룹 rebalance가 발생한다.
  • 처음부터 여유 있게: 필요한 파티션 수의 2–3배 여유를 두고 처음부터 설계하는 것이 운영 부담을 줄인다.

2. Consumer Lag: 지연을 측정하고 줄이는 법

Consumer Lag이란

Consumer lag은 브로커의 최신 오프셋(Log End Offset)과 컨슈머가 커밋한 오프셋의 차이다.

Consumer Lag = Log End Offset − Consumer Committed Offset

lag이 0이면 컨슈머가 실시간으로 따라가고 있다는 의미다. lag이 지속적으로 증가하면 컨슈머가 프로듀서 속도를 따라가지 못하는 것이다.

offset 0 LEO (최신) Committed Offset 컨슈머가 처리 완료한 위치 Log End Offset 브로커에 쌓인 최신 메시지 Lag = 290 offsets
Consumer Lag 개념과 Offset 관계

Lag 측정 방법

# 컨슈머 그룹별 lag 조회
kafka-consumer-groups.sh \
  --bootstrap-server broker:9092 \
  --group my-consumer-group \
  --describe

# 출력 컬럼: TOPIC, PARTITION, CURRENT-OFFSET, LOG-END-OFFSET, LAG, CONSUMER-ID

Kafka의 __consumer_offsets 내부 토픽에 오프셋 정보가 기록된다. Prometheus + kafka_exporter, Datadog, Grafana 등의 모니터링 도구는 이를 읽어서 시계열로 추적한다.

Lag 주요 원인과 해결

원인진단 신호해결 방향
컨슈머 처리 속도가 느림lag 증가, CPU 낮음처리 로직 최적화, 배치 처리 도입
파티션보다 컨슈머 수 부족파티션당 lag 일정컨슈머 인스턴스 증설
프로듀서 유입량 급증(스파이크)lag 일시 급증 후 수렴backpressure 설계, 버퍼 증설
컨슈머 rebalance 반복lag 주기적 급증rebalance 원인 제거, 안정화
오프셋 커밋 지연committed offset 정체커밋 간격 조정 (auto.commit.interval.ms)
GC pause, slow DB 연동산발적 lag 급증컨슈머 타임아웃 조정, 외부 의존성 최적화

경고 기준 예시: lag이 5분 이상 지속적으로 증가하면 경고, 30분 넘으면 긴급. 절대 lag 수치보다 lag 증감 추세가 더 중요한 신호다.


3. Rebalance: 처리 중단의 원인과 최소화

Rebalance란

컨슈머 그룹에 멤버가 추가되거나 제거될 때 파티션 할당을 재조정하는 과정이 rebalance다. 기존 프로토콜(eager/stop-the-world)에서는 rebalance 시작 시 모든 컨슈머가 파티션을 반납하고, 새 할당이 완료될 때까지 소비가 멈춘다.

❌ Eager (기존) — Stop-the-world
1. 모든 컨슈머
파티션 반납
2. 전체 소비 중단
(수 초~수십 초)
3. 새 할당 계산
4. 모든 컨슈머
새 파티션 재할당
파티션이 많을수록, 컨슈머가 많을수록 중단 시간이 길어짐.
✅ Cooperative Sticky — 증분 Rebalance
1. 변경이 필요한
파티션만 반납
2. 나머지 파티션은
계속 소비 중
3. 변경 파티션만
재할당
영향 받지 않는 파티션의 소비는 중단 없이 계속됨. Kafka 3.7+ KIP-848(NGCRP)로 더욱 개선.
Rebalance 프로토콜 비교: Eager vs Cooperative

Rebalance를 유발하는 주요 원인

  1. session.timeout.ms 초과: 컨슈머가 브로커에 heartbeat를 보내지 못하면 dead로 간주. 처리 로직이 느릴 때 발생.
  2. max.poll.interval.ms 초과: poll() 호출 간격이 너무 길면 컨슈머가 그룹에서 제외. 배치 처리 시간이 긴 경우.
  3. 배포/스케일 아웃: 컨슈머 인스턴스 추가·제거.
  4. 네트워크 일시 단절.

Rebalance 최소화 설정

# 컨슈머 설정
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor

# heartbeat와 세션 타임아웃 적절히 설정 (heartbeat < session.timeout)
heartbeat.interval.ms=3000
session.timeout.ms=45000

# poll 간격: 처리 시간보다 넉넉하게
max.poll.interval.ms=300000

# 처리량 조정: 한 번에 너무 많이 가져오면 처리 시간이 길어짐
max.poll.records=500

Kafka 3.7부터 KIP-848로 새로운 Consumer Rebalance Protocol(NGCRP)이 도입되었다. 기존 group coordinator 방식 대신 브로커가 직접 파티션 할당 상태를 관리해 rebalance 속도가 최대 20배 빨라진다.


4. Retention: 데이터를 얼마나 보관할 것인가

Retention 정책의 두 축

Kafka는 시간 기반크기 기반 retention을 지원한다. 둘 다 설정하면 먼저 도달하는 조건에서 삭제된다.

설정설명기본값
retention.ms메시지를 유지할 최대 시간7일 (604800000ms)
retention.bytes파티션당 최대 보관 크기-1 (무제한)
log.segment.bytes세그먼트 파일 크기 (삭제 단위)1 GB
log.retention.check.interval.ms삭제 체크 주기5분

Retention 설계 원칙

컨슈머 lag을 retention보다 낮게 유지해야 한다. lag이 쌓여서 retention 기간을 넘으면 컨슈머가 이미 삭제된 오프셋을 읽으려 하고 OffsetOutOfRangeException이 발생한다.

삭제된 세그먼트 Committed Offset ⚠ 삭제된 영역 안에 있음! → OffsetOutOfRangeException Log End Offset Lag = 540 오프셋 (너무 큼)
Retention과 Lag의 위험 관계

Retention 설계 기준:

  • 최소 retention = (현재 lag / 프로듀서 처리량) × 안전 계수 (≥ 2)
  • 예: lag이 최대 50만 건, 프로듀서가 초당 1만 건이면 최소 50초 × 2 = 약 2분 — 이건 너무 짧으므로 보통 1–7일로 설정하고 lag을 그 이하로 관리
  • 재처리 요건: 장애 후 재처리가 필요한 경우 처리 SLA보다 여유 있는 retention이 필요
  • 컴플라이언스·감사: 법적 보존 기간이 있는 경우 별도 스토리지(S3/HDFS)에 아카이브 후 Kafka retention은 짧게

Retention 관련 운영 설정

# 토픽별 retention 변경 (무중단)
kafka-configs.sh --bootstrap-server broker:9092 \
  --alter --entity-type topics --entity-name user-events \
  --add-config retention.ms=604800000,retention.bytes=107374182400

# 즉시 오래된 데이터 정리 (긴급 시)
kafka-configs.sh ... --add-config retention.ms=1000
# 잠시 후 원래값으로 되돌리기

5. 운영 대시보드: 핵심 지표

Kafka 클러스터를 안정적으로 운영하려면 다음 지표를 상시 추적해야 한다.

Consumer 지표
consumer_lag (그룹별, 파티션별)
commit_rate
poll_rate
records_consumed_rate
fetch_latency_avg
Broker 지표
BytesInPerSec / BytesOutPerSec
MessagesInPerSec
UnderReplicatedPartitions
ActiveControllerCount (=1이어야 함)
RequestHandlerAvgIdlePercent
Producer 지표
record_send_rate
record_error_rate
record_queue_time_avg
batch_size_avg
compression_rate_avg
알림 기준 (예시)
consumer lag 5분 이상 증가 → 경고
UnderReplicatedPartitions > 0 → 경고
ActiveControllerCount ≠ 1 → 긴급
디스크 사용률 > 80% → 경고
RequestHandlerAvgIdlePercent < 20% → 경고
Kafka 운영 지표 트리

파티션 skew 점검

파티션 간 lag이나 처리량 차이가 크면 파티션 skew가 발생한 것이다. 원인은 키 분포가 편향되어 있거나(핫 파티션), 특정 파티션에 이상 데이터가 집중된 경우다.

# 파티션별 offset 확인
kafka-run-class.sh kafka.tools.GetOffsetShell \
  --bootstrap-server broker:9092 \
  --topic user-events --time -1

# 파티션별 lag 상세 확인
kafka-consumer-groups.sh \
  --bootstrap-server broker:9092 \
  --group my-group --describe | sort -k6 -n

6. 종합: 토픽 설계 결정 체크리스트

새 토픽을 만들 때 결정해야 할 사항을 명확히 정의해두면 이후 운영 문제를 줄일 수 있다.

  • [ ] 파티션 수: 목표 처리량 / 파티션당 처리량, 예상 컨슈머 수, 2배 여유를 고려
  • [ ] Replication Factor: 운영 환경은 최소 3 (브로커 1대 장애 허용)
  • [ ] Retention: 시간 기반 vs 크기 기반, 재처리 요건, 규정 준수
  • [ ] Compaction 여부: 최신 상태만 필요한 경우 log.cleanup.policy=compact
  • [ ] 키 설계: 순서 보장이 필요한 단위로 키 설정, 핫 파티션 방지
  • [ ] 컨슈머 그룹 할당 전략: Cooperative Sticky Assignor 사용 여부
  • [ ] Lag 알림 기준: 비즈니스 SLA에서 역산

References

  • Confluent, "How to Choose the Number of Topics/Partitions in a Kafka Cluster?," https://www.confluent.io/blog/how-choose-number-topics-partitions-kafka-cluster/
  • Confluent Documentation, "Choose and Change the Partition Count in Kafka," https://docs.confluent.io/kafka/operations-tools/partition-determination.html
  • Instaclustr, "Rebalance your Apache Kafka® partitions with the next generation Consumer Rebalance Protocol," https://www.instaclustr.com/blog/rebalance-your-apache-kafka-partitions-with-the-next-generation-consumer-rebalance-protocol/
  • Netdata, "Apache Kafka Consumer Lag: Troubleshooting & Fixes," https://www.netdata.cloud/academy/apache-kafka-consumer-lags/
  • Conduktor, "Kafka Partitioning: 5 Strategies Compared," https://www.conduktor.io/glossary/kafka-partitioning-strategies-and-best-practices
  • Factor House, "Kafka topic partition best practices," https://factorhouse.io/articles/kafka-topic-partition-best-practices
  • Factor House, "Kafka scaling best practices," https://factorhouse.io/articles/kafka-scaling-best-practices
  • AutoMQ, "Kafka Partition Rebalancing: Why It's Slow & How to Fix," https://www.automq.com/blog/kafka-partition-rebalancing-why-slow-how-to-fix
  • Medium (Sudhanshu Thakur), "Scaling Kafka Consumers: Strategies and Best Practices," https://medium.com/@sudhanshubliz/scaling-kafka-consumers-strategies-and-best-practices-fc9ec58b7252