Kafka를 운영하다 보면 가장 자주 만나는 지표 중 하나가 Consumer Lag입니다.
Lag는 단순히 "처리가 조금 밀렸다"는 의미로 끝나지 않습니다. 실시간 정산, 로그 수집, 주문 이벤트, 알림 시스템처럼 뒤쪽 서비스가 Kafka 메시지를 기준으로 움직이는 구조라면 Lag 증가는 곧 데이터 지연, 장애 전파, 사용자 경험 저하로 이어질 수 있습니다.
이 글에서는 Kafka Consumer Lag가 왜 생기는지, 어떤 순서로 확인해야 하는지, 운영 환경에서 어떤 설정을 먼저 의심해야 하는지 정리합니다.
Kafka Consumer Lag란?
Kafka Consumer Lag는 Producer가 Topic에 기록한 최신 offset과 Consumer Group이 처리 완료한 offset 사이의 차이입니다.
쉽게 말해 Kafka에는 메시지가 계속 쌓이고 있는데 Consumer가 그 속도를 따라가지 못하면 Lag가 커집니다.
Log End Offset = Topic partition의 최신 offset
Committed Offset = Consumer Group이 처리 완료한 offset
Consumer Lag = Log End Offset - Committed Offset
Lag가 일시적으로 증가했다가 곧 줄어든다면 큰 문제는 아닐 수 있습니다. 하지만 Lag가 계속 증가하거나 특정 partition에만 쌓인다면 운영 장애로 이어질 가능성이 큽니다.
먼저 확인할 지표
장애 대응에서는 원인을 바로 단정하지 말고 아래 순서로 확인하는 것이 좋습니다.
kafka-consumer-groups.sh \
--bootstrap-server localhost:9092 \
--describe \
--group my-consumer-group
확인해야 할 값은 다음과 같습니다.
항목의미확인 포인트
| TOPIC | 대상 토픽 | 특정 토픽만 문제인지 확인 |
| PARTITION | 파티션 번호 | 특정 파티션 쏠림 여부 확인 |
| CURRENT-OFFSET | Consumer 처리 offset | offset이 멈췄는지 확인 |
| LOG-END-OFFSET | Broker 최신 offset | Producer 유입량 확인 |
| LAG | 미처리 메시지 수 | 증가/감소 추세 확인 |
| CONSUMER-ID | 처리 중인 Consumer | Consumer가 살아있는지 확인 |
원인 1. Consumer 처리 속도가 느림
가장 흔한 원인은 Consumer 내부 처리 시간이 길어진 경우입니다.
예를 들어 메시지 하나를 처리할 때 외부 API 호출, DB insert, 파일 저장, 복잡한 계산이 들어가면 Consumer 처리량은 급격히 떨어집니다.
특히 아래 패턴은 Lag를 자주 만듭니다.
- 메시지마다 동기 HTTP API 호출
- 메시지마다 단건 DB insert
- 트랜잭션 범위가 너무 긴 처리
- 실패한 메시지를 즉시 무한 재시도
- Consumer thread 수보다 partition 수가 많은 구조
해결 방향은 메시지 처리 경로를 짧게 만드는 것입니다.
@KafkaListener(topics = "order-events", groupId = "order-worker")
public void consume(OrderEvent event) {
// 나쁜 예: 메시지마다 외부 API와 DB를 동기 호출
paymentClient.verify(event.getPaymentId());
orderRepository.save(convert(event));
}
운영에서는 외부 API 호출을 분리하거나, DB 저장을 batch 처리하거나, 실패 이벤트를 DLQ로 보내는 구조를 먼저 검토합니다.
원인 2. Partition 수와 Consumer 수가 맞지 않음
Kafka Consumer Group에서는 하나의 partition을 동시에 여러 Consumer가 나눠 처리할 수 없습니다.
예를 들어 partition이 3개인데 Consumer 인스턴스가 6개라면 실제로 일하는 Consumer는 최대 3개입니다. 반대로 partition이 12개인데 Consumer가 2개라면 각 Consumer가 여러 partition을 맡아 처리하므로 Lag가 쉽게 쌓일 수 있습니다.
확인 기준은 단순합니다.
처리 병렬성의 상한 = partition 수
처리량이 부족하다면 Consumer 수만 늘릴 것이 아니라 partition 수, Consumer concurrency, 메시지 처리 시간을 함께 봐야 합니다.
Spring Kafka를 쓴다면 아래 설정도 확인합니다.
spring:
kafka:
listener:
concurrency: 3
단, concurrency를 무작정 높이면 DB 커넥션, 외부 API rate limit, CPU 사용량이 함께 증가합니다. Consumer만 빠르게 늘리는 방식은 장애를 다른 곳으로 옮길 수 있습니다.
원인 3. 특정 Partition에 메시지가 몰림
Lag가 전체 partition에 고르게 생기지 않고 특정 partition에만 몰린다면 key 설계를 의심해야 합니다.
Kafka는 같은 key를 가진 메시지를 같은 partition으로 보냅니다. 주문 ID, 사용자 ID, 회사 ID처럼 특정 값이 지나치게 많이 들어오면 한 partition만 바빠집니다.
확인 방법은 Consumer Group 출력에서 partition별 Lag를 비교하는 것입니다.
PARTITION 0 LAG 10
PARTITION 1 LAG 12
PARTITION 2 LAG 153420
이런 형태라면 Consumer 수를 늘려도 큰 효과가 없습니다. 병목 partition은 여전히 하나의 Consumer만 처리하기 때문입니다.
해결 방법은 key 분산 전략을 바꾸거나, 토픽을 목적별로 분리하거나, 메시지 처리량이 큰 key를 별도 경로로 분리하는 것입니다.
원인 4. Offset Commit 전략 문제
Consumer가 메시지를 처리했는데 offset commit이 늦거나 실패하면 Lag가 줄지 않습니다.
반대로 offset을 너무 빨리 commit하면 장애 시 메시지 유실처럼 보이는 문제가 생길 수 있습니다.
운영에서는 아래 기준을 권장합니다.
- 처리 성공 후 commit
- 실패 시 재시도 횟수 제한
- 반복 실패 메시지는 DLQ로 이동
- auto commit은 처리 보장이 중요한 업무에서 신중히 사용
Spring Kafka에서는 manual ack 방식을 검토할 수 있습니다.
@KafkaListener(topics = "order-events", groupId = "order-worker")
public void consume(OrderEvent event, Acknowledgment ack) {
try {
orderService.process(event);
ack.acknowledge();
} catch (Exception e) {
throw e;
}
}
원인 5. Broker 또는 네트워크 문제
Consumer 코드가 정상이더라도 Broker 상태가 나쁘면 Lag가 증가합니다.
다음 항목을 함께 확인합니다.
- Broker CPU, Disk I/O, Network I/O
- Under Replicated Partition
- ISR 감소
- GC pause
- Controller 변경 빈도
- Consumer와 Broker 사이 네트워크 지연
운영 장애에서는 Consumer Lag만 보면 안 됩니다. Broker 지표와 애플리케이션 지표를 같이 봐야 원인을 빠르게 좁힐 수 있습니다.
장애 대응 순서
실제 운영에서는 아래 순서로 대응하면 좋습니다.
1. Consumer Group의 partition별 Lag를 확인합니다. 2. Lag가 전체적으로 증가하는지 특정 partition만 증가하는지 구분합니다. 3. Consumer 로그에서 처리 오류, 재시도, 외부 API 지연을 확인합니다. 4. DB 커넥션, API 응답 시간, thread pool 사용률을 확인합니다. 5. Broker 지표와 네트워크 지표를 확인합니다. 6. 임시 대응으로 Consumer 인스턴스 또는 concurrency를 조정합니다. 7. 근본 대응으로 batch 처리, DLQ, key 분산, partition 재설계를 검토합니다.
운영 체크리스트
체크 항목정상 기준
| Lag 추세 | 일시 증가 후 감소 |
| partition별 Lag | 특정 partition만 과도하게 높지 않음 |
| Consumer 처리 시간 | 평소 대비 급증하지 않음 |
| 실패 메시지 | 무한 재시도하지 않음 |
| DB/API 지연 | Consumer 처리량을 막지 않음 |
| commit 전략 | 처리 성공 기준으로 commit |
| 알림 | Lag 임계치 초과 시 알림 발생 |
FAQ
Consumer 수를 늘리면 Lag가 바로 줄어드나요?
항상 그렇지는 않습니다. partition 수가 병렬 처리의 상한이기 때문에 Consumer 수가 partition 수보다 많으면 추가 Consumer는 일을 하지 못합니다.
Lag가 0이어야 정상인가요?
항상 0일 필요는 없습니다. 트래픽이 순간적으로 늘면 Lag는 생길 수 있습니다. 중요한 것은 Lag가 줄어드는 추세인지, 계속 증가하는지입니다.
특정 partition에만 Lag가 쌓이면 어떻게 해야 하나요?
key 분산 문제일 가능성이 큽니다. Consumer 수를 늘리기보다 메시지 key 설계, partition 수, 토픽 분리 전략을 먼저 봐야 합니다.
관련 글로 연결할 주제
- Spring Boot Kafka Consumer 설정 실무 정리
- Kafka 메시지 중복 처리 방지 패턴
- Airflow와 Kafka를 함께 쓸 때 장애 포인트
- ELK로 Kafka Consumer Lag 모니터링하기
- 운영 장애 보고서 작성법
함께 보면 좋은 운영·기술 글
- 1편 — 금융권은 왜 하둡을 쓰는가: 도입 배경과 진화
- 2편 — 하둡 구성도: HDFS·YARN·Hive·Spark 운영 흐름
- 3편 — 운영 자동화 스크립트 모음 (금융권 표준)
- 4편 — 하둡 보안 아키텍처: 계정·권한·감사·데이터 보호
- 5편 — Job Template·배포 체계 표준화
- 6편 — Hadoop + Kafka 실시간 분석 아키텍처
- 7편 — 클러스터 운영 체계: 폐쇄망·보안·권한 관리
- 8편 — Sqoop·Oozie·Spark Batch 적재 파이프라인
- 9편 — 실사용 ①: 신용평가 / 여신 리스크 모델링
- 10편 — 실사용 ②: FDS 이상거래탐지 로그 분석
'트러블슈팅 & 장애 대응' 카테고리의 다른 글
| Kubernetes Pod Pending 해결 가이드 — 리소스·Taint·Affinity·PVC 원인별 점검 (0) | 2026.08.10 |
|---|---|
| Kubernetes ImagePullBackOff 해결 가이드 — 이미지·인증·네트워크 원인별 점검 (0) | 2026.08.09 |
| Kubernetes CrashLoopBackOff 해결 가이드 — 로그·이벤트·Probe·OOM 점검 (0) | 2026.07.26 |