본문 바로가기
Kafka

[Kafka] Advanced Producer Configurations

'Stéphane Maarek - Learn Apache Kafka for Beginners v2'를 보고 작성한 글입니다. 😀

Acks & min.insync.replicas

acks = 0 (no acks)

ack 를 요청하지 않음

브로커가 오프라인 상태가되거나 exception 이 발생하면 데이터가 손실될 수 있다

데이터를 손실해도 괜찮은 것에 유용

  • Metrics collection
  • Log collection

acks = 1(leader acks)

리더 브로커의 ack 는 요청하지만 레플리케이션은 보장하지 않음

ack 를 받지 못하면, 프로듀서는 재전송할 수 있다

리더 브로커가 오프라인 상태가되었지만 레플리케이션이 아직 데이터를 복제하지 않을 경우 데이터가 손실된다

acks = all (replicas acks)

acks = all 은 min.insync.replicas 와 함께 사용해야한다

min.insync.replicas 는 브로커 또는 토픽 수준에서 설정 가능 (재정의)

min.insync.replicas = 2 는 최소 2개 이상의 ISR인 브로커(리더 포함)가 ack 해야한다

replication.factor = 3, min.insync = 2, acks = all 을 사용하는 경우 브로커 1개 까지만 중단을 허용할 수 있다

 

Idempotent Producer

프로듀서는 네트워크 오류로 인해 데이터를 중복할 수 있다

"idempotent Producer" 를 통해 커밋을 하지 않아 데이터 중복을 방지할 수 있다

멱등성(idempotent)은 안정적이고 안전한 파이프라인을 보장한다

사용방법 : enable.idempotence=true (producer level) + min.insync.replicas=2 (broker/topic level)

ack=all, retries=MAX_INT, max.in.flight.requests.connection=5

idempotent Producer 를 실행하면 처리량 및 지연 시간에 영향을 미칠 수 있음

 

Message Compression

프로듀서는 일반적으로 JSON 데이터와 같이 텍스트 기반 데이터를 보낸다

이 경우 프로듀서에게 압축을 적용하는 것이 중요하다

압축은 프로듀서 수준에서 활성화되며 브로커 또는 컨슈머에서 구성 변경이 필요하지 않다

"compression.type" 은 default 가 'none' 이고, 'gzip', 'lz4', 'snappy' 등이 가능하다

Kafka로 전송되는 메시지의 배치가 클수록 압축이 더 효과적이다

압축된 배치(compressed batch)의 장점

  • 훨씬 더 작은 프로듀서의 요청 크기 (최대 4 배의 압축률!)
  • 네트워크를 통한 데이터 전송 속도 향상 => 지연 시간 감소
  • 더 좋은 처리량
  • Kafka 에서 더 좋은 디스크 활용도 (디스크에 저장된 메시지가 더 작음)

압축된 배치(compressed batch)의 단점

  • 프로듀서는 일부 CPU cycle 을 압축에 적용해야한다
  • 컨슈머는 압축 해제를 위해 일부 CPU cycle 을 수행해야한다

결론

  • 최적의 속도 및 압축 비율을 위해 snappy 또는 lz4 테스트 고려해 볼 만함
  • 사용하는 데이터에 대한 최상의 성능을 제공하는 압축 알고리즘을 찾으면 적용하면 될 듯...
  • 처리량이 많을 경우는 반드시 사용하는게 나을 거 같다
  • 추가적으로 linger.msbatch.size 를 조정하는 것도 고려하면 좋다

 

Producer Batching

기본적으로 Kakfa 는 가능한 한 빨리 레코드를 보내려고 한다

많은 데이터를 보내야하는 경우 데이터를 개별적으로 보내지 않고 배치를 통해 한번에 일괄 처리하여 보낸다

배치(일괄 처리)를 통해 Kafka 는 매우 낮은 대기 시간을 유지하면서 처리량을 늘릴 수 있다

배치는 압축률이 높아 효율성이 향상된다

Linger.ms : 배치를 보내기 전에 프로듀서가 기다릴 수 있는 시간 (기본값 0)

약간의 지연 (예 : linger.ms = 5)을 도입하여 메시지가 일괄적으로 함께 전송 될 가능성을 높인다

따라서 약간의 지연을 도입하는 대신 프로듀서의 처리량, 압축 및 효율성을 높일 수 있다

linger.ms 기간이 끝나기 전에 배치가 가득 차면 (batch.size 참조) 즉시 Kafka로 전송된다

batch.size : 배치에 포함될 최대 바이트 수 (기본값 16KB)

배치 크기를 32KB 또는 64KB로 늘리면 요청의 압축, 처리량 및 효율성을 높일 수 있다

배치 크기보다 큰 메시지는 배치되지 않는다

배치는 파티션별로 할당되므로 너무 높은 숫자로 설정하면 메모리 낭비하게 된다

(참고 : Kafka Producer Metrics 를 사용하여 평균 배치 크기 메트릭을 모니터링 할 수 있다)

linger.ms 증가는 압축을 향상시켜 일괄 처리 가능성을 높인다

batch.size 증가는 일괄 처리 가능성을 높이지 않고 일괄 처리를 더 크게 만든다

 

High Throughput Producer Demo

프로듀서에 snappy 메시지 압축을 추가한다

snappy는 log 라인 또는 JSON 문서와 같이 메시지가 텍스트 기반인 경우 매우 유용하다

snappy는 CPU / 압축 비율의 균형이 좋다

또한 batch.size 를 32KB 로 늘리고 linger.ms 를 20ms로 늘려 약간의 지연을 허용한다

// high throughput producer (at the expense of a bit of latency and CPU usage)
properties.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy");
properties.put(ProducerConfig.LINGER_MS_CONFIG, "20");
properties.put(ProducerConfig.BATCH_SIZE_CONFIG, Integer.toString(32*1024)); // 32KB batch size

 

Producer Default Partitioner and how keys and hashed

기본적으로 키는 "murmur2" 알고리즘을 사용하여 해시된다

파티셔너의 동작을 재정의하지 않는 것이 가장 선호된다

공식 : targetPartition = Utils.abs (Utils.murmur2 (record.key ())) % numPartitions;

즉, 동일한 키는 동일한 파티션으로 이동하고 **토픽에 파티션을 추가하면 공식이 완전히 변경된다

 

Producer - Max.block.ms 및 buffer.memory

프로듀서는 브로커가 취할 수있는 것보다 더 빨리 생산하면 레코드가 메모리에 버퍼링된다

buffer.memory = 32MB (default) : 전송 버퍼의 크기

해당 버퍼는 시간이 지남에 따라 채워지고 브로커에 대한 처리량이 증가하면 다시 채워진다

버퍼가 가득 차면 (모두 32MB) .send() 메서드가 차단되기 시작한다 (즉시 반환되지 않음)

max.block.ms = 60000 (default) : .send() 시간은 예외가 발생할 때까지 차단된다

예외는 기본적으로 다음과 같은 경우에 발생한다

  • 프로듀서가 버퍼를 다 채울 때
  • 브로커가 새로운 데이터를 수락하지 않을 때
  • 60초가 지났을 때

일반적으로 브로커가 요청에 응답 할 수 없기 때문에 다운되거나 과부하 상태임을 의미하는 예외 적중에 도달 한 경우

 


References


🏋🏻 개인적으로 공부한 내용을 기록하고 있습니다.
잘못된 부분이 있다면 과감하게 지적해주세요!! 🏋

댓글