'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.ms 와 batch.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
🏋🏻 개인적으로 공부한 내용을 기록하고 있습니다.
잘못된 부분이 있다면 과감하게 지적해주세요!! 🏋
'Kafka' 카테고리의 다른 글
[Kafka] Advanced Consumer Configurations (0) | 2021.11.23 |
---|---|
[Kafka] Kafka Theory (기본 개념) (0) | 2021.11.23 |
[Kafka] Kafka Stream 에제 4 - user-event-Enricher (join) (0) | 2021.11.23 |
댓글