[Kafka] Java Kafka Consumer 리밸런싱과 전략

이재민·2024년 2월 24일
0

Kafka

목록 보기
17/17

Kafka Consumer 리밸런싱

컨슈머가 그룹에 합류하거나 나갈때마다 파티션이 컨슈머 사이에서 이동을 하게 되는데, 이를 리밸런싱이라고 합니다.
또한 관리자가 새 파티션을 토픽에 추가하게 되는 경우에도 발생하게 됩니다.

예제 코드는 앞선 kafka Consumer Demo 에서 사용했던 예제 코드를 재사용 하도록 하겠습니다.

다중 인스턴스 허용하기

먼저 intellij 기준으로 아래 Edit Configurations 를 클릭합니다.
Allow multiple instances 를 클릭해줍니다.

이제 2개의 consumer 애플리케이션을 실행해보도록 하겠습니다.

ouput

새로운 consumer 애플리케이션을 실행하기 기존 consumer 애플리케이션에서 아래와 같은 결과를 확인할 수 있습니다.
기존 애플리케이션은 demo_java-1 파티션을 구독하고 있고, 새로운 애플리케이션은 demo_java-2를 구독하고 있는 것을 확인할 수 있습니다.
재밌는 것은 기존 애플리케이션은 demo_java-1, demo_java-2 를 구독하고 있었는데 새로운 consumer를 발견하고 리밸런싱이 이뤄지는 것을 확인할 수 있습니다.

메시지 발행

Producer에서 메시지를 발행하고 결과를 확인해보도록 하겠습니다.
아래 사진과 같이 각자 구독중인 파티션에서의 데이터만 가져오는 것을 확인할 수 있습니다.


리밸런싱 전략

Eager Rebalance

새로운 컨슈머(그림에서 consumer3)가 합류하게 되면 모든 모든 컨슈머의 읽기 작업이 종료되는데, 이를 Eager Reblance(적극적 리밸런싱) 이라고 합니다.
읽기가 진행되는 컨슈머, 파티션이 존재하지 않습니다. 그러면 모든 컨슈머가 이전에 속했던 그룹에 다시 합류해서 새 파티션을 할당받게 됩니다.
이로 인해 전체 컨슈머 그룹이 처리를 멈추게 되어 Stop the world 현상이 발생하게 됩니다.
그리고 컨슈머가 원래 있던 파티션으로 돌아간다는 보장도 없습니다.

Cooperative Rebalance

Cooperative Reblance(협렵적 리밸런싱)는 카프카에서 최근에 나온 전략입니다.
파티션을 작은 그룹으로 나눠서 일부만 한 컨슈머에서 다른 컨슈머로 재할당하는 것입니다. 전체 컨슈머 그룹이 안정적인 할당을 찾을 때 까지 여러 번의 재조정을 거칠 수 있기 때문에 점진적인 리밴런싱이라고도 합니다.

Kafka Consumer에서 리밸런싱 사용하기

partition.assignment.strategy 구성을 여러 값으로 설정할 수 있습니다.

  • RangeAssignor: 토픽 당 파티션을 할당합니다.
  • RoundRobin: 모든 파티션이 모든 토픽에 걸쳐서 할당하는데 공평하게 분배하기 좋습니다.
  • StickyAssignor: 라운드로빈과 같이 균형을 유지하다가, 컨슈머가 그룹에 합류하거나 나갈때 파티션 이동을 최소화합니다.

위 세 전략은 Eager Rebalance 에 속합니다. 때문에 Stop the world 가 발생하고 consumer group을 몇초간 해체하게 됩니다. 컨슈머 그룹이 크다면, 모든 파티션을 할당하는데 시간이 꽤 걸립니다.

CooperativeStickyAssignor

rebalance 전략은 StickyAssignor과 동일하지만, 협력적 재조정을 지원하기 때문에 consumer는 계속해서 해당 topic에서 consume 할 수 있습니다.

Consumer Static Group Membership

기본적으로 컨슈머가 그룹을 떠나면 해당 파티션이 취소되고 다시 할당됩니다. 컨슈머가 다시 합류하게 된다면 새로운 member.id를 갖게되고 앞서 설명한 메커니즘에 따라 새로운 파티션이 할당됩니다.

하지만, group.instance.id 를 정의하게 된다면, consumer는 static member로 동작하게 됩니다. consumer가 떠나고 sessin.timeout,ms 이내에 복귀하게 된다면, 리밸런싱 없이 파티션이 재할당 됩니다.
이는 컨슈머가 로컬 상태와 캐시를 유지할 때(캐시 재구축을 피하기 위해) 재조정을 트리거하지 않고 롤링 재시작을 수행할 때 유용합니다.

코드 확인

컨슈머 애플리케이션을 실행하면 아래 partition.assignment.strategy를 확인할 수 있습니다.
RangeAssignor, CooperativeStickyAssignor를 확인할 수 있는데 RangeAssignor가 우선입니다. 처음 생겼고 모든 컨슈머에 지원하기 때문입니다.

컨슈머 애플리케이션에 설정하는 것은 간단합니다. 기존 consumer property에 아래 그림과 같이 추가 설정을 진행합니다.
애플리케이션을 재시작 후 설정을 확인하면 CooperativeStickyAssignor로 설정된 것을 확인할 수 있습니다.

profile
문제 해결과 개선 과제를 수행하며 성장을 추구하는 것을 좋아합니다.

0개의 댓글