Kafka Producer는 겉으로 보기엔 단순하다.

“메시지를 하나 보내면 되지 않나?” 하지만 실제 동작을 살펴보면, 그 안에는 의외로 섬세한 의도와 기계적인 아름다움이 숨어 있다.

데이터를 어떻게 모아두고, 언제 묶어서 전송하고, 어떤 기준으로 안정성을 확보하며, 메시지 순서를 어떻게 보장할 것인지까지. Producer는 Kafka 구조에서 생각보다 중요한 축을 담당한다.

이 글에서는 Producer의 전체 흐름을 천천히 따라가면서 내부 동작과 핵심 옵션들이 어떤 의미를 갖는지 자연스럽게 이해해보려 한다.


Producer가 메시지를 다루는 방식

메시지가 전송되기까지의 여정은 생각보다 길고 복잡하다.

Kafka Producer는 단일 메시지를 바로 브로커로 밀어 넣지 않는다.

대신 일단 RecordAccumulator라는 곳에 잠시 쌓아두고,

여러 조건을 고려해 적절한 ‘타이밍’을 만들었을 때 배치로 묶어 전송한다.

이 과정은 감각적으로 이해하는 게 더 좋다.

그래서 아래에 Producer 내부 흐름을 조금 더 입체적으로 표현해보았다.

flowchart LR
    A["앱에서 send() 호출<br/><br/>· key/value 포함<br/>· 전송하려는 토픽 지정"] --> B["Serializer 적용<br/><br/>· key/value 직렬화<br/>· 전송 가능한 byte 배열로 변환"]
    B --> C["RecordAccumulator<br/><br/>· 파티션별로 메시지 버퍼링<br/>· linger.ms 만큼 기다리며 배치"]
    C --> D["배치 생성<br/><br/>· batch.size 를 기준으로 묶음<br/>· 필요 시 압축(zstd/lz4 등)"]
    D --> E["Sender Thread<br/><br/>· 브로커 메타데이터 확인<br/>· Leader 브로커로 전송"]
    E --> F["브로커 응답 처리<br/><br/>· acks 에 따른 안정성 보장<br/>· 재시도, 순서 보장 처리"]

Producer는 마치 리듬감 있는 악기처럼 작동한다.

조금 더 기다렸다가 보내면 효율이 좋아지는 순간이 있고,

즉시 보내면 지연은 줄지만 비용이 커진다.

이 균형을 제어하는 옵션들이 바로 Producer의 핵심이다.


linger.ms와 batch.size