개요
ETL 파이프 라인을 운영하면서 카프카의 내부 기전을 자세히 모르고 있으면 장애 상황이 발생했을 때 대응하기가 어려움을 절실히 느꼈다. 이번 포스팅에서는 카프카의 주요 구성 요소중 하나인 프로듀서는 무엇인가? 내부적으로 어떻게 동작하는가? 에 대해 알아보도록 하자.
내용
프로듀서란 무엇인가?
먼저 카프카 공식 문서에서는 프로듀서에 대해 하기와 같이 정의하고 있다.
A producer partitioner maps each message to a topic partition, and the producer sends a produce request to the leader of that partition. The partitioners shipped with Kafka guarantee that all messages with the same non-empty key will be sent to the same partition.
프로듀서 파티셔너는 각 메세지를 토픽 파티션에 매핑하고, 해당 파티션의 리더에게 생산 요청을 보낸다고 한다. (동일한 키를 동일한 파티션으로 전송되도록 보장한다고도 되어있다. 이것이 무슨 말인지는 후술하도록 하겠다.)
카프카를 공부한 적 있거나 사용해 본 경험이 있는 사람이라면 상기 문구를 이해하기 쉽겠지만 처음 접해본 사람은 저 말을 이해하기 쉽지 않을것이다. 이유는, 파티셔너, 토픽 파티션, 리더 등등의 용어가 카프카에서 어떻게 사용되는지 내부 기전을 알지 못하기 때문이다.
우선 이렇게 정의하고자 한다. 프로듀서는, 카프카 메세지를 카프카에(브로커의 특정 토픽 파티션에) 보내는 주체이다.
그럼 어떻게 적재하는지 알아보자.
프로듀서의 내부 구조
프로듀서는 카프카 브로커로 데이터를 전송할 때 단순히 쏟아 붓는것이 아니라, 내부적으로 파티셔너, 배치 생성 단계를 거친다. 어떤 파티션으로 전송할지 효율적으로 채택하고, TCP 연결을 최소화 하기 위해 내부적으로 배치 생성 단계를 거치는 것이다.
ProducerRecord
ProducerRecord는 프로듀서에서 생성하는 레코드를 뜻한다. 보낼 데이터에 대해 정의하는 것이다. 구성요소는 아래와 같다.
ProducerRecord의 구성 요소 | 설명 |
토픽 | 토픽은 메시지가 저장되는 주요 단위이며, 여러 개의 파티션으로 분할될 수 있다. |
파티션 | 토픽 내에서 데이터가 분할되어 저장되는 물리적인 단위이다. |
타임스탬프 | 메시지가 생성되거나 처리된 시간을 나타낸다. |
메세지 키 | 카프카 메시지를 유일하게 식별하는 데 사용되는 값이다. 키는 옵셔널하며, 같은 키를 가진 메시지는 같은 파티션으로 라우팅될 수 있다. |
메세지 값 | 실제로 전달되는 데이터 또는 페이로드를 나타낸다. |
기본적으로 토픽과 파티션만 있더라도 데이터를 보내는 데에는 지장 없다.
이렇게 레코드가 생성되면 send() 메소드를 호출할 수 있다.
참고로 레코드의 구성요소에는 Offset도 있는데, Offset은 특정 파티션에 데이터가 저장되고 나서 생성되는 값이다.
Partitioner
Partitioner는 어느 파티션으로 보낼지 지정하는 역할을 한다.
메세지 키에 따라 지정되고, 메세지 키가 동일하면 같은 파티션에 지정된다. (해싱에 의함)
파티셔너의 종류에 따라 작동 기전이 달라질 수 있는데 자세한 내용은 후술하도록 하겠다.
Accumulator
Accumulator는 배치로 데이터를 묶어 전송할 데이터를 모으는 버퍼를 뜻한다. 위에서 간단히 설명하였지만, 배치로 묶어서 TCP 통신 한번에 데이터를 최대한 많이 보내기 위해 사용한다.
Sender
샌더는 옵션에 따라 특정 시점이 되면 카프카 브로커에게 보내는 역할을 한다.
파티셔너
파티셔너에는 전술한바와 같이 어느 파티션으로 메세지를 보낼지 정하는 역할을 한다. 프로듀서 API에서는 UniformStickyPartitioner와 RoundRobinPartitioner 2개 파티셔너를 제공한다. 두 구현체의 차이점을 알아보자
파티셔너 이름 | 메세지 키가 있을 때 | 메세지 키가 없을 때 |
UniformStickyPartitioner | 두 구현체 모두 메세지 키가 있을 경우 메세지 키의 해시 값으로 파티션을 매칭하여 전송하며, 파티션 개수가 변경될 경우 메세지 키와 파티션 매칭은 깨지게 된다. (리밸런싱 발생) | ProducerRecord가 들어오는 대로 메세지를 순회한다. (어큐뮤레이터에서 버퍼되는 사이즈가 작다) |
RoundRobinPartitioner | 어큐뮤레이터에서 레코드들이 배치로 묶일때까지 기다렸다가 전송한다. |
이외에도 커스텀 파티셔너를 생성하여 사용할 수 있다.
프로듀서 주요 옵션
필수 옵션
속성명 | 기능 설명 |
bootstrap.server | 브로커의 호스트 명(2개 이상 입력 가능하다) |
key.serializer | 레코드의 메세지 키 직렬화 클래스 지정 (참고) 카프카에서 Key와 Value는 바이트 어레이로 되어있다. 대부분 String으로 직렬화하지만, Int나 float를 String으로 변경하면 데이터 사용량이 많아지게 되면서 네트워크 및 로그 세그먼트로 저장할 때 자원 소모가 심하다. |
value.serializer | 레코드의 메세지 값 직렬화 클래스 지정 (참고) String으로 직렬화 하면 kafka-console-producer에서 디버깅 할 때 용이하다. |
선택 옵션
속성명 | 기능 설명 |
acks | 프로듀서가 메시지를 보내고나서 카프카 브로커로부터 받는 확인(acknowledgment)의 수준을 나타낸다. acks=0: 프로듀서가 메시지를 보내고 나서 브로커로부터 어떠한 확인도 기다리지 않는다. 메시지 손실 가능성이 높으며, 최소한의 지연을 보장한다. (대신 빠름) acks=1: 프로듀서가 메시지를 보내고 나서 리더 파티션에서만 확인을 받는다. 리더 파티션에 메시지가 기록되면 프로듀서는 성공적으로 보낸 것으로 간주한다. 이 설정은 일부 메시지 손실의 가능성을 가지지만, 일반적으로 높은 처리량을 보장한다. acks=all 또는 acks=-1: 프로듀서가 메시지를 보내고 나서 리더 파티션과 모든 ISR(In-Sync-Replicas)프로듀서가 파티션의 리플리카로 설정된 서버)에서 확인을 받을 때까지 기다린다. 이 설정은 가장 안전한 옵션이지만, 가장 큰 지연을 유발할 수 있다. 기본값은 1이다 (참고) acks와 같이 쓰는 옵션으로 min.insync.replicas가 있다. 이는 최소 ISR 그룹의 파티션 개수를 지정하는 옵션이다. |
linger.ms | 프로듀서가 메시지를 전송하기 전에 대기하는 시간을 지정하는 옵션이다. 일반적으로, 프로듀서는 여러 개의 메시지를 한 번에 묶어서(batch) 전송하는데, 이를 배치(batch) 전송이라고 한다. linger.ms 옵션은 이러한 배치 전송에서 프로듀서가 메시지를 얼마 동안 대기할지를 설정한다. 기본적으로, 프로듀서는 배치 전송을 수행하면서 가능한 빨리 메시지를 보내려고 한다. 그러나 linger.ms를 설정하면, 프로듀서가 배치를 전송하기 전에 지정된 시간(밀리초 단위) 동안 대기하도록 할 수 있다. |
retries | 메시지 전송이 실패할 경우 재시도할 횟수를 지정하는 옵션이다. 카프카 클러스터에 메시지를 보낼 때 네트워크 문제나 브로커의 장애로 인해 전송이 실패할 수 있다. 이때 retries 옵션을 사용하면 프로듀서가 전송에 실패한 경우에 해당 메시지를 재시도할 횟수를 설정할 수 있다. retries 옵션을 사용하여 재시도할 횟수를 설정하면, 프로듀서는 전송 실패 시 일정 횟수의 재시도를 시도한 후에 메시지를 보류하거나 에러를 반환한다. 기본값은 2147483647이다. |
max.in.flight.requests.per.connection | 한 번에 요청하는 최대 커넥션 개수 기본값은 5이다. |
partitioner.class | 메시지를 어느 파티션으로 보낼지를 결정하는 파티셔너 클래스를 지정하는 데 사용되는 옵션. 프로듀서가 메시지를 특정 토픽으로 보낼 때, 그 메시지를 어느 파티션에 저장할지 결정하는 파티셔너를 선택할 수 있다. 기본값은 org.apache.kafka.clients.producers.internals.DefaultPartitional이다. |
enable.idempotence | 메시지 전송의 원자성을 보장하는 기능을 활성화하는데 사용된다. enable.idempotence를 활성화하면 다음과 같은 기능이 활성화된다: Idempotent Producer (멱등성 프로듀서): 프로듀서가 동일한 메시지를 여러 번 보내더라도 오직 한 번만 카프카 클러스터에 기록된다. 이는 클라이언트 라이브러리에서 중복 전송을 추적하여 중복 메시지를 필터링한다. enable.idempotence를 활성화하면 메시지 전송의 안전성이 향상되지만, 약간의 성능 오버헤드가 발생할 수 있다. 기본값은 false이다. |
trasactional.id | 트랜잭션을 식별하는 데 사용되는 고유한 식별자(transactional identifier)를 설정하는 데 사용된다. 카프카에서 트랜잭션은 메시지를 안전하게 전송하고 처리하기 위한 메커니즘 중 하나이다. transactional.id를 설정하면 프로듀서는 해당 식별자를 사용하여 트랜잭션을 관리한다. 이를 통해 여러 메시지를 하나의 트랜잭션으로 그룹화하고, 이 트랜잭션의 원자성을 보장할 수 있다. 기본값은 null이다. |
참고 자료
Kafka Producer | Confluent Documentation
An Apache Kafka® Producer is a client application that publishes (writes) events to a Kafka cluster. This section gives an overview of the Kafka producer and an introduction to the configuration settings for tuning. Concepts The Kafka producer is conceptu
docs.confluent.io
Learning About Producers in Apache Kafka
Learn about producers, client applications outside of the Kafka cluster proper that produce data into it. Producers perform network buffering, connection pooling, and partitioning.
developer.confluent.io
[아파치 카프카 애플리케이션 프로그래밍] 개념부터 컨슈머, 프로듀서, 커넥트, 스트림즈까지! |
데브원영 DVWY | 실전 환경에서 사용하는 아파치 카프카 애플리케이션 프로그래밍 지식들을 모았습니다! 데이터 파이프라인을 구축하는데 핵심이 되는 아파치 카프카의 각종 기능들을 살펴보고
www.inflearn.com
ProducerRecord (kafka 2.3.0 API)
A key/value pair to be sent to Kafka. This consists of a topic name to which the record is being sent, an optional partition number, and an optional key and value. If a valid partition number is specified that partition will be used when sending the record
kafka.apache.org
'기술 탐구 > kafka' 카테고리의 다른 글
(Kafka) Exactly-once Semantics의 원리와 엣지 케이스 (0) | 2025.03.07 |
---|