[Kafka Study] Eager/Cooperative Rebalance & Static Group Membership

Created
Sep 17, 2023
Created by
Tags
Kafka
Property
 
학습 자료
 
 

 
 

Rebalance

  • 토픽 내 파티션을 컨수머에게 재할당 하는 것을 ‘리밸런싱’ 이라고 한다.
  • 리밸런싱은 기본적으로 컨수머 그룹의 가용성(availability)과 규모 가변성(scalability)을 제공하지만, 전략에 따라 오히려 가용성과 규모 가용성을 저해하기도 한다.
  • 리밸런싱은 아래 상황에서 발생한다.
    • 토픽 내 파티션을 새로 추가할 때.
    • 컨수머 그룹 내에 신규 컨수머를 추가할 때.
    • 컨수머 그룹 내에 일부 컨수머가 종료/크래시 되었을 때.
 

Eager Rebalance

  • eager rebalancing 하는 도중에는 컨수머그룹 내 모든 컨수머들이 메세지 읽기를 멈추고 파티션 멤버십도 포기한다. (called 'stop the world' event)
  • eager rebalancing 완료되고 나면 컨수머들은 이전에 할당 받았던 파티션과 다른 파티션을 새로 할당받게 된다.
  • 컨수머들이 메세지 읽기 작업을 멈췄다가 파티션을 재할당 받기까지 걸리는 시간(다운타임)은 컨수머그룹의 규모가 클수록 길어진다. → 운영에서 안 쓸거 같다.
 
notion image
 
위 그림은 모든 컨수머들이 컨수머그룹에 탈퇴하고 나서 파티션을 재할당 받는 과정을 나타낸다.
  1. 컨수머들은 그룹 코디네이터에게 JoinGroup 요청을 보낸다. (컨수머 → 그룹 코디네이터 갈색 화살표) 이 때, 컨수머들 중에 가장 먼저 조인한 컨수머가 리더가 된다. (위 그림에서는 C가 리더가 될 것.)
  1. 그룹 코디네이터는 컨수머들에게 JoinGroup 요청에 대한 응답을 보내는데, 리더에게는 응답에 컨수머 목록을 포함하여 전달한다. (그룹 코디네이터 → 컨수머 갈색 화살표)
  1. 리더는 그룹 코디네이터로부터 받은 컨수머 목록을 기반으로 어느 컨수머에게 어느 파티션을 할당할지 결정한다.
    1. synchronization barrier : 파티션들을 재할당하는 시점에 파티션들은 모두 멤버십이 포기되어 있어야 함을 나타낸다.
  1. 컨수머들이 그룹 코디네이터에게 SyncGroup 요청을 보낸다. 리더는 SyncGroup 요청에 할당 결과를 포함하여 전달한다.(컨수머 → 그룹 코디네이터 노란색 화살표)
  1. 그룹 코디네이터는 리더로부터 받은 파티션 할당 결과를 SyncGroup 에 대한 응답에 포함하여 보낸다. (그룹 코디네이터 → 컨수머 노란색 화살표)
 

Cooperative Rebalance

  • 3.1 버전 이후로 디폴트로 쓰인다.
  • 토픽 내 일부 파티션만 기존 컨수머에서 다른 컨수머에게 재할당한다.
  • 다른 컨수머들은 리밸런싱에 방해받지 않고 기존에 할당받은 파티션에서 메세지를 읽는 작업을 유지한다.
  • cooperative rebalancing 과정은 아래와 같다.
      1. 컨수머그룹 내 리더가 다른 컨수머들에게 리밸런싱 한다고 통보한다.
      1. 리더에게 통보를 받고 나면 다른 컨수머들은 메세지를 읽고 있었던 파티션에 대한 멤버십을 포기한다.
      1. 컨수머그룹 내 리더는 파티션들을 재할당한다.
 
 
notion image
위 그림은 컨수머들이 리밸런싱 통보를 받고 나서 컨수머 A 가 멤버십을 갖고 있었던 3번 파티션을 C에게 재할당하는 과정을 나타낸다.
 
1st rebalance
  1. 컨수머들은 자기가 어느 파티션을 소유하고 있는지에 대한 정보를 포함하여 그룹 코디네이터에게 JoinGroup 요청을 보낸다.
  1. 그룹 코디네이터는 컨수머들에게 JoinGroup 에 대한 응답을 보내는데, 리더에게는 컨수머들의 파티션 멤버십 정보를 포함하여 응답을 보낸다.
  1. 컨수머들은 그룹 코디네이터에게 SyncGroup 요청을 보내는데, 리더는 컨수머 A 에게 3번 파티션 멤버십을 회수한다는 정보를 포함하여 요청한다.
  1. 그룹 코디네이터는 A 에게 3번 파티션을 제외한다는 정보를 포함하여 SyncGroup 에 대해 응답한다.
    1. synchronization barrier : 3번 파티션의 멤버십이 포기되어 있어야 함을 나타낸다.
2nd rebalance
  1. 컨수머들은 자기가 어느 파티션을 소유하고 있는지에 대한 정보를 포함하여 코디네이터에게 JoinGroup 요청을 보낸다 .(A의 파티션 멤버십 정보에는 3번 파티션이 없을 것.)
  1. 그룹 코디네이터는 JoinGroup 에 대해 응답한다.
  1. 컨수머들이 SyncGroup 요청을 보내는데, 리더 컨수머는 C 에게 3번 파티션을 할당한다는 정보를 포함하여 요청한다.
  1. 그룹 코디네이터는 C 에게 3번 파티션이 할당되었다는 정보를 포함하여 SyncGroup 에 대해 응답한다.
 
 

Partition Assignor

  • 리더 컨수머가 어느 파티션을 어느 컨수머에게 할당할지 결정할 때 쓰인다.
  • Range, RoundRobin, Sticky 방식은 eager 리밸런싱을 일으킨다.

레인지 (Range)

  • 무조건 고정된 파티션 묶음을 특정 컨수머에게 할당한다.
    • ex) 어떤 컨수머그룹이 구독하는 a, b, c 토픽에 각각 파티션이 3개 있다면 0~1 번 파티션은 무조건 컨수머 A 에게, 2번 파티션은 컨수머 B 에게 할당.
  • 파티션 재할당 계산에 의한 지연시간은 적겠지만 특정 컨수머에게 파티션이 치중될 수 있다.

라운드-로빈 (Round Robin)

  • 모든 토픽의 파티션들을 가져다 순차적으로 컨수머에게 돌아가며 할당한다.
  • 레인지 전략에 비해 컨수머에게 균등하게 파티션을 할당할 수 있다.
  • 컨수머 그룹의 규모가 크다면 재할당 계산 비용이 많이 발생할 수 있다.

스티키 (Sticky)

  • 컨수머들에게 최대한 균등하게 파티션을 할당하면서, 재할당 계산 비용을 최대한 줄이는 걸 목표로 한다.
  • 처음에 컨수머그룹을 생성할 때 라운드-로빈 방식으로 파티션을 할당하지만, 리밸런싱이 일어나면 기존 컨수머들의 파티션 멤버십에 최대한 변화를 주지 않고 재할당이 일어나도록 한다.
  • 하지만 eager 리밸런싱을 일으켜서 컨수머들이 메세지 읽기 작업을 멈추기 때문에 다운타임이 생긴다는 단점이 있다.

코퍼레티브 스티키 (CooperativeSticky)

  • Sticky 방식의 단점을 보완한 방식으로, cooperative 리밸런싱을 통해 다운타임을 개선한다.
 
 

Static Group Membership

  • static group membership 은 리밸런싱이 의도하지 않게 자주 발생하는 것을 개선한다.
  • 컨수머가 그룹 코디네이터에게 heartbeat 를 보내지 않으면 그룹 코디네이터는 기본적으로 컨수머가 죽은 것으로 간주하고 리밸런싱을 한다. 죽었다고 간주된 컨수머는 컨수머그룹에서 탈퇴된 후 재가입 했을 때 새로운 멤버 ID 를 발급받으며, 어떤 파티션 어사이너를 쓰는지에 따라 이전에 소유했던 파티션과 다른 파티션을 할당 받을 수 있다.
  • 하지만 컨수머에게 static group membership 을 부여하면 (group.instance.id 를 지정하면) 컨수머의 heartbeat 주기가 잠깐 멈추더라도 (혹은 정말로 죽었다가 살아돌아와도) 그룹 코디네이터는 컨수머를 컨수머그룹에서 탈퇴시키지 않고 리밸런싱도 발생하지 않는다. (리밸런싱이 발생하지 않는다는 건 파티션 재할당이 일어나지 않고 파티션의 멤버십이 해당 컨수머에게 유지된다는 뜻이다.)
  • static group membership 을 유지하는 기간은 session.timeout.ms 설정에 의존한다. 즉, session.timeout.ms 내에 컨수머가 heartbeat 를 보내지 않으면 컨수머그룹에서 탈퇴되고 리밸런싱이 일어난다.
  • static group membership 은 컨수머가 파티션으로부터 읽은 메세지를 가지고 캐시를 생성하는 데에 시간이 오래걸리거나, k8s 환경에서 rolling out 배포 방식을 사용할 때 유용하다.