Kafka/Kafka

Kafka: Static Membership

Zayson 2024. 11. 3. 17:35

서론


Kafka Consumer는 여러 가지 이벤트를 통해 리밸런싱이 발생한다.

  • Consumer ↔ GroupCoordinator 간 session.timeout.ms 내에 Heartbeat가 수신되지 않은 경우
  • Consumer가 Consumer Group을 나가거나 들어오는 경우
  • Consumer Group이 구독하는 토픽의 파티션이 추가되는 경우 등

Consumer는 리밸런싱이 시작되면 완료되기 전까지 데이터를 처리하지 못한다. 이로 인해 데이터 처리가 일시 중단되며 지연이 발생한다.

또한, 리밸런싱 과정에서 파티션을 Revoke/Assign 하는 과정에서 네트워크 부하 등으로 인한 클러스터 성능 저하가 발생한다.

 

Kafka 2.3.0부터는 이러한 리밸런싱의 단점을 보완하기 위해 Static Membership이라는 메커니즘이 도입되었다.

Consumer Group Membership Strategy


Kafka의 Consumer Group Membership에는 다음 2가지 방식이 있다.

  1. Dynamic Membership
  2. Static Membership

 

Static Membership리밸런싱 횟수를 줄이고자 KIP-345에서 제안되어 Kafka 2.3.0에 도입됐다.

Dynamic Membership

Consumer Group에 속한 각 Consumer는 member.id라는 고유 ID를 부여받는다.

Dynamic Membership 에서는 각 Consumer가 Consumer Group에 참여할 때마다 새로운 member.id가 발급된다.

따라서, GroupCoordinator는 Consumer Group에 새로 참여하는 모든 Consumer를 새로운 Consumer로 인식하게 된다.

 

예를 들어, Consumer Group에 속한 특정 Consumer에게 잠깐의 순단이 발생했다고 가정해보자.

Consumer는 고유한 멤버 ID를 갖고 있으며, con-1, con-2, con-3의 ID를 가진 상태라고 하자.

con-1이 Consumer Group을 탈퇴하면 LeaveGroup에 따른 리밸런싱이 발생한다.

이 때, con-1이 처리하던 토픽 파티션은 revoke되고, 다른 Consumer에게 assign된다.

[그림1] LeaveGroup으로 인한 리밸런싱 발생 / [그림2] Revoke된 토픽 파티션은 새로운 Consumer에게 Assign

 

Consumer가 다시 Consumer Group에 들어오기 위해 요청한다.

GroupCoordinator는 이를 새로운 Consumer로 인식해 con-A라는 새로운 member.id를 발급한다.

 

새로운 member.id 를 발급받아 Consumer Group 재가입

 

con-A는 Consumer Group에 들어오고 새로운 토픽 파티션을 할당받는다.

새로운 토픽 파티션을 Assign

 

잠깐의 순단으로 인해서 2번의 리밸런싱이 발생했다.

그림으로는 간단해보이지만, Consumer A → B로 토픽 파티션을 리밸런싱하는 작업은 많은 양의 데이터 전송이 필요하다.

Static Membership

Static Membership에서는 GroupCoordinator가 특정 Consumer가 기존에 Consumer Group에 속해 있었던 Consumer임을 인식하도록 설계된다.

 

이를 위해 각 Consumer는 고유한 group.instance.id를 설정해줘야 하며, 이 설정을 통해 Static Membership을 사용할 수 있다.

# Consumer 1
props.put("group.instance.id", "con-1");

 

Dynamic Membership에서 사용한 예시로 Static Membership을 적용했을 땐 어떻게 동작하는지 확인해보자.

 

con-1이 Consumer Group을 탈퇴한다.

이 때, con-1은 GroupCoordinator에게 Consumer Group 탈퇴를 알리지 않으므로 리밸런싱이 발생하지 않는다.

con-1은 Consumer Group을 떠나지만 GroupCoordinator에게 알리지 않아 리밸런싱이 트리거 되지 않음

 

리밸런싱이 발생하지 않기 때문에 con-1이 처리하고 있던 토픽 파티션은 어떠한 Consumer에게도 할당되지 않은 상태로 남는다.

토픽 파티션은 session.timeout.ms 동안 대기

 

con-1이 다시 Consumer Group으로 돌아온다.

GroupCoordinator는 con-1이 이미 Consumer Group에 속했던 Consumer임을 인지하므로 리밸런싱이 발생하지 않는다.

con-1은 그대로 다시 자신이 처리하던 토픽 파티션을 할당받아 처리한다.

 

session.timeout.ms 내에 Consumer Group에 돌아와 리밸런싱이 발생하지 않음

 

Static Membership을 사용하면 Dynamic Membership을 사용할 때와 달리 리밸런싱이 발생하지 않은 것을 확인할 수 있다.

Static Membership을 적용하고 리밸런싱을 피함으로써 리밸런싱 시 발생할 수 있는 단점들을 피할 수 있다.

 

위에 내용을 설명할 때 고려하지 않은 부분이 있다. Consumer가 Consumer Group으로 돌아오지 않을 수도 있다.

할당받지 않은 토픽 파티션은 결국 다른 Consumer가 할당받아 처리해야 한다. 토픽 파티션을 무한히 처리하지 않도록 방치할 수 없기 때문이다.

 

Static Membership은 기존 Consumer가 다시 Consumer Group으로 돌아와서 토픽 파티션을 처리하기 까지 대기하는 유예 기간으로 session.timeout.ms를 사용한다.

 

session.timeout.ms 내에 기존 Consumer가 돌아오지 않으면 GroupCoordinator는 리밸런싱을 트리거한다.

그리고 처리되지 않던 토픽 파티션을 새로운 Consumer에게 Assign되어 처리된다.

session.timeout.ms 내에 Consumer Group이 돌아오지 않아 리밸런싱 발생

 

따라서, Static Membership을 사용시에는 Consumer가 재시작되는 시간을 고려해 적절한 값으로 session.timeout.ms를 지정해야 한다.

예를 들어, Consumer가 Consumer Group에 다시 들어오기 까지 약 1분이 걸린다면 session.timeout.ms를 1분보다 큰 값으로 지정해야 불필요한 리밸런싱을 줄일 수 있다.

Reference.


Conduktor: https://learn.conduktor.io/kafka/consumer-incremental-rebalance-and-static-group-membership/


Confluent: https://www.confluent.io/blog/dynamic-vs-static-kafka-consumer-rebalancing/


Medium: https://medium.com/apache-kafka-from-zero-to-hero/apache-kafka-guide-16-partition-rebalance-static-group-membership-1a5af31269b8


KIP-345: https://cwiki.apache.org/confluence/display/KAFKA/KIP-345%3A+Introduce+static+membership+protocol+to+reduce+consumer+rebalances


실전 카프카 개발부터 운영까지

반응형