LLM WikiAccess-protected knowledge portal

WIKI

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

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

경로human/study/content/streaming-data-platform/02-kafka-advanced-partition-sizing-consumer-lag-rebalance-retention.md
카테고리Study
태그#consumer #lag #monitoring #rebalance #retention #sizing #study

운영 현실에서 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(필요 처리량 / 프로듀서 파티션당 처리량,
               필요 처리량 / 컨슈머 파티션당 처리량)

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

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

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

파티션 수 늘릴 때 주의점

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


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 관련 운영 설정

# 토픽별 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. 종합: 토픽 설계 결정 체크리스트

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


References