Small Asteroid Blog

Kafka Consumer Lag이 쌓이다가 Consumer Group이 사라진 문제 본문

카테고리 없음

Kafka Consumer Lag이 쌓이다가 Consumer Group이 사라진 문제

작은소행성☄️ 2026. 3. 12. 23:21
728x90

Consumer Lag이란

Kafka에서 Consumer Lag은 다음을 의미한다.

Lag = Topic의 최신 offset - Consumer가 읽은 offset

즉 Consumer가 메시지를 얼마나 뒤쳐져서 읽고 있는지를 나타낸다.

Lag이 줄어들지 않는다는 것은 보통 다음 중 하나다.

  1. Consumer가 메시지를 읽지 못하는 경우
  2. Offset commit이 되지 않는 경우
  3. Consumer Group이 정상 등록되지 않은 경우

 

문제 상황

Kafka 기반 스트림 처리 시스템을 운영하면서 만난 이슈에 대한 내용이다.

Kafka Topic에는 메시지가 계속 들어오고 있었는데 Consumer Lag이 줄어들지 않고 계속 쌓였다.

더 이상한 점은 Lag이 많이 쌓인 이후 Consumer Group 자체가 보이지 않는 것처럼 보이는 현상이었다.

이번 글에서는 이 문제의 원인과 Kafka Consumer의 동작 방식에 대해 정리해본다.

 

Kafka Consumer의 핵심 동작 방식

Kafka Consumer는 다음과 같은 poll loop 구조로 동작한다.

poll() → 메시지 가져오기
처리
poll()
처리
poll()

Kafka는 Consumer가 주기적으로 poll()을 호출하는지를 확인한다. max.poll.interval.ms

기본값 300000ms(5분) 인데, 5분 동안 poll()이 호출되지 않으면 Kafka는 consumer가 죽었다고 판단한다.

 

Consumer Lag이 많을 때 발생하는 문제

Lag이 매우 많을 때 다음 상황이 발생할 수 있다.

poll()
→ 메시지 대량 fetch
→ 메시지 처리 시작
→ 처리 시간이 오래 걸림
→ 다음 poll() 호출 지연

예를 들어

poll()
→ 5000 messages
→ DB 저장
→ 처리 시간 10분
→ 다음 poll()

이 경우 Kafka 입장에서는 max.poll.interval.ms 초과가 발생한다.

Kafka는 이를 consumer failure 로 판단하고 Consumer를 group membership에서 제거한다.

그래서 Consumer Group이 사라진 것처럼 보인다.

 

Python Consumer에서 더 자주 발생하는 이유

Python Kafka client에서는 이 문제가 더 쉽게 발생할 수 있다.

이유는 다음 구조 때문이다.

poll() + message processing = 같은 thread

즉, 메시지 처리가 오래 걸리면 poll 호출 자체가 지연된다.

poll()
→ 메시지 가져오기
→ 처리
→ poll()

 

Java Consumer로 마이그레이션 후 정상 동작

기존 Python consumer를 Java consumer로 마이그레이션하면서 구조가 다음처럼 바뀌었다.

poll thread
processing worker thread

poll → queue 적재
worker → 메시지 처리

이 구조에서는 poll() 호출이 계속 유지되기 때문에 consumer session , consumer group 이 정상 유지가 된다.

 

결과적으로

  • consumer group 정상 등록
  • lag 감소
  • partition assignment 정상

으로 문제가 해결되었다.

 

Kafka Consumer Lag 장애 시 확인해야 할 것

Consumer Lag 문제가 발생하면 다음 설정을 확인해야 한다.

 

1️⃣ max.poll.interval.ms

 Consumer가 poll() 을 호출하지 않아도 되는 최대 시간

2️⃣ max.poll.records

poll() 한 번에 가져오는 메시지 수

3️⃣ session.timeout.ms

consumer heartbeat timeout

 

 

해결 방법

대표적인 해결 방법은 다음과 같다.

1️⃣ poll thread와 processing thread 분리

poll → queue
worker → 처리

2️⃣ max.poll.interval 증가

max.poll.interval.ms = 1800000

3️⃣ batch size 감소

max.poll.records = 100

 

정리

이번 장애의 핵심은 다음과 같다.

문제 원인
Consumer Lag 증가 메시지 처리 속도 부족
Consumer Group 사라짐 poll 호출 지연
Kafka에서 consumer 미표시 max.poll.interval 초과

 

 

Consumer Lag이 많아서 Consumer Group이 사라진 것이 아니라, 메시지 처리 지연으로 poll() 호출이 늦어지면서 Kafka가 Consumer 세션이 끊긴 것으로 판단해 group membership에서 제거된 것이었다.
Kafka Consumer는 일정 시간 내에 poll()을 호출하지 않으면 coordinator가 Consumer를 비활성 상태로 판단하기 때문에, poll loop가 끊기지 않도록 처리 구조를 설계하는 것이 중요하다.
728x90
반응형