Kafka - Producer 1

develkkm·2025년 11월 8일

Kafka Producer는 데이터를 브로커로 전송하는 역할을 한다.
하지만 단순히 “보낸다” 수준이 아니라, 내부적으로 여러 단계를 거쳐 효율적으로 데이터를 처리한다.
이번 글에서는 Producer의 처리 로직, send() 메서드의 동작, 구조, 그리고 비동기 전송 방식을 중심으로 살펴본다.


Producer 구조

Producer는 내부적으로 여러 구성 요소로 분리되어 협력한다.

구성요소역할
ProducerRecord전송할 데이터 단위. Topic, Partition, Key, Value를 포함
SerializerKey, Value를 바이트 배열로 변환
PartitionerKey를 기준으로 전송할 Partition 결정
RecordAccumulator전송 전 메시지를 임시 저장하는 버퍼
SenderAccumulator에 쌓인 배치를 브로커로 전송하는 스레드

이 구조 덕분에 Kafka는 높은 처리량을 유지하면서도, 데이터 손실 없이 안정적으로 메시지를 보낼 수 있다.


Producer의 처리 로직

Kafka Producer가 메시지를 전송할 때 내부적으로 다음과 같은 과정을 거친다.

  1. ProducerRecord 생성 — 전송할 Topic, Key, Value 정보를 포함
  2. Serializer를 통해 Key, Value를 바이트 배열로 변환
  3. Partitioner가 Key를 기준으로 파티션을 결정
  4. RecordAccumulator(버퍼)에 저장 -- send() 끝
  5. Sender Thread가 주기적으로 배치를 전송

Partitioner

Kafka는 데이터를 여러 파티션으로 분산시켜 병렬 처리를 수행한다.
이때 Partitioner는 메시지가 어떤 파티션으로 전송될지를 결정하는 핵심 역할을 한다.

Partitioner의 동작 방식

구분설명
Key가 있을 때Key를 Hash하여 항상 동일한 Partition으로 전송
Key가 없을 때Round-Robin / Sticky Partitioning
Custom Partitioner 사용 시사용자가 원하는 기준으로 직접 파티션 지정 가능

예를 들어, Key를 사용자 ID로 설정하면 같은 사용자의 데이터는 항상 같은 Partition으로 전송되어 순서가 보장된다.

반면, Key가 없는 경우 Kafka는 자동으로 파티션을 분배하기 때문에
메시지 순서가 전역적으로는 보장되지 않는다.


send()

send()는 단순히 “데이터 전송”을 수행하는 함수가 아니다.
Kafka는 내부적으로 비동기 전송 구조를 갖고 있으며,
실제 네트워크 전송은 별도의 스레드(Sender Thread)가 담당한다.

ProducerRecord<String, String> record =
        new ProducerRecord<>("topic-name", "key", "value");

producer.send(record);

ASync & Callback

Kafka Producer는 비동기 전송을 기본으로 한다.
send() 메서드는 즉시 반환되며, 실제 전송 결과는 Callback으로 전달받는다.

producer.send(record, (metadata, exception) -> {
    if (exception == null) {
        System.out.printf("전송 성공! topic=%s, partition=%d, offset=%d%n",
                metadata.topic(), metadata.partition(), metadata.offset());
    } else {
        exception.printStackTrace();
    }
});
  • metadata: 전송된 메시지의 위치 정보
  • exception: 전송 실패 시 예외 객체

이 방식은 I/O 블로킹을 최소화하면서도 전송 성공 여부를 즉시 확인할 수 있게 해준다.


Sync

비동기 방식이 기본이지만, .get()을 호출하면 동기 전송으로 사용할 수 있다.
이는 개발 중 디버깅이나 간단한 실험에 유용하다.

producer.send(record).get();

단, 동기 방식은 응답을 기다리는 동안 스레드가 블로킹되므로,
실제 운영 환경에서는 성능 저하를 유발할 수 있다.


실습

https://github.com/develkkm/kafka-from-0/tree/kafka-core/producers

profile
알던것을 더 확실하게

0개의 댓글