Kafka/Consumer

Consumer Assignment Strategies

재심 2023. 2. 4. 23:46

목차

    [Range]

    Consumer를 브로커가 할당한 member_id 를 사용하여 사전순으로 배치하고, 이를 파티션 숫자 순서대로 할당.

    ex) consumer 3개가 있고, 2개 토픽이 각각 파티션 2개,2개를 갖고 있다면 아래처럼 할당된다.

     

    Consumer Assigned Topic Partitions
    C0 T0P0, T1P0
    C1 T0P1, T1P1
    C2 유휴

     

    만약 토픽별로 파티션 개수의 편차가 크다면 뒤에 있는 Consumer들은 유휴상태로 남아있는다.

     

    [Round-Robin]

    참조: https://kafka.apache.org/24/javadoc/org/apache/kafka/clients/consumer/RoundRobinAssignor.html#:~:text=The%20round%20robin%20assignor%20lays,partitions%20will%20be%20uniformly%20distributed

    순서대로 할당하는 방식.

    마찬가지로 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는 두가지 목적을 가지고 있다. 

    1. 가능한한 균형잡힌 할당을 보장
    2. 재할당 시 최대한 기존 할당을 유지

     

    가능한한 균형잡힌 할당 보장

    • 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의 현재 할당 목록

     

    동작방식

    1. 더 이상 존재하지 않는 consumer를 제거하여 currentAssignment를 업데이트
    2. 할당되지 않은 파티션을 남아있는 consumer에게 할당. 이 때 선정되는 consumer기준은 현재 할당 개수가 가장 적은 consumer이다.
    3. 고정된 토픽파티션을 할당받은 consumer를 찾아 currentAssignment를 업데이트
    4. 균형 개선을 위해 재할당 할 수 있는 파티션 목록으로부터 다른 Consumer로 이동을 고려 (이는 균형이 잡힐때 까지 계속한다고 한다)
    5. 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

    초기 파티션 할당 비교

    RR
    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-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

     

    기존 방식 : 리밸런싱이 일어나면 모든 파티션이 쫓겨난다. 

    Confluent

    이상적인 방식: 1,2번 파티션은 그대로 처리하게 두고, 3번 파티션만 옮겨가면 되지 않으냐?

    Confluent

     

    하지만 현실에서는 ConsumerA가 파티션3번의 소유권을 언제 포기해야 되는지 알 길이 없다.

    무턱대고 기다릴 순 없으니 현재는 전체 파티션의 소유권을 박탈하고 재할당하는 방식을 취하고 있었다라고 설명.

    그럼에도 이러한 요구가 계속해서 있었다고 함.

     

    Incremental cooperative rebalancing protocol (증분 협조적 리밸런싱 프로토콜) 

     

    Confluent

     

    증분이니까 변경된거만 바꾸는 프로토콜. 

    동작방식 

    • 모든 consumer가 소유한 파티션을 취소하는 대신 구독 정보를 취합하여 코디네이터에게 보냄.
    • 코디네이터는 그룹 리더에게 구독정보를 보냄
    • 리더는 Assign규칙을 통해 파티션의 새로운 할당 정보를 Consumer들에게 알려줌
    • Consumer는 이것을 보고 지금 본인이 갖고 있는 할당 정보와 새롭게 부여 받은 할당 정보를 비교. 
    • 이전 할당과 새 할당 정보에 기존 파티션이 있다면 그 파티션은 구독 취소하지 않고 계속 수행함.
    • 구독 취소된 파티션은 다른 Consumer들에게 새롭게 할당됨

     

    Confluent

    CooperativeSticky를 사용했을 때 효과가 없는 경우

    • 새롭게 구독하는 파티션들이 기존 정보와 완전히 다를 때 - RoundRobin과 다를바 없다.

     

    직접해보기

    topic: jaeshim-20220804

    partitions: 8개

    consumer-group: jaeshim-20220804-group

    max.poll.records: 1 

    concurrency: 1

    fusion에서 pod 띄워서 구동 

     

    메시지 처리 방식

    메시지 처리당 sleep 1초부여하여 로그로 확인할 수 있도록 함.

    Assignor지정

     

    시나리오

    1. perf-producer로 메시지 생성
    2. pod 1개 구동 후 assign 확인
      1. 메시지 1초마다 1개씩 처리되는 지 확인. 이 pod이 처리하고 있는 파티션번호 확인.
    3. 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를 활용하면 리밸런싱이 발생했을 때 기존 할당된 파티션 처리를 유지하면서 리밸런싱을 점진적으로 일으킬 수 있는 것 같다. 

     

     

    [참조]

    https://medium.com/streamthoughts/understanding-kafka-partition-assignment-strategies-and-how-to-write-your-own-custom-assignor-ebeda1fc06f3

     

    Understanding Kafka partition assignment strategies and how to write your own custom assignor

    Kafka Clients allows you to implement your own partition assignment strategies for consumers. This can be very useful to adapt to specific

    medium.com

     

    '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