카테고리 없음

[실전 카프카 개발부터 운영까지] 6. 컨슈머의 내부 동작 원리와 구현

noahkim_ 2025. 5. 8. 09:57

1. 컨슈머 오프셋 관리

오프셋

  • 컨슈머가 읽은 메시지 위치를 나타내는 번호
  • 다음에 어디부터 읽을지 알 수 있음

 

__consumer_offest 토픽

항목 설명
역할
각 컨슈머 그룹이 어떤 파티션의 몇 번째 메시지까지 읽었는지 기록함
포맷
key: (group.id, topic, partition), value: offset
파티션 수 조정
offsets.topic.num.partitions (기본: 50)
복제 수 조정
offsets.topic.replication.factor (기본: 3 추천)

 

 

기본 동작

  1. 컨슈머
    • 지정된 토픽의 메시지를 읽음
    • 읽은 메시지의 오프셋 정보를 __consumer_offest에 기록
  2. 컨슈머 그룹
    • 컨슈머들의 오프셋 추적
    • 장애 시, 지정된 오프셋을 통해 복구

 

2. 그룹 코디네이터

그룹 코디네이터

  • 컨슈머 그룹의 구성, 오프셋, 리밸런싱 관리를 담당하는 브로커
  • 컨슈머 그룹이 브로커에 최초 연결 시, 해당 브로커가 자동으로 그룹 코디네이터로 지정됨
구분 설명
트래킹
그룹 멤버와 파티션을 지속적으로 모니터링
- 모니터링 중 변화를 감지하면 리밸런싱을 트리거함
리밸런싱 컨슈머 구성에 변화로 인해 재분배
  - 컨슈머 그룹은 컨슈머들에게 토픽의 파티션을 분배해야 함

 

옵션
옵션 설명
heartbeat.interval.ms
컨슈머가 그룹 코디네이터에게 하트비트를 보내는 주기
session.timeout.ms
설정한 시간 내에 하트비트를 받지 못하면 해당 컨슈머가 장애난 것으로 간주하고 리밸런싱을 시작
max.poll.interval.ms
컨슈머가 poll() 메서드를 호출하는 최대 허용 간격 (너무 오래 걸리면 세션이 끊긴 것으로 간주)

 

컨슈머 그룹 등록 과정

  1. 컨슈머: 브로커에게 커넥션 연결 요청을 보냄
  2. 브로커: 그룹 코디네이터 생성
  3. 그룹 코디네이터: 컨슈머 요청 대기 (group.initial.rebalance.delay.ms)
  4. 컨슈머: 그룹 코디네이터에 등록 요청 (맨 처음 요청한 컨슈머가 리더가 됨)
  5. 그룹 코디네이터: 구독 토픽과 파티션 리스트를 리더에게 응답
  6. 리더 컨슈머: 리밸런싱 및 분배 정보를 그룹 코디네이터에 전달
  7. 그룹 코디네이터: 분배 정보를 캐시하고 컨슈머들에게 성공 통보
  8. 팔로워 컨슈머들: 자신에게 할당된 파티션으로부터 메시지들을 가져옴

 

3. 스태틱 멤버십

  • 컨슈머 그룹에서 컨슈머가 재시작하거나 일시적으로 끊겼다가 다시 접속해도 리밸런싱이 발생하지 않게 하는 기능
항목 설명
문제점
컨슈머 재시작 시 새로운 컨슈머 ID가 부여됨
필연적으로 리밸런싱 발생
리밸런싱으로 인해 상당한 지연 시간 발생
스태틱 멤버십 도입 이유
불필요한 리밸런싱을 방지하여, 재시작 후에도 빠르게 정상 복귀 가능
스태틱 멤버십 방식
각 컨슈머에 고유한 ID(group.instance.id)를 부여하여, 재접속 시에도 기존 구성원으로 인식
- 스태틱 멤버십 컨슈머는 그룹에서 떠날 때 그룹 코디네이터에 알리지 않음
- 컨슈머가 다시 합류하면, 코디네이터가 group.instance.id를 확인하여 기존 멤버로 인식
주의사항
session.timeout.ms 값을 충분히 크게 설정해야 함 (컨슈머가 다시 합류할 시간을 벌어주기 위함)

 

4. 컨슈머 파티션 할당 전략

  • 누가 어떤 파티션을 소비할지를 결정하는 방식
  • 리더 컨슈머가 정해진 파티션 할당 전략에 따라 각 컨슈머와 대상 토픽의 파티션을 매칭시킴

 

할당 전략

  • partition.assignment.strategy 옵션을 통해 전략을 선택할 수 있음
할당 전략 설명 특징
RangeAssignor 각 토픽의 파티션을 순서대로 나열
각 컨슈머에게 최소 할당 파티션 수로 분배
불균형 발생 가능성 있음
(파티션 수가 컨슈머 수와 정확히 맞지 않으면)
RoundRobinAssignor 모든 파티션을 순서대로 나열
각 컨슈머에게 전체 파티션에서 순차적으로 분배
불균형을 피할 수 있음
- 데이터가 연속적인 경우 비효율적일 수 있음
StickyAssignor 기존 할당을 최대한 유지
- 변경이 필요할 때만 파티션 재할당
- 리밸런싱 시 변경을 최소화
- 안정적 / 효율적
CooperativeStickyAssignor Sticky 기반 전략에 점진적 리밸런싱 도입 - 리밸런싱 시 전체 그룹 중단 없이 점진적으로 재할당
- COOPERATIVE 프로토콜 사용

 

5. 정확히 한 번 컨슈머 동작