728x90

- Serialize > Partitioning > Compression > Record Accumulator 저장 > Sender에서 별도의 Thread로 전송
- Record Accumulator에서 Batch 단위로 전송하게 된다.
Producer Record와 Record Batch

- KafkaProducer 객체의 Send() 메서드는 호출 시마다 하나의 ProducerRecord를 입력하지만 바로 전송되지 않고 내부 메모리에서 단일 메시지를 Topic 파티션에 따라 Record Batch 단위로 묶은 뒤 전송한다.
- 메시지들은 Producer Client의 내부 메모리에 여러 개의 Batch들로 buffer.memory 설정 사이즈만큼 보관할 수 있으며 여러 개의 Batch들로 한꺼번에 전송될 수 있다.
상세 분석

- Record Accumulator는 Partitioner에 의해서 메시지 배치가 전송이 될 토픽과 Partition에 따라 저장되는 kafkaProducer 메모리 영역
- Sender Thread는 Record Accumulator에 누적된 메시지 배치를 꺼내서 브로커로 전송한다.
- KafkaProducer의 MainThread는 send() 메서드를 호출하고 Record Accumulator에 데이터를 저장하고 Sender Thread는 별개로 데이터를 브로커로 전송한다.
linger.ms와 batch.size


- Sender Thread는 기본적으로 전송할 준비가 되어 있으면 Record Accumulator에서 1개의 Batch를 가져갈수도, 여러개의 Batch를 가져갈 수도 있다.
- Batch에 메시지가 다 차지 않아도 가져갈 수 있음
- linger.ms를 0보다 크게 설정하여 Sender Thread가 하나의 Record Batch를 가져갈 때 일정 시간 대기하여 Recored Batch에 메시지를 보다 많이 채울 수 있도록 적용
- max.inflight.requests.per.connection 값에 따라 몇개의 Batch를 보낼 수 있는지 설정
Producer의 linger.ms에 대한 고찰
- linger.ms를 반드시 0보다 크게 설정할 필요가 없다.
- Producer와 Broker간의 전송이 매우 빠르고 Producer에서 메시지를 적절한 Record Accumulator에 누적된다면 linger.ms가 0이 되어도 무방
- 전반적인 Producer와 Broker간의 전송이 느리다면, linger.ms를 높여서 메시지가 배치로 적용될 수 있는 확률을 높이는 시도를 해볼 만하다.
- linger.ms는 보통 20ms 미만으로 설정 권장
실습하기
//Bootstrap.servers, key.serializer.class, value.serializer.class
//props.setProperty("bootstrap.servers", "192.168.56.101:9092");
props.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.56.101:9092");
props.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.setProperty(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.setProperty(ProducerConfig.ACKS_CONFIG, "0");
props.setProperty(ProducerConfig.BATCH_SIZE_CONFIG, "32000");
props.setProperty(LINGER_MS_CONFIG, "20");
Producer의 Sync와 Callback Async에서의 Batch
- 기본적으로 KafkaProducer 객체의 send() 메서드는 비동기이며, Batch 기반으로 메시지 전송
- Callback 기반의 Async는 비 동기적으로 메시지를 보내면서 RecordMetaData를 Client가 받을 수 있는 방식을 제공
- Callback 기반의 Async는 여러 개의 메시지가 Batch로 만들어짐
- RecordMetaData recordMetadata = KafkaProducer.send().get()와 같은 방식으로 개별 메시지 별로 응답을 받을 때까지 block 되는 방식으로는 메시지 배치 처리가 불가능
- 전송은 배치레벨이지만 배치에 메시지는 단 1개
- 동기와 비동기는 단순 통신 속도의 차이뿐만 아니라 배치 시간만큼에 차이도 있는 것이다.
728x90
'카프카 > Java 기반 카프카 클라이언트 구현, Producer 내부 메커니즘 2' 카테고리의 다른 글
| Custom Partitioner로 메시지의 특정 Partition 설정하기 (0) | 2025.10.04 |
|---|---|
| idempotence(멱등성) 기반 중복 없이 전송 (0) | 2025.10.04 |
| Producer의 max.in.flight.request.per.connection의 이해 (0) | 2025.10.04 |
| Producer의 전송/재전송 내부 메커니즘 및 재전송 동작 관련 주요 파라미터 (0) | 2025.09.30 |
| acks 값 설정에 따른 Producer의 전송 방식 차이 이해 (0) | 2025.09.29 |