목차
[Range]
Consumer를 브로커가 할당한 member_id 를 사용하여 사전순으로 배치하고, 이를 파티션 숫자 순서대로 할당.
ex) consumer 3개가 있고, 2개 토픽이 각각 파티션 2개,2개를 갖고 있다면 아래처럼 할당된다.
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P0 |
C1 | T0P1, T1P1 |
C2 | 유휴 |
만약 토픽별로 파티션 개수의 편차가 크다면 뒤에 있는 Consumer들은 유휴상태로 남아있는다.
[Round-Robin]
순서대로 할당하는 방식.
마찬가지로 member_id를 사용하여 사전순으로 배치하긴 한다.
ex) consumer 3개가 있고, 2개 토픽이 각각 파티션 2개,2개를 갖고있다면
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1 |
C1 | T0P1 |
C2 | T1P0 |
만약 토픽별로 파티션 개수 편차가 크더라도 순서대로 consumer에 할당되기 때문에 유휴 consumer가 그만큼 줄어들게 된다.
But Consumer가 제외되는 상황일 때 전체를 재할당하므로 리소스 낭비가 있다고 한다.
static membership이 도입된 이후 member.id를 기반으로 파티션 할당을 정적으로 할당할 수도 있다고 한다.
예제1. 균형 상황 (Consumer가 동일한 토픽을 구독하는 경우)
Consumer - C0,C1
Topic(Partiton Count) - T0(3), T1(3)
Partiton - T0P0, T0P1, T0P2, T1P0, T1P1, T1P2 - 6개
이 상황에서는 아래와 같이 배치
Consumer | Assigned Topic Partitions |
C0 | T0P0, T0P2, T1P1 |
C1 | T0P1, T1P0, T1P2 |
예제2. 불균형 상황 (C2 Consumer만 T2토픽을 구독하는 경우)
Consumer - C0, C1, C2
Topic(Partiton Count) - T0(1), T1(2), T2(3)
Partiton - T0P0, T1P0,T1P1, T2P0,T2P1,T2P2 - 6개
이 때 C2만 T2를 구독한다고하자. 그러면 Consumer 입장에서 봤을 때 아래처럼 불균형이 일어나게 된다.
Consumer | Assigned Topic Partitions |
C0 | T0P0 |
C1 | T1P0 |
C2 | T1P1, T2P0, T2P1, T2P2 |
요약
Consumer 자원을 고르게 활용할 수 있음.
Consumer가 추가되거나 제거될 때 전체적으로 재할당을 함 (리소스 낭비).
Consumer별로 구독 토픽이 다른경우 Consumer간 불균형을 초래할 수 있음.
→ MoA의 logstash는 Consumer 추가/제거가 매우 빈번할 듯하고, 이 때 파티션 할당과정에서 리소스 낭비가 있을 것 같다.
→ consumer별로 구독 토픽이 다르지는 않을 것이기 때문에 불균형 상황은 발생하지 않을 것 같다.
[Sticky]
참조: https://cwiki.apache.org/confluence/display/KAFKA/KIP-54+-+Sticky+Partition+Assignment+Strategy
도입동기
- Round-Robin의 경우 Range에 비해 Consumer의 활용성을 더 높일 수 있지만 Consumer별로 구독의 차이가 있는 경우 파티션 할당의 불균형이 있을 수 있다.
- 또 재할당이 발생했을 때 기존에 어떤 파티션이 어떤 consumer에게 할당되어 있었는지 고려하지 않아 전체적인 재할당이 발생하게 됨.
- Sticky는 이전에 할당된 정보를 최대한 유지하여 리소스를 절약할 수 있다.
- org.apache.kafka.clients.consumer.StickyAssignor 클래스로 사용가능
변경점
Sticky는 두가지 목적을 가지고 있다.
- 가능한한 균형잡힌 할당을 보장
- 재할당 시 최대한 기존 할당을 유지
가능한한 균형잡힌 할당 보장
- Consumer 별로 할당된 파티션 수는 최대 1만큼 다름을 보장. 예를 들어 consumer B가 A보다 2개이상의 파티션을 할당받은 경우 다음 파티션을 B에게 더 이상 할당하지 않음
- 새로운 할당이 시작될 때 sticky 방식은 최대한 균형잡히게 파티션 할당을 배분한다. 라운드로빈과 비슷하게 느껴질 수 있지만, 재할당 과정에서 기존할당을 유지하려는 속성 때문에 좀 더 균형잡힌 결과를 도출할 수 있다고 한다.
재할당 시 최대한 기존 할당을 유지
- 재할당 시 최대한 기존 할당을 유지하되, 위의 균형잡힌 할당 보장을 위배할 경우 파티션 할당의 재조정이 있을 수 있다. (우선 순위가 균형에 좀 더 초점잡혀 있다)
- Sticky는 아래의 내장 프로토콜을 사용하여 기존 파티션 할당 정보를 유지할 수 있도록하여 Consumer의 In/Out이 발생할 때 기존 파티션 정보를 참조하기 용이하게 한다고 한다.
ProtocolName => "sticky"
ProtocolMetadata => Version Subscription UserData
Version => int16
Subscription => [Topic]
Topic => string
UserData => CurrentAssignments
CurrentAssignments => [Topic [Partition]]
Topic => string
Partition => int32
예제
예제1. Consumer 제거 상황
Consumer 3개와 토픽4개가 있으며 각 토픽은 파티션을 2개씩 가지고 있다. (총8개)
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1, T3P0 |
C1 | T0P1, T2P0, T3P1 |
C2 | T1P0, T2P1 |
위의 상황에서 Consumer2가 제외되었을 때 라운드로빈의 경우 전체 재조정을 수행하여 아래와 같이 된다.
Consumer | Assigned Topic Partitions |
C0 | T0p0, T1P0, T2P0, T3P0 |
C2 | T0P1, T1P1, T2P1, T3P1 |
Sticky의 경우 아래와 같은 결과가 나올 수 있다. 라운드 로빈은 기존 파티션 할당을 3개만 유지했지만 Sticky의 경우 5개를 유지했다.
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1, T3P0, T2P0 |
C2 | T1P0, T2P1, T0P1, T3P1 |
예제2. 불균형 상황
Consumer는 3개가 있고, 토픽도 3개가 있다. 그리고 이 때 토픽은 각각 파티션 1,2,3개씩 가지고 있다. (파티션은 총 6개)
이 때 C0,C1 Consumer는 T0,T1만 구독 C2 Consumer는 모든 토픽을 구독한다.
라운드로빈의 경우 구독불균형으로 아래처럼 배치될 수도 있다.
Consumer | Assigned Topic Partitions |
C0 | T0P0 |
C1 | T1P0 |
C2 | t1p1, t2p0, t2p1, t2p2 |
위는 균형잡히게 배치되지 않았다. 이 때 sticky의 경우 아래처럼 조정된다고 한다.
(C1은 T1 토픽을 구독하므로 T1P1 파티션이 C1으로 재배치 되었다)
Consumer | Assigned Topic Partitions |
C0 | T0P0 |
C1 | T1P0, T1P1 |
C2 | T2P0, T2P1, T2P2 |
이 때, C0 Consumer가 제거되었다고 가정하면, 라운드로빈은 아래처럼 할당한다.
C0가 가지고 있던 t0p0가 C1에 할당된 모습을 볼 수 있다.
(기존 파티션 할당 3개만 유지)
Consumer | Assigned Topic Partitions |
C1 | T0P0, T1P1 |
C2 | T1P0, T2P0, T2P1, T2P2 |
Sticky는 아래처럼 된다고 한다 (기존 파티션5개 유지하면서 좀 더 균형있게 배치)
Consumer | Assigned Topic Partitions |
C1 | T1P0, T1P1, T0P0 |
C2 | T2P0, T2P1, T2P2 |
예제3. Consumer 추가 상황
Consumer 2개와 토픽 2개가 있고, 각 토픽은 파티션 2개를 가지고 있다 (총 파티션4개)
Range와 RR에서 아래처럼 배치될 것이다.
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P0 |
C1 | T0P1, T1P1 |
이 때 Consumer가 새로 투입되었을 때
Range는 아래처럼 계속 유지되어 Consumer를 투입한 효과가 없음
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P0 |
C1 | T0P1, T1P1 |
C2 |
RR의 경우 아래처럼 배치 (파티션 이동이 2개만 유지되었다)
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1 |
C1 | T0P1 |
C2 | T1P0 |
Sticky의 경우 기존 파티션 할당을 3개 유지하였다.
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P0 |
C1 | T0P1 |
C2 | T1P1 |
알고리즘
Sticky에서 Input 값들은 아래와 같다.
- partitonsPerTopic: 토픽에 맵핑된 파티션 정보
- subscriptions: Consumer 구독정보
- currentAssignment: 현재 할당 정보
이를 바탕으로 여러 데이터 구조를 정의하고 관리하는 방식을 취한다고 한다.
- 각 토픽 파티션의 잠재적인 consumer 목록
- 각 consumer가 처리할 수 있는 토픽파티션 목록
- 현재 토픽파티션의 consumer 목록
- 토픽 파티션을 처리할 수 있는 consumer의 정렬
- 토픽 파티션이 할당되지 않아 새로운 consumer 할당이 필요한 토픽파티션 목록
- 현재 할당된 파티션 수에 따른 consumer 목록
- 재할당 가능한 파티션
- 고정 파티션 목록
- 고정 파티션을 변경할 수 없는 consumer의 현재 할당 목록
동작방식
- 더 이상 존재하지 않는 consumer를 제거하여 currentAssignment를 업데이트
- 할당되지 않은 파티션을 남아있는 consumer에게 할당. 이 때 선정되는 consumer기준은 현재 할당 개수가 가장 적은 consumer이다.
- 고정된 토픽파티션을 할당받은 consumer를 찾아 currentAssignment를 업데이트
- 균형 개선을 위해 재할당 할 수 있는 파티션 목록으로부터 다른 Consumer로 이동을 고려 (이는 균형이 잡힐때 까지 계속한다고 한다)
- 4번 과정후에도 전체적으로 균형이 맞지 않는 경우 결론적으로 균형을 못잡았기 때문에 assignment를 다시 원복한다
균형을 맞출 때 원칙
- Consumer간 토픽 파티션 할당수의 차이는 최대 1을 유지해야한다.
- 균형을 판단하는 점수는 모든 Consumer에 할당된 파티션 크기 차이의 합으로 계산한다고 한다. (0점인 경우 완벽하게 균형잡혔다고 여긴다고 한다)
[동일한 상황에서 Round-Robin과 Sticky 비교해보기 ]
위의 예제상황에서 각각 비교해본다
테스트 토픽
토픽 | 파티션 수 |
asmt-test-p1-1 | 1 |
asmt-test-p1-2 | 1 |
asmt-test-p1-3 | 1 |
asmt-test-p2-1 | 2 |
asmt-test-p2-2 | 2 |
asmt-test-p3-3 | 2 |
asmt-test-p4-4 | 2 |
asmt-test-p3-1 | 3 |
asmt-test-p3-2 | 3 |
시나리오1. Consumer 제거상황
Consumer 3개와 토픽4개가 있으며 각 토픽은 파티션을 2개씩 가지고 있다. (총8개)
사용한 커맨드
#Round-Robin
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p2-1|asmt-test-p2-2|asmt-test-p2-3|asmt-test-p2-4' \
--group asmt-s1-rr \
--consumer.config consumer.properties
#Sticky
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p2-1|asmt-test-p2-2|asmt-test-p2-3|asmt-test-p2-4' \
--group asmt-s1-st1 \
--consumer.config consumer.properties
초기 파티션 할당 비교
RRConsumer | Assigned Topic Partitions |
C0 | T0P0, T1P1, T3P0 |
C1 | T0P1, T2P0, T3P1 |
C2 | T1P0, T2P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s1-rr asmt-test-p2-1 0 consumer-asmt-s1-rr-1-0fedfb14-503c-49de-995b-78ab53a9deb0 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-1 1 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-2 0 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-2 1 consumer-asmt-s1-rr-1-0fedfb14-503c-49de-995b-78ab53a9deb0 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-3 0 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-3 1 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-4 0 consumer-asmt-s1-rr-1-0fedfb14-503c-49de-995b-78ab53a9deb0 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-4 1 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
Sticky
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1, T3P0 |
C1 | T0P1, T2P0, T3P1 |
C2 | T1P0, T2P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s1-st1 asmt-test-p2-1 0 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-1 1 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-2 0 consumer-asmt-s1-st1-1-811f8602-646c-4e9e-bb0e-556bf7e53839 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-2 1 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-3 0 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-3 1 consumer-asmt-s1-st1-1-811f8602-646c-4e9e-bb0e-556bf7e53839 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-4 0 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-4 1 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
→ Round-Robin, Sticky 동일하게 배치되었음.
C1제거
RR
Consumer | Assigned Topic Partitions |
C0 | T0P0,T1P0,T2P0,T3P0 |
C2 | T0P1,T1P1,T2P1,T3P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s1-rr asmt-test-p2-1 0 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-1 1 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-2 0 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-2 1 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-3 0 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-3 1 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-4 0 consumer-asmt-s1-rr-1-50150472-63b7-45e1-81cf-2c6968772f53 /172.30.1.4 consumer-asmt-s1-rr-1
asmt-s1-rr asmt-test-p2-4 1 consumer-asmt-s1-rr-1-60f0c68d-5541-47b7-959d-d9aa9283fe05 /172.30.1.4 consumer-asmt-s1-rr-1
→ 기존 할당 3개유지
Sticky
Consumer | Assigned Topic Partitions |
C0 | T0P0,T1P0,T1P1,T3P0 |
C2 | T0P1,T2P0,T2P1,T3P1 |
→ 기존 할당 4개유지
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s1-st1 asmt-test-p2-1 0 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-1 1 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-2 0 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-2 1 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-3 0 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-3 1 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-4 0 consumer-asmt-s1-st1-1-524d1f79-b891-4cc9-a3be-3ed4c63deb10 /172.30.1.4 consumer-asmt-s1-st1-1
asmt-s1-st1 asmt-test-p2-4 1 consumer-asmt-s1-st1-1-67b1c371-9557-44da-b65b-01d78da2c402 /172.30.1.4 consumer-asmt-s1-st1-1
시나리오2. 불균형 상황
Consumer는 3개가 있고, 토픽도 3개가 있다. 그리고 이 때 토픽은 각각 파티션 1,2,3개씩 가지고 있다. (파티션은 총 6개)
이 때 C0,C1 Consumer는 T0,T1만 구독 C2 Consumer는 모든 토픽을 구독한다.
사용한 커맨드
#RR
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p1-1|asmt-test-p2-1' \
--group asmt-s2-rr \
--consumer.config consumer.properties
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p1-1|asmt-test-p2-1|asmt-test-p3-1' \
--group asmt-s2-rr \
--consumer.config consumer.properties
#Sticky
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p1-1|asmt-test-p2-1' \
--group asmt-s2-st3 \
--consumer.config consumer.properties
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p1-1|asmt-test-p2-1|asmt-test-p3-1' \
--group asmt-s2-st3 \
--consumer.config consumer.properties
초기파티션 할당 및 Consumer 추가/제거
RR
Consumer | Assigned Topic Partitions |
C0 | T0P0,T1P1 |
C2 | T1P0 |
C2투입
Consumer | Assigned Topic Partitions |
C0 | T0P0 |
C1 | T1P0 |
C2 | T1P1, T2P0,T2P1,T2P2 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-rr asmt-test-p1-1 0 consumer-asmt-s2-rr-1-6dc59d75-9c8a-4a20-8ca4-5eca9a4d3c30 /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 0 consumer-asmt-s2-rr-1-c766e5ad-82e7-4410-afe8-861be5ee124a /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 1 consumer-asmt-s2-rr-1-6dc59d75-9c8a-4a20-8ca4-5eca9a4d3c30 /172.30.1.4 consumer-asmt-s2-rr-1
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-rr asmt-test-p1-1 0 consumer-asmt-s2-rr-1-6dc59d75-9c8a-4a20-8ca4-5eca9a4d3c30 /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 0 consumer-asmt-s2-rr-1-c766e5ad-82e7-4410-afe8-861be5ee124a /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 1 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 0 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 1 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 2 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
c0 제거
Consumer | Assigned Topic Partitions |
C1 | T1P0,T1P1 |
C2 | T1P0,T2P0,T2P1,T2P2 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-rr asmt-test-p1-1 0 consumer-asmt-s2-rr-1-c766e5ad-82e7-4410-afe8-861be5ee124a /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 0 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p2-1 1 consumer-asmt-s2-rr-1-c766e5ad-82e7-4410-afe8-861be5ee124a /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 0 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 1 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
asmt-s2-rr asmt-test-p3-1 2 consumer-asmt-s2-rr-1-e81e7bc9-abbc-41f9-b3c0-50acdd850aeb /172.30.1.4 consumer-asmt-s2-rr-1
→ 할당 균형이 각각 2개, 4개로 맞지않는 모습
Sticky
C0,C1만 있을 때 RR과 동일하게 배치
Consumer | Assigned Topic Partitions |
C0 | T0P0,T1P1 |
C1 | T1P0 |
C2 투입
Consumer | Assigned Topic Partitions |
C0 | T0P0, T1P1 |
C1 | T1P0 |
C2 | T2P0,T2P1,T2P2 |
#C0, C1만 있을 때
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-st2 asmt-test-p1-1 0 consumer-asmt-s2-st2-1-0aacc653-3b0b-4558-846b-f5be461b67de /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 0 consumer-asmt-s2-st2-1-44938f77-4e3b-4f14-b28f-58a9f0ac9afa /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 1 consumer-asmt-s2-st2-1-0aacc653-3b0b-4558-846b-f5be461b67de /172.30.1.4 consumer-asmt-s2-st2-1
#C2를 투입한 후
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-st2 asmt-test-p1-1 0 consumer-asmt-s2-st2-1-0aacc653-3b0b-4558-846b-f5be461b67de /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 0 consumer-asmt-s2-st2-1-44938f77-4e3b-4f14-b28f-58a9f0ac9afa /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 1 consumer-asmt-s2-st2-1-0aacc653-3b0b-4558-846b-f5be461b67de /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 0 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 1 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 2 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
c0 제거
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0,T1P1 |
C2 | T2P0,T2P1,T2P2 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s2-st2 asmt-test-p1-1 0 consumer-asmt-s2-st2-1-44938f77-4e3b-4f14-b28f-58a9f0ac9afa /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 0 consumer-asmt-s2-st2-1-44938f77-4e3b-4f14-b28f-58a9f0ac9afa /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p2-1 1 consumer-asmt-s2-st2-1-44938f77-4e3b-4f14-b28f-58a9f0ac9afa /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 0 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 1 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
asmt-s2-st2 asmt-test-p3-1 2 consumer-asmt-s2-st2-1-3945f70b-b939-463b-a309-d2cd2c3e41ac /172.30.1.4 consumer-asmt-s2-st2-1
→ 3개씩 균형이 맞추어진 모습 확인
시나리오3. Consumer 추가 상황
Consumer 2개와 토픽 2개가 있고, 각 토픽은 파티션 2개를 가지고 있다 (총 파티션4개)
사용한 커맨드
#Range
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p2-1|asmt-test-p2-2' \
--group asmt-s3-ra \
--consumer.config consumer.properties
#RR
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p2-1|asmt-test-p2-2' \
--group asmt-s3-rr \
--consumer.config consumer.properties
#Sticky
sudo kafka-console-consumer \
--bootstrap-server 172.30.1.35:9092 \
--whitelist 'asmt-test-p2-1|asmt-test-p2-2' \
--group asmt-s3-st \
--consumer.config consumer.properties
초기 파티션 할당 및 Consumer 추가
Range
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0 |
C2 | T0P1,T1P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-ra asmt-test-p2-1 0 consumer-asmt-s3-ra-1-73527aa2-6577-411d-a8a1-a70306d66f7d /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-1 1 consumer-asmt-s3-ra-1-75e63b71-8fa7-462d-82d9-e25b68611863 /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-2 0 consumer-asmt-s3-ra-1-73527aa2-6577-411d-a8a1-a70306d66f7d /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-2 1 consumer-asmt-s3-ra-1-75e63b71-8fa7-462d-82d9-e25b68611863 /172.30.1.4 consumer-asmt-s3-ra-1
Consumer 추가
Consumer가 활용되지 못함
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0 |
C2 | T0P1,T1P1 |
C3 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-ra asmt-test-p2-1 0 consumer-asmt-s3-ra-1-73527aa2-6577-411d-a8a1-a70306d66f7d /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-1 1 consumer-asmt-s3-ra-1-75e63b71-8fa7-462d-82d9-e25b68611863 /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-2 0 consumer-asmt-s3-ra-1-73527aa2-6577-411d-a8a1-a70306d66f7d /172.30.1.4 consumer-asmt-s3-ra-1
asmt-s3-ra asmt-test-p2-2 1 consumer-asmt-s3-ra-1-75e63b71-8fa7-462d-82d9-e25b68611863 /172.30.1.4 consumer-asmt-s3-ra-1
RR
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0 |
C2 | T0P1,T1P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-rr asmt-test-p2-1 0 consumer-asmt-s3-rr-1-cb8ee7cc-3b33-429b-8cca-bd9a26ab2ff0 /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-1 1 consumer-asmt-s3-rr-1-d6cfe5e2-5d1c-4b47-bace-a2ae2a5505cf /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-2 0 consumer-asmt-s3-rr-1-cb8ee7cc-3b33-429b-8cca-bd9a26ab2ff0 /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-2 1 consumer-asmt-s3-rr-1-d6cfe5e2-5d1c-4b47-bace-a2ae2a5505cf /172.30.1.4 consumer-asmt-s3-rr-1
Consumer 추가
기존 파티션 할당 2개 유지
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P1 |
C2 | T0P1 |
C3 | T1P0 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-rr asmt-test-p2-1 0 consumer-asmt-s3-rr-1-4d122389-a10e-4e61-bef1-a7afa7b8a672 /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-1 1 consumer-asmt-s3-rr-1-cb8ee7cc-3b33-429b-8cca-bd9a26ab2ff0 /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-2 0 consumer-asmt-s3-rr-1-d6cfe5e2-5d1c-4b47-bace-a2ae2a5505cf /172.30.1.4 consumer-asmt-s3-rr-1
asmt-s3-rr asmt-test-p2-2 1 consumer-asmt-s3-rr-1-4d122389-a10e-4e61-bef1-a7afa7b8a672 /172.30.1.4 consumer-asmt-s3-rr-1
Sticky
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0 |
C2 | T0P1,T1P1 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-st asmt-test-p2-1 0 consumer-asmt-s3-st-1-55bfd405-2d4f-4a8e-a092-0a5122605b87 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-1 1 consumer-asmt-s3-st-1-72f79d4e-d79f-439f-acd7-b3e9f2b1d595 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-2 0 consumer-asmt-s3-st-1-55bfd405-2d4f-4a8e-a092-0a5122605b87 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-2 1 consumer-asmt-s3-st-1-72f79d4e-d79f-439f-acd7-b3e9f2b1d595 /172.30.1.4 consumer-asmt-s3-st-1
Consumer 추가
기존 파티션 할당 3개 유지
Consumer | Assigned Topic Partitions |
C1 | T0P0,T1P0 |
C2 | T1P1 |
C3 | T1P0 |
GROUP TOPIC PARTITION CONSUMER-ID HOST CLIENT-ID
asmt-s3-st asmt-test-p2-1 0 consumer-asmt-s3-st-1-55bfd405-2d4f-4a8e-a092-0a5122605b87 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-1 1 consumer-asmt-s3-st-1-a89629c4-e347-43fb-89fa-c5b5bc4e9334 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-2 0 consumer-asmt-s3-st-1-55bfd405-2d4f-4a8e-a092-0a5122605b87 /172.30.1.4 consumer-asmt-s3-st-1
asmt-s3-st asmt-test-p2-2 1 consumer-asmt-s3-st-1-72f79d4e-d79f-439f-acd7-b3e9f2b1d595 /172.30.1.4 consumer-asmt-s3-st-1
→ Sticky는 Consumer 추가 상황에서도 Round-Robin에 비해 기존 파티션 할당 정보를 유지하려고 한다.
[CooperativeStickyAssignor]
Apache Kafka 2.5 이상부터 사용가능.
Confluent 공식 문서에 따르면 리밸런싱에 좀 더 협조적이라고 한다.
"Follows the same StickyAssignor logic, but allows for cooperative rebalancing."
StickyAssingnor의 파티션을 최대한 균등하게 할당해주는 특성을 갖음과 동시에 리밸런싱이 발생했을 때 기존의 할당을 유지시켜주는 방식이라고 한다.
무슨말인지 알아야될 것 같으니 문서를 찾아봄.
https://www.confluent.io/en-gb/blog/cooperative-rebalancing-in-kafka-streams-consumer-ksqldb/
https://blog.voidmainvoid.net/473
기존 방식 : 리밸런싱이 일어나면 모든 파티션이 쫓겨난다.
이상적인 방식: 1,2번 파티션은 그대로 처리하게 두고, 3번 파티션만 옮겨가면 되지 않으냐?
하지만 현실에서는 ConsumerA가 파티션3번의 소유권을 언제 포기해야 되는지 알 길이 없다.
무턱대고 기다릴 순 없으니 현재는 전체 파티션의 소유권을 박탈하고 재할당하는 방식을 취하고 있었다라고 설명.
그럼에도 이러한 요구가 계속해서 있었다고 함.
Incremental cooperative rebalancing protocol (증분 협조적 리밸런싱 프로토콜)
증분이니까 변경된거만 바꾸는 프로토콜.
동작방식
- 모든 consumer가 소유한 파티션을 취소하는 대신 구독 정보를 취합하여 코디네이터에게 보냄.
- 코디네이터는 그룹 리더에게 구독정보를 보냄
- 리더는 Assign규칙을 통해 파티션의 새로운 할당 정보를 Consumer들에게 알려줌
- Consumer는 이것을 보고 지금 본인이 갖고 있는 할당 정보와 새롭게 부여 받은 할당 정보를 비교.
- 이전 할당과 새 할당 정보에 기존 파티션이 있다면 그 파티션은 구독 취소하지 않고 계속 수행함.
- 구독 취소된 파티션은 다른 Consumer들에게 새롭게 할당됨
CooperativeSticky를 사용했을 때 효과가 없는 경우
- 새롭게 구독하는 파티션들이 기존 정보와 완전히 다를 때 - RoundRobin과 다를바 없다.
직접해보기
topic: jaeshim-20220804
partitions: 8개
consumer-group: jaeshim-20220804-group
max.poll.records: 1
concurrency: 1
fusion에서 pod 띄워서 구동
메시지 처리 방식
메시지 처리당 sleep 1초부여하여 로그로 확인할 수 있도록 함.
Assignor지정
시나리오
- perf-producer로 메시지 생성
- pod 1개 구동 후 assign 확인
- 메시지 1초마다 1개씩 처리되는 지 확인. 이 pod이 처리하고 있는 파티션번호 확인.
- pod 1개 추가로 구동하는데, 이 때 소유를 유지할 파티션의 메시지 처리를 계속하는지 확인한다.
Perf-test 구동
sudo kafka-producer-perf-test \ --topic jaeshim-20220804 \ --num-records 100000 \ --record-size 1 \ --throughput 10 \ --producer-props acks=1 \ bootstrap.servers=localhost:9092 |
Pod 1개 구동
당연하겠지만 모든 파티션이 구독목록에 추가되었다.
//1개만 띄웠을 때
Assigned partitions: [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2, jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0]
Current owned partitions: []
Added partitions (assigned - owned): [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2, jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0]
Revoked partitions (owned - assigned): []
메시지 처리 로그 확인
메시지 처리당 1초의 sleep을 걸어놓았고, 처리할 때 마다 파티션번호와 오프셋을 찍도록 하였다.
2022-08-04 20:25:57.250 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:25:57.250 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1209
2022-08-04 20:25:58.253 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:25:58.254 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1210
Pod 1개 추가 구동 (총 2개)
#처리중
2022-08-04 20:25:56.244 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1208
2022-08-04 20:25:57.250 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:25:57.250 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1209
2022-08-04 20:25:58.253 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:25:58.254 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1210
#리밸런싱 발생
2022-08-04 20:25:59.254 INFO 1 --- [-20220804-group] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Attempt to heartbeat failed since group is rebalancing
2022-08-04 20:25:59.259 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] (Re-)joining group
#리밸런싱 발생하였지만 메시지를 계속처리중
2022-08-04 20:25:59.260 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:25:59.260 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1211
2022-08-04 20:26:00.261 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Successfully joined group with generation Generation{generationId=60, memberId='jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de', protocol='cooperative-sticky'}
2022-08-04 20:26:00.262 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Finished assignment for group at generation 60: {jaeshim-20220804-0-0642cbe1-aa23-4a02-83fb-35cdffc5617a=Assignment(partitions=[]), jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de=Assignment(partitions=[jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2])}
2022-08-04 20:26:00.263 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Failing OffsetCommit request since the consumer is not part of an active group
#메시지 처리중
2022-08-04 20:26:00.263 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:00.263 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1212
2022-08-04 20:26:00.363 INFO 1 --- [-20220804-group] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Successfully synced group in generation Generation{generationId=60, memberId='jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de', protocol='cooperative-sticky'}
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Updating assignment with
#새로운 그룹 할당 정보. 기존에 처리하던 파티션2번의 소유권을 그대로 갖게 되었다.
Assigned partitions: [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2]
Current owned partitions: [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2, jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0]
Added partitions (assigned - owned): []
Revoked partitions (owned - assigned): [jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0]
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Revoke previously assigned partitions jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer : jaeshim-20220804-group: partitions revoked: [jaeshim-20220804-5, jaeshim-20220804-4, jaeshim-20220804-1, jaeshim-20220804-0]
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Notifying assignor about the new Assignment(partitions=[jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2])
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Adding newly assigned partitions:
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer : jaeshim-20220804-group: partitions assigned: []
2022-08-04 20:26:01.268 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] (Re-)joining group
#메시지 계속 처리중
2022-08-04 20:26:01.270 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:01.270 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1213
2022-08-04 20:26:02.270 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Failing OffsetCommit request since the consumer is not part of an active group
2022-08-04 20:26:02.271 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Failing OffsetCommit request since the consumer is not part of an active group
2022-08-04 20:26:02.271 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:02.272 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1214
2022-08-04 20:26:03.272 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Failing OffsetCommit request since the consumer is not part of an active group
2022-08-04 20:26:03.273 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Successfully joined group with generation Generation{generationId=61, memberId='jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de', protocol='cooperative-sticky'}
2022-08-04 20:26:03.273 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Finished assignment for group at generation 61: {jaeshim-20220804-0-0642cbe1-aa23-4a02-83fb-35cdffc5617a=Assignment(partitions=[jaeshim-20220804-0, jaeshim-20220804-1, jaeshim-20220804-4, jaeshim-20220804-5]), jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de=Assignment(partitions=[jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2])}
2022-08-04 20:26:03.274 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Failing OffsetCommit request since the consumer is not part of an active group
2022-08-04 20:26:03.274 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:03.274 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1215
2022-08-04 20:26:03.374 INFO 1 --- [-20220804-group] o.a.k.c.c.internals.AbstractCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Successfully synced group in generation Generation{generationId=61, memberId='jaeshim-20220804-0-e72257db-e502-4cc5-b002-1a5194cab7de', protocol='cooperative-sticky'}
groupId=jaeshim-20220804-group] Committed offset 1216 for partition jaeshim-20220804-2
2022-08-04 20:26:04.279 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Updating assignment with
#파티션 할당 완료
Assigned partitions: [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2]
Current owned partitions: [jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2]
Added partitions (assigned - owned): []
Revoked partitions (owned - assigned): []
2022-08-04 20:26:04.279 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Notifying assignor about the new Assignment(partitions=[jaeshim-20220804-7, jaeshim-20220804-6, jaeshim-20220804-3, jaeshim-20220804-2])
2022-08-04 20:26:04.279 INFO 1 --- [ntainer#0-0-C-1] o.a.k.c.c.internals.ConsumerCoordinator : [Consumer clientId=jaeshim-20220804-0, groupId=jaeshim-20220804-group] Adding newly assigned partitions:
2022-08-04 20:26:04.279 INFO 1 --- [ntainer#0-0-C-1] o.s.k.l.KafkaMessageListenerContainer : jaeshim-20220804-group: partitions assigned: []
#처리하던 것 계속 처리 중
2022-08-04 20:26:04.282 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:04.282 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1216
2022-08-04 20:26:05.288 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
2022-08-04 20:26:05.289 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : sleep 1 second. partition: 2, offset: 1217
2022-08-04 20:26:06.293 INFO 1 --- [ntainer#0-0-C-1] c.g.b.consumer.listener.BatchListener : recordsCount = 1
결론
- Sticky의 장점은 "같은 그룹 내 구독 정보가 다른 경우에 파티션 할당을 균형있게 하고", "Consumer의 추가/제거 시 최대한 기존 할당을 맞추는 것".
- 만약 같은 그룹 내 Consumer의 구독정보가 모두 동일하다면 전자는 크게 의미가 없을수도 있다.
- Consumer 추가/제거가 빈번하다면 파티션 재할당으로 인한 리소스를 줄이는 것을 기대할 수 있다.
CooperativeStickyAssignor를 활용하면 리밸런싱이 발생했을 때 기존 할당된 파티션 처리를 유지하면서 리밸런싱을 점진적으로 일으킬 수 있는 것 같다.
[참조]
'Kafka > Consumer' 카테고리의 다른 글
Consumer Error Handling Patterns (0) | 2023.05.09 |
---|---|
Kafka Consumer 성능과 고려 요소들 (0) | 2023.04.23 |
Kafka Simple Consumer (0) | 2023.03.03 |
Rebalancing (0) | 2023.03.03 |
Auto Commit 사용시 메시지 유실 테스트 (0) | 2023.02.04 |