카프카 컨수머를 공부하다보면 많은 비슷한 단어로 혼동이온다.
인터넷에 찾아봐도 잘 나오지 않고 왜 이런 명칭이 나왔는지 배경과 코드를 보며 알아봤습니다.
1. ClientId
An id string to pass to the server when making requests. The purpose of this is to be able to track the source of requests beyond just ip/port by allowing a logical application name to be included in server-side request logging.
요청을 할 때 서버에 전달할 ID 문자열입니다.
이는 서버 측 요청 로깅에 논리적 애플리케이션 이름이 포함되도록 허용하여 단순한 IP/포트를 넘어 요청의 출처를 추적할 수 있도록 하기 위한 것입니다.
목적
브로커에 찍힌 컨수머의 로깅 추척
배경
아래의 링크 Description을 보면 브로커에서 어느 컨슈머에서 요청을 한것인지 request log를 보는데 어느 컨수머인지 확인이 불편했습니다.
많은 컨수머 중 어떤 컨수머 그룹에서 요청을 보냈는지 알 수 없었던 것입니다. 따라서 ClientId가 컨수머 그룹 ID 정보까지 저장하는 형태로 변경하기로 했습니다.
코드 level
기존에는 ClientId 값을 Auto increment로 할당을 해주는것을 볼수있습니다.
변경된 코드 부분에서는 GroupId(컨수머 그룹) 값도 넣는것을 볼 수 있습니다.
원래 ClientId 할당 로직이 KafkaConsumer 생성자에 있었지만 현재는 ConsumerConfig 클래스에서 책임을 갖도록 리팩토링되었습니다.
2. member.id
member.id에 대해 정확히 나온곳이없어서 카프카 이슈를 둘러보다가 발견했습니다.
A new consumer joins the group with member.id field set as UNKNOWN_MEMBER_ID (empty string), since it needs to receive the identity assignment from broker first. For request with unknown member id, broker will blindly accept the new join group request, store the member metadata and return a UUID to consumer.
새 Consumer는 브로커로부터 신원 할당을 먼저 받아야 하므로 member.id 필드가 UNKNOWN_MEMBER_ID(빈 문자열)로 설정된 상태로 그룹에 가입합니다. 알수없는 member.id 요청의 경우, 브로커는 새 그룹 가입 요청을 맹목적으로 수락하고 멤버 메타데이터를 저장한 후 소비자에게 UUID를 반환합니다.
목적
group Coordinator(broker 중 하나)과 컨수머 JoinGroup 요청시 고유 식별자 memberId를 보내 사용됩니다.
컨수머 하트비트 전송시에도 memberId를 보내 줍니다.
코드 level
memberId는 컨수머 그룹에 등록됐을때 초기화 됩니다.
memberId 할당 부분을 봅시다.
memberId가 Consumer group 요청시 초기 memberId값은 UNKNOWN_MEMBER_ID이다.
그 이후 doNewMemberJoinGroup 로직으로 들어가게 됩니다.
doCurrentMemberJoinGroup 로직 부분은 4번 group.instance.id와 연관이있어 뒤에서 설명하겠습니다.
ClientId값과 UUID의 혼합값으로 할당합니다.
3. group.id
A unique string that identifies the consumer group this consumer belongs to. This property is required if the consumer uses either the group management functionality by using subscribe(topic) or the Kafka-based offset management strategy.
이 소비자가 속한 소비자 그룹을 식별하는 고유 문자열입니다. 이 속성은 소비자가 subscribe(topic)을 사용하여 그룹 관리 기능을 사용하거나 카프카 기반 오프셋 관리 전략을 사용하는 경우 필요합니다.
목적
컨수머 토픽의 논리적 그룹
배경
구독하는 토픽에대해 컨수머들을 묶어서 관리해야하는데 필요한 KafkaConfig 설정입니다.
4. group.instance.id
A unique identifier of the consumer instance provided by the end user. Only non-empty strings are permitted. If set, the consumer is treated as a static member, which means that only one instance with this ID is allowed in the consumer group at any time. This can be used in combination with a larger session timeout to avoid group rebalances caused by transient unavailability (e.g. process restarts). If not set, the consumer will join the group as a dynamic member, which is the traditional behavior.
최종 사용자가 제공한 소비자 인스턴스의 고유 식별자입니다. 비어 있지 않은 문자열만 허용됩니다. 설정하면 소비자는 정적 멤버로 취급되며, 이는 소비자 그룹에서 언제든지 이 ID를 가진 인스턴스 하나만 허용됨을 의미합니다. 이는 일시적인 사용 불가(예: 프로세스 재시작)로 인한 그룹 재조정을 방지하기 위해 더 큰 세션 시간 초과와 함께 사용할 수 있습니다. 설정하지 않으면 소비자는 기존 동작인 동적 멤버로 그룹에 참여하게 됩니다.
목적
리밸런스시 파티션이 재분배 되지 않게하기 위한 설정
배경
2.3 버전 이후 생긴 개념입니다.
컨수머 그룹에 새로운 컨수머가 들어오거나 떠나게되면 파티션 리밸런스 현상이 발생합니다. 그 영향으로 컨수머 그룹 안 컨수머들은 모두 stop the world 현상에 빠지게됩니다. 그동안 브로커에는 토픽이 쌓여 들어온 데이터와 commit offset의 lag는 증가하게 될겁니다.
컨수머가 다운됐을때는 리밸런스가 무조건 일어나야하지만 내가 의도한 상황(ex. 재기동)일때 파티션이 다시 재분배 상태일때는 너무 큰 비용을 낭비하게됩니다.
이런 문제점을 해소하기 위해 정적 멤버라는 개념이 추가됐습니다.
KafkaConsumerConfig에 group.instance.id를 기입하면 정적 멤버라고 인식하게되어 컨수머 그룹 이탈시 LeaveGroup 호출을 하지 않게됩니다.
정적 멤버가 떠나며 LeaveGroup을 호출하는 유일한 경우는 session.time.out으로 인해서만 발생하게됩니다.
코드 level
여기서 instanceId(group.instance.id) 값의 유무를 통해 컨수머 그룹 JoinGroup시 정적멤버, 동적멤버 생성로직이 분기되어 관리되는것을 볼 수 있습니다.
정적멤버가 그룹에 재참여할때는 doCurrentMemberJoinGroup의 로직으로 관리되는것을 볼수 있습니다.
빨간색은 동적멤버의 상황의 파티션 분배이고 초록색은 정적멤버의 파티션 분배로 동일하게 분배받은것을 볼수 있습니다.
정리
client.id, group.id, group.instance.id는 Config값으로 입력할 수 있고
member.id는 값을 입력할수 없고 내부적으로 할당되어 브로커와 컨수머간 서로 통신을 위한 값이다.
'오픈소스 > 카프카' 카테고리의 다른 글
카프카 오픈소스 뜯어보기 Consumer poll 메서드 (kafkaConsumer) (0) | 2022.11.22 |
---|