본문 바로가기

Kafka

[Kafka] Producer (2)

Producer Acks

  • Producer Parameter 중 하나
  • Producer에서 Kafka가 메시지를 잘 전달받았는지 확인할 수 있는 방법
  • acks 설정은 요청이 성공할 때를 정의하는 데 사용되는 Producer Parameter이다.

* acks = 0 -> ack가 필요하지 않음(주로 사용되지 않지만, 메시지 손실이 다소 있더라도 메시지를 빠르게 보내야 할 때 사용한다.)

* acks = 1(default) -> Leader가 메시지를 수신하면 ack를 보낸다. Leader가 Producer에게 ACK를 보낸 후, Follower가 복제하기 전에 Leader에 장애가 발생하면 메시지가 손실된다. (최대 한 번 전송을 보장한다.)

* acks = -1 : acks = all 동일한 옵션, Producer가 전송한 메시지가 Leader, Flower 모든 Replica까지 Commit 되면 ACK를 보낸다. Leader를 잃어도 데이터가 살아남을 수 있도록 보장한다. 

* 다른 옵션에 비해 대기 시간이 더 길고, 특정 실패 사례에서 반복되는 가능성이 존재한다. (최소 한 번 전송을 보장한다.)


Producer Retry

  • 재전송을 위한 Producer Parameter
  • 재시도(retry)는 네트워크 또는 시스템의 일시적인 오류를 보완하기 위해 모든 환경에서 중요하다.
retries 메시지를 Send하기 위해 재시도하는 횟수 default = MAX_INT
retry.backoff.ms 재시도 사이에 추가되는 대기 시간 default = 100
delivery.timeout.ms send() 후 성공 또는 실패를 보고하는 시간의 상한 default = 120,000(2분)
request.timeout.ms Producer가 응답을 기다리는 최대 시간 default = 30,000(30초)
  • 보통은 retries를 조정하는 것이 아닌 delivery.timeout.ms 조정으로 재시도 동작을 제어한다.

Producer Batch 처리

  • 메시지를 한 번에 모아서 전송
  • Batch 처리는 RPC(Remote Procedure Call)수를 줄여서 Broker가 처리하는 작업이 줄어들기 때문에 더 나은 처리량을 제공한다.
linger.ms 메시지가 함께 Batch 처리될 때까지의 대기 시간 default = 0, 일반 설정 = 100 ms
batch.size 보내기 전 Batch의 최대 크기 default = 16KB, 일반 설정 = 1000000
  • batch.size로 배치 처리를 조정하는 것이 아니라 linger.ms로 배치 처리를 조정한다. -> batch.size만큼 데이터가 안 쌓일 가능성이 존재하기 때문이다.
  • linger.ms 시간만큼, batch에 데이터를 저장하고 전송한다.

Producer Delivery Timeout

  • send() 후 성공 또는 실패를 보고하는 시간의 상한
  • Producer가 생성한 Record를 send()할 때의 Life Cycle

Message Send 순서 보장

  • 진행 중인 여러 요청을 재시도하면 순서가 변경될 수 있다.
  • Batch로 데이터를 전송할 때, max.in.flight.requests.per.connection = 5 (default) 개수만큼 데이터가 네트워크 상으로 전송된다.
  • 이때, 처음 전송된 batch 0이 실패되고, batch 1...4는 성공한다면 Batch 0보다 Batch 1이 먼저 Commit Log(Partition)에 추가되어 순서가 달라질 수 있다.
  • 이런 상황을 방지하는 데 사용하는 옵션이 Producer 쪽에서 설정할 수 있는 enable.idempotence이다.
  • 해당 옵션을 true로 설정하면, 하나의 Batch가 실패하면, 같은 Partition으로 들어오는 후속 Batch들도 OutOfOrderSequenceException과 함께 실패한다.

Page Cache, Flush

  • 메시지는 Broker로 전송되고, Disk에 저장된다.
  • Partition은 Log Segment Filef로 구성되어 있다. (default : 1GB마다 새로운 Segment를 생성한다.)
  • Broker는 성능을 위해 Log Segment라는 OS Page Cache에 저장한다. -> 이후 나중에 Flush를 진행한다.
  • 로그 파일에 저장된 메시지의 데이터 형식은 Broker가 Producer로부터 수신한 것, Consumer로 보내지는 것과 동일하므로 Zero-Copy가 가능하다.
  • Broker가 완전히 종료되면, OS background "Flusher Thread" 실행 -> 디스크로 Flush된다.
  • OS가 데이터를 디스크로 Flush하기 전에, Borker 시스템에 장애가 발생
    • Partition이 Replication되어 있다면, Broker가 다시 온라인 상태가 될 때, 필요시 Leader Replica에서 데이터가 복구된다.
    • 만일, Replication이 없다면, 데이터는 영구적으로 손실될 수 있다.

* Zero-Copy 전송이란, 데이터가 User Space에 복사되지 않고, CPU의 개입 없이 Page Cache와 Network Buffer 사이에서 직접 전송되는 것을 의미한다. -> 이것을 통해 Broker Heap 메모리를 절약하고 엄청난 처리량을 제공할 수 있다.

 

* Flush 옵션

log.flush.interval.messages 마지막 Flush 이후의 메시지 수
log.flush.interval.ms 마지막 Flush 이후의 시간

해당 옵션을 통해, Flush를 트리거 하도록 설정할 수 있다.

* Kafka는 OS의 background Flush 기능을 허용하는 것을 선호하기 떄문에, 해당 옵션들을 기본값으로 유지하는 것을 권장한다.

* *.log 파일을 보면 디스크로 Flush된 데이터와 아직 Flush되지 않은 Page Cache에 있는 데이터 모두 표시된다.

'Kafka' 카테고리의 다른 글

[Kafka] Replication (1)  (0) 2022.10.12
[Kafka] Consumer (2)  (0) 2022.10.11
[Kafka] Consumer (1)  (0) 2022.10.10
[Kafka] Producer (1)  (0) 2022.10.09
[Kafka] Apache Kafka란?  (0) 2022.10.07