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 |