본문 바로가기
도서기록/카프카인액션

05 컨슈머: 데이터 열기

by 코엘리 2025. 1. 19.
반응형

컨슈머는 카프카에서 데이터를 가져와 다른 시스템이나 애플리케이션에 이 데이터를 제공한다. 컨슈머는 브로커 외부에 존재하는 클라이언트 이므로 다양한 프로그래밍 언어로 작성이 가능하다.

5.1 예제

  • 컨슈머 클라이언트는 관심 있는 토픽을 구독하는 프로그램이다.
  • 실제 프로덕션 환경에서 대부분의 컨슈머 클라이언튼느 별도의 호스트에 있다.
  • 컨슈머가 토픽을 구독하는 대신 데이터가 푸시되지 않는다. -> 처리 제어의 권한은 컨슈머에게 이전된다.

5.1.1 컨슈머 옵션

  • 클라이언트 시작 시 연결을 시도할 수 있는 브로커를 항상 알아야 한다.
  • 메시지를 생성한 직렬 변환기와 일치하는 키와 값에 대한 역직렬 변환기를 사용해야 한다.

5.1.2 코디네이트 이해

  • 컨슈머가 브로커에게 보내는 로그의 인덱스 위치로 오프셋을 사용한다. 이를 통해 로그는 소비하려는 메시지 위치를 알 수 있다.
  • --from-beginning 플래그를 사용하면, 이는 컨슈머 auto.offset.reset 구성 매개변수를 earliest 로 구성한다. 해당 구성을 사용하면, 콘솔 컨슈머를 시작하기 전에 전송된 경우에도 연결된 파티션의 해당 토픽에 대한 모든 레코드를 볼 수 있다.
  • auto.offset.reset 옵션을 추가하지 않으면 기본 값은 latest 이다. 이 옵션은 토픽 파티션에 이미 있는 메시지 처리를 무시한다.
  • 오프셋은 항상 각 파티션에 대해 증가한다.
  • 오프셋을 찾기 위해서는, 기록된 토픽 내에서 파티션을 찾은 다음 인덱스 기반 오프셋을 찾는다.
    • 컨슈머는 일반적으로 컨슈머의 파티션 리더 레플리카에서 읽는다.
  • 각 컨슈머 그룹에 대해 특정 브로커가 그룹 코디네이터 역할을 수행하여, 연결할 파티션과 그 리더가 어디있는지 알 수 있다.
  • 그룹 코디네이터는 어떤 컨슈머가 어떤 파티션을 읽을지 지정하는 것 뿐만 아니라, 컨슈머가 추가/실패 될 때 컨슈머도 할당한다.
    • 컨슈머보다 파티션이 더 많은 경우 하나의 컨슈머가 둘 이상의 파티션을 처리한다.
  • 파티션이 많으면 브로커 간에 파티션이 복제될 때까지 기다리는 시간을 고려해야 하고, 이는 컨슈머에게 메시지 전달 전 동기화가 완료되어야 하기 때문에 파티션이 많다고 좋지는 않다.

5.2 컨슈머가 상호작용하는 방식

  • 그룹에 컨슈머를 추가하거나 그룹에서 제거함으로써 처리 규모에 영향을 준다.
  • 동일한 그룹의 일부가 아닌 컨슈머는 오프셋에 대한 동일한 코디네이션을 공유하지 않ㄴ는다.
  • 새 그룹 ID 가 필요한지 여부를 결정하는데 중요 사항은 컨슈머가 하나의 애플리케이션의 일부로 작업하는지 아니면 별도의 논리 흐름으로 작업하는 지이다.

5.3 추적

  • 카프카는 컨슈머를 1개로 제한하지도 않는다.
  • 카프카는 메시지가 전달되었다고 해서 사라지지 않기 때문에, 컨슈머 클라이언트는 토픽에서 읽은 위치를 기록할 방법이 필요하다.
  • 많은 애플리케이션이 동일 토픽을 읽을 수 있으므로 오프셋과 파티션이 특정 컨슈머 그룹에만 속해야 한다.
    • 그룹, 토픽, 파티션 번호를 이용한 고유 조합이 중요하다.

5.3.1 그룹 코디네이터

  • 그룹 코디네이터는 컨슈머 클라이언트와 협력하여 특정 그룹이 읽은 토픽 내부의 기록을 유지한다.
  • 토픽에 대한 파티션 좌표와 그룹 ID 는 오프셋 값에 특정 값을 할당한다.
  • 일반적으로 컨슈머 그룹당 하나의 컨슈머만 하나의 파티션을 읽을 수 있다. 즉, 파티션은 많은 컨슈머가 읽을 수 있지만 한 번에 각 그룹의 한 컨슈머만 읽을 수 있다.

5.3.2 파티션 할당 전략

  • 레인지 할당자
    • 단일 토픽을 사용해 파티션 수를 찾은 다음 컨슈머 수로 분할한다.
    • 분할이 짝수가 아닌 경우 첫 번째 컨슈머는 남은 파티션을 가져온다.
    • 파티션 7개, 컨슈머 3개일 경우 (1,2,3) / (4,5) / (6,7) 로 분리한다.
  • 라운드 로빈
    • 컨슈머 밑으로 균일하게 분산되는 방식이다.
    • 파티션 7개, 컨슈머 3개일 경우 (1,4,7) / (2,5) / (3,6) 로 분리한다.

5.4 작업 위치 표시

  • enable.auto.commit을 true로 표시하면(기본값), 오프셋은 컨슈머 클라이언트가 대신 커밋해준다. 즉, 오프셋 커밋을 위해 다른 호출을 할 필요가 없다.
    • 그러나 컨슈머 로직 중 실패 시, 처리되지 않았음에도 불구하고 소비된 것으로 간주될 수 있다.
  • enable.auto.commit 을 false로 표시하면, 애플리케이션이 실제로 메시지를 사용하고 커밋할 때 관리를 직접 수행할 수 있다.
  • 오프셋 제어 시 동기/비동기 방식으로 커밋을 제어할 수 있다.

5.5 컴팩션된 토픽에서 읽기

  • 컨슈머는 컴팩션된 토픽을 읽고 있다는 사실을 인지해야 한다.
  • 카프카는 백그라운드 프로세스에서 파티션 로그를 컴팩션하고, 마지막 키를 제외하고 동일한 키를 가진 레코드가 삭제될 수 있다. -> 7장에서 자세히
  • 간단히 말하면, 동일한 키값을 가진 레코드는 업데이트해야한다.
  • 클라이언트는 같은 키에 둘 이상의 값이 있는 경우 이 경우를 처리해야 한다.
    • 중복 키를 처리하고 필요한 경우 마지막 값을 제외한 모든 값을 무시하는 로직이 있어야 한다.

5.6 우리 공장의 요구사항에 대한 코드 검색

5.6.1 읽기 옵션

  • 이미 읽었더라도 토픽의 시작 부분부터 읽고 싶은 경우
    • auto.offset.reset = earlist로 설정하거나
    • 다른 컨슈머 그룹 ID를 사용한다.
  • 컨슈머 시작시, 데이터가 너무 오래되어 비즈니스 가치가 없어져 과거 메시지를 제외하고 싶을 경우에는, auto.offset.rest = latest 로 설정한다.

5.6.2 요구사항

  • 메시지를 잃지 않는 안전한 방법은 소비된 직후 레코드별 오프셋을 구체적으로 커밋하는 것이다.
    • enable.auto.commit: false로 설정한다.
  • 관심이 있는 특정 파티션만 읽기 위해서는 TopicPartition 객체를 사용해 토픽에 관심이 있는 특정 파티션을 카프카에게 알린다.
    • TopicPartition 객체를 assign 메서드에 전달하면 컨슈머가 그룹 코디네이터 할당의 재량에 따르도록 허용하는 대신 직접 특정 파티션에 할당하는 방식을 사용할 수 있다.
반응형

'도서기록 > 카프카인액션' 카테고리의 다른 글

04 프로듀서: 데이터 공급  (0) 2025.01.12
03 카프카 프로젝트  (1) 2025.01.05
02 카프카 알아보기  (2) 2024.12.14