프로젝트/kafka
kafka Consumer 그룹 리밸런싱
Junuuu
2023. 8. 8. 00:01
728x90
Kafka Consumer 그룹 리밸런싱이란?
Kafka Consumer는 토픽의 각 파티션에 대해 메시지를 처리합니다.
하지만 특정 Consumer에 문제가 생겨 더 이상 메시지를 처리할 수 없다면, 파티션의 소유권은 다른 컨슈머에게 이관합니다.
이러한 작업을 리밸런싱이라 합니다.
Kafka Consumer 그룹 리밸런싱은 언제 일어날까?
1. 일반적으로 애플리케이션을 배포하는 상황에서 컨슈머가 생성/삭제되는 과정이 일어나기 때문에 발생합니다.
2. 시간 내에 Poll 요청 실패
3. 컨슈머가 일정시간 내에 하트비트를 보내지 못하는 경우
리밸런싱이 발생하면 어떻게 될까?
- 컨슈머 그룹 전체 메시지 처리 중단(Stop The World)
- 메시지 중복 컨슈밍
- 메시지 손실
실제로 예전에 문자메시지를 발송하는 Consumer에서 리밸런싱이 일어나서 중복된 메시지를 컨슈밍 하여 동일한 고객에게 문자메시지를 계속 발송하는 경우가 발생한 적이 있습니다.
https://junuuu.tistory.com/667
예를 들어 Kafka Consumer의 설정이 다음과 같다고 정의해 보겠습니다.
- enable.auto.commit = true -> poll()을 호출할 때마다 commit 할 시간이 되었는지 확인하여 commit을 수행
- poll을 호출하여 message 500개 중 400개 처리 (auto.commit.interval.ms가 지나서 에러발생) -> commit -> 에러발생으로 100개 메시지 유실
- poll을 호출하여 message를 가져옴 500개중 100개 처리 (auto.commit.interval.ms가 지나기 전에 에러발생) -> offset이 갱신되지 않아 다음 poll때 이미 처리한 100개의 메시지를 가져와서 중복발생
- max.poll.records = 500 -> Consumer가 한 번에 최대 500개만큼 처리함
- max.poll.interval.ms = 5분 -> 설정 시간을 넘기게 되면 컨슈머에 문제가 있다고 판단하여 리밸런싱 발생
다음과 같은 경우 리밸런싱이 발생하면 문제가 발생할 수 있습니다.
- poll을 호출하여 record 500개를 가져옴
- 메시지 500개 처리 중
- 고객에게 메시지 전송이 400개 나감
- 아직 max.poll.interval.ms가 지나지 않음
- 리밸런싱이 발생하고 offset 커밋이 되지 않음
- 다른 컨슈머가 마지막으로 커밋된 메시지부터 처리(중복 처리)
해결 방법
- max.poll.records 값을 작게 설정하여 리밸런싱 시간을 단축시키거나, 리밸런싱 발생 가능성을 감소
- max.poll.records=1으로 설정하여 단일 메시지 단위로 커밋시도
- BATCH, MANUAL 등의 Ack Mode를 적용하여 중복 Consume 가능성 감소
- 중복 메시지 처리 방지 로직을 작성하기 (멱등성을 처리하도록)
- 서비스 중인 컨슈머 개수가 파티션의 개수보다 적을 때 ConcurerntKafkaListener 적용하기
- Producer에서 너무 많은 메시지를 보내지 않도록 조절
max.poll.records 옵션과 성능 이슈
단순 로깅만 하는 Consumer 로직의 1000개 처리시간 테스트
- max.poll.records=1일 때 메시지 하나당 처리시간은 약 25ms
- max.poll.records=500일 때 메세지 하나당 처리시간은 약 0.1ms
서비스에 맞게 조정이 필요할 것 같으며 대부분의 서비스에서 max.poll.records를 1로 설정해도 이슈가 없을 것 같습니다.
참고자료