프로젝트/kafka

kafka Consumer 그룹 리밸런싱

Junuuu 2023. 8. 8. 00:01
728x90

Kafka Consumer 그룹 리밸런싱이란?

https://jhleed.tistory.com/179

Kafka Consumer는 토픽의 각 파티션에 대해 메시지를 처리합니다.

하지만 특정 Consumer에 문제가 생겨 더 이상 메시지를 처리할 수 없다면, 파티션의 소유권은 다른 컨슈머에게 이관합니다.

이러한 작업을 리밸런싱이라 합니다.

 

Kafka Consumer 그룹 리밸런싱은 언제 일어날까?

1. 일반적으로 애플리케이션을 배포하는 상황에서 컨슈머가 생성/삭제되는 과정이 일어나기 때문에 발생합니다.

2. 시간 내에 Poll 요청 실패

3. 컨슈머가 일정시간 내에 하트비트를 보내지 못하는 경우

 

 

리밸런싱이 발생하면 어떻게 될까?

  • 컨슈머 그룹 전체 메시지 처리 중단(Stop The World)
  • 메시지 중복 컨슈밍
  • 메시지 손실

 

실제로 예전에 문자메시지를 발송하는 Consumer에서 리밸런싱이 일어나서 중복된 메시지를 컨슈밍 하여 동일한 고객에게 문자메시지를 계속 발송하는 경우가 발생한 적이 있습니다.

https://junuuu.tistory.com/667

 

SMS 메시지 중복 발송(kafka 메시지 중복 발행)

개요 무료 구독은 만료되면 자동으로 유료로 전환됩니다. 이때 아직 구독 취소를 하지 않은 사용자에게 3일 전에 알림을 주기 위해 메시지를 발송하는 로직이 존재했습니다. 어느 날, 메시지 발

junuuu.tistory.com

 

예를 들어 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로 설정해도 이슈가 없을 것 같습니다.

 

 

참고자료

https://techblog.gccompany.co.kr/%EC%B9%B4%ED%94%84%EC%B9%B4-%EC%BB%A8%EC%8A%88%EB%A8%B8-%EA%B7%B8%EB%A3%B9-%EB%A6%AC%EB%B0%B8%EB%9F%B0%EC%8B%B1-kafka-consumer-group-rebalancing-5d3e3b916c9e

https://access.redhat.com/documentation/ko-kr/red_hat_amq_streams/2.3/html/kafka_configuration_tuning/avoiding_data_loss_or_duplication_when_committing_offsets

https://pula39.tistory.com/19

 

Kafka의 Auto Commit 에서 Auto는 당신이 생각하는 Auto가 아닐 수 있다.

환경설정을 할 때 auto라는 키워드가 나오면 작업자는 날먹을 꿈꾸며 행복해지는 한 편, 이 auto가 어디까지 자동으로 해주고 어디까지는 안해주는지 공포에 떨며 작업을 하게 된다. 나에게 kafka의

pula39.tistory.com