-
개발환경의 파티션은 어떤 consumer가 점유했을까?프로젝트/kafka 2025. 6. 30. 01:10반응형
개요
만약 kafka의 파티션이 3개이고, consumer가 1개라면 어떤 consumer가 파티션을 점유할까요?
만약 kafka의 파티션이 3개이고, consumer가 2개(로컬환경, 개발환경)라면 어떤 consumer가 파티션을 점유할까요?
추가로 concurrency 옵션은 어떤 관계가 있을까요?
위 질문에 답을 알아가는 과정을 통하여 예측가능한 테스트 환경을 만들 수 있습니다.
Kafka Topic과 Partition

https://www.lydtechconsulting.com/blog-kafka-message-keys.html Kafka는 이벤트의 관심사에 따라 각각 topic에 메시지를 적재합니다.
foo라는 topic이 구성되어 있고 3개의 파티션으로 구성되어 있습니다.
이 파티션에는 kafka consumer가 붙어서 메시지를 처리합니다.
위 구조 덕분에 consumer의 처리량을 늘리고 싶다면 파티션을 증설하고 kafka consumer를 매핑시킬 수 있습니다.
위 그림에서 파티션을 1개 더 늘리게 되면 유휴 kafka consumer 1대가 메시지를 consume 하게 됩니다.
파티션이 3개, consumer가 1개일 때 ( concurrency =1 )

https://www.lydtechconsulting.com/blog-kafka-message-keys.html concurrency 옵션은 애플리케이션 인스턴스 내에서 동시에 실행할 KafkaConsumer 수를 의미합니다.
기본적으로 1로 할당되며 만약 concurrency를 3으로 할당하면 각각의 consumer가 파티션을 1개씩 맡아 병렬로 처리하게 됩니다.
위 상황을 개발 환경의 consumer로 대입해서 생각해 보면 개발 환경의 consumer 1개가 파티션 3개의 메시지를 잘 처리하고 있을 겁니다.
파티션이 3개이고, consumer가 2개일 때(concurrency = 1)

https://developer.confluent.io/courses/architecture/consumer-group-protocol/ consumer 2를 개발환경이라고 생각하고, 로컬환경에서 consumer1을 구동했다고 가정해 보겠습니다.
그런 경우 위 그림처럼 파티션 3개가 2개, 1개로 consumer에게 할당되게 됩니다. (range assignor라고 가정)
만약 로컬환경의 consumer1에 파티션이 2개가 할당되고, 개발환경의 consumer 2에 파티션에 1개가 할당되었다면 로컬환경에서 consumer1을 테스트해보고 싶은데 topic에 메시지를 발행했을 때 파티션 3으로 발행된다면 개발환경의 consumer2 가 동작하게 되며 의도한 테스트를 할 수 없습니다.
왜 이런 일이 발생하는 걸까요?
Range Assignor 동작과정
range assignor의 동작과정을 이해하면 위의 상황을 이해할 수 있습니다.
kafka에서는 여러개의 consumer가 존재할 때 Partition Assignor를 통해 consumer가 어떤 파티션을 처리할지 정해집니다.
이때 별다른 설정이 없다면 기본적으로 range assignor가 활용됩니다.
range assignor는 consumer id를 사전순으로 정렬하고 파티션을 균등하게 범위를 나누어 consumer에 할당합니다.
이때 파티션 수를 소비자 수로 나누고 균등하게 분배합니다.
총 파티션 수 = 3, Consumer 수 = 2 인경우
- Consumer 당 기본 할당 개수 = 3 / 2 = 1
- 남는 파티션: 3 % 2 = 1 → 사전순 앞 consumer가 추가 1개 더 가짐
분배 결과
consumer-A partition-0, partition-1 consumer-B partition-2 총 파티션 수 = 5, Consumer 수 = 3 인경우
- Consumer 당 기본 할당 개수 = 5 / 3 = 1
- 남는 파티션: 5 % 3 = 2개 → 앞에서부터 한 개씩 추가로 할당
분배 결과
consumer-A 2개 partition-0, partition-1 consumer-B 2개 partition-2, partition-3 consumer-C 1개 partition-4 파티션이 5개이고, consumer가 2개일 때(concurrency = 5)
concurrency 옵션은 애플리케이션 인스턴스 내에서 동시에 실행할 KafkaConsumer 수를 의미합니다.
concurrency를 5로 설정하게 되면 KafkaConsumer 수가 5개가 되고 consumer id도 5개가 됩니다.
consumer A의 concurrency가 5이고, consumer B의 concurrency는 1일 때
총 Consumer 수
- App A: 5개 (appA-consumer-0 ~ appA-consumer-4)
- App B: 1개 (appB-consumer-0)
- → 총 6개
파티션 수 = 5, Consumer 수 = 6
- → 5 / 6 = 0 → 파티션 5개 모두 사전순 상위 5명에게 1개씩 할당
- 하위 1명은 idle 상태
consumer A의 concurrency가 5이고, consumer B의 concurrency는 1일 때
appA-consumer-0 partition-0 appA-consumer-1 partition-1 appA-consumer-2 partition-2 appA-consumer-3 partition-3 appA-consumer-4 partition-4 appB-consumer-0 없음 (idle) 모든 파티션을 App A가 점유하고, App B는 메시지를 전혀 소비하지 않습니다.
consumer A의 concurrency가 1이고, consumer B의 concurrency는 5일 때
appA-consumer-0 partition-0 appB-consumer-0 partition-1 appB-consumer-1 partition-2 appB-consumer-2 partition-3 appB-consumer-3 partition-4 appB-consumer-4 없음 (idle) 총 5개의 파티션이 앞에서부터 1개씩 차례로 할당되며, 마지막 consumer 1명은 할당을 못 받아 idle 상태가 됩니다.
예측 가능한 테스트 환경 만들기
range assignor의 동작과정을 학습했으니 위 문제를 해결해볼 수 있습니다.
로컬환경의 Consumer ID는 의도적으로 prefix에 00을 넣어주어 사전순으로 당기고 concurrency를 파티션 개수보다 많게 설정하게 되면 로컬환경의 consumer가 실행될 때 리밸런싱이 일어나게 되고 range assignor에 의해 모든 파티션을 가져와 로컬환경의 consumer가 처리하게 됩니다.
이제 새롭게 개발한 로직으로 메시지가 consume 되어 예측가능한 테스트 환경을 만들어낼 수 있습니다.
'프로젝트 > kafka' 카테고리의 다른 글
우리는 왜 spring kafka batch listener를 활용하지 않나요? (0) 2024.12.01 spring kafka auto-commit 동작원리 : 데이터 유실과 중복처리 (6) 2024.10.13 Kafka Consumer를 On Off 할 수 있을까? (1) 2023.11.26 Kafka Binder란 무엇인가? (0) 2023.11.21 Dead Letter Queue란 무엇인가? (0) 2023.11.16