728x90
반응형
SMALL
Producer는 Kafka가 Message를 잘 받았는지 어떻게 알까?
Producer Acks
acks 설정은 요청이 성공할 때를 정의하는 데 사용되는 Producer에 설정하는 파라미터.
acks = 0
- acks가 필요하지 않음. 이 수준은 자주 사용되지 않음. 메시지 손실이 다소 있더라도 빠르게 메시지를 보내야 하는 경우에 사용
- 그러니까, Producer들은 메시지를 보내고 잘 받았는지 안 받았는지 관심이 없다는 것.
acks = 1 (기본값)
- Leader가 메시지를 수신하면 ack를 보냄. 그런데, Leader가 Producer에게 Ack를 보낸 후, Follower가 복제하기 전에 Leader에 장애가 발생하면 메시지가 손실. "At most once(최대 한 번)"전송을 보장.
acks = -1 또는 acks = all
- 메시지를 Leader가 모든 Replica까지 Commit 되면 ack를 보냄. Leader를 잃어도 데이터가 살아남을 수 있도록 보장. 그러나 그만큼 대기시간이 더 길다. "At least once(최소 한 번)" 전송을 보장
- 쉽게 말해 모든 Replica가 전부 다 해당 메시지가 복제되면, 그때 ack를 보낸다고 생각하면 된다.
Producer Retry
재전송을 위한 Parameters
Parameter | 설명 | Default 값 |
retries | 메시지를 send 하기 위해 재시도하는 횟수 | MAX_INT |
retry.backoff.ms | 재시도 사이에 추가되는 대기 시간 | 100 |
request.timeout.ms | Producer가 응답을 기다리는 최대 시간 | 30,000 (30초) |
delivery.timeout.ms | send() 후 성공 또는 실패를 보고하는 시간의 상한 | 120,000 (2분) |
- acks = 0 에서는 retry는 무의미하다.
- retries를 조정하는 대신에 delivery.timeout.ms 조정으로 재시도 동작을 제어
Producer Batch
메시지를 모아서 한번에 전송하는 것으로, Batch 처리는 RPC(Remote Procedure Call)수를 줄여서 Broker가 처리하는 작업이 줄어들기 때문에 더 나은 처리량을 제공한다.
- 애플리케이션에서 send()를 호출하면 내부적으로, Serializer에 의해 데이터를 Serialize하고, Partitioner에 의해 어떤 파티션으로 보낼지가 결정된다. 그리고 그 이후, 메시지를 모아서 한번에 보내는 과정이 위 그림의 RecordAccumulator -> ProduceRequest -> Broker 이다.
- 그럼 배치 처리를 하기 위한 옵션은 어떤게 있을까?
- linger.ms (default : 0, 즉시 보냄) : 메시지가 함께 Batch 처리될 때까지 대기 시간
- batch.size (default : 16KB) : 보내기 전 Batch의 최대 크기
- 일반적으로, linger.ms = 100, batch.size = 1000000로 설정해서 배치 사이즈는 크게 잡고, 배치 대기 시간을 짧게 하여 이벤트가 너무 늦게 전송되지도 않고 너무 한번에 바로 바로 전송되지도 않게 한다.
Producer Delivery Timeout
send() 후 성공 또는 실패를 보고하는 시간의 상한
- send()를 호출하는 동안에 영향을 받는 옵션은 max.block.ms 인데, 이는 메시지를 담기 위한 Buffer 할당 대기 시간이다.
- 그 이후 단계부터 영향 받는 범위가 delivery.timeout.ms 이다.
- linger.ms는 메시지가 함께 Batch 처리될 때까지 대기 시간을 의미한다. 너무 길어도 너무 짧아도 안된다.
- retry.backoff.ms는 재시도를 하는데 재시도 사이의 대기 시간을 설정하는 것이다. 재시도를 바로 하는게 아니라 잠깐 기다렸다가 다시 재시도, 잠깐 기다렸다가 다시 재시도하는 것이다.
Message Send 순서 보장
진행 중인 여러 요청을 재시도하면 순서가 변경될 수 있다. 예를 들어, Producer가 메시지를 생성해서 Kafka에 보낼 때 하나의 브로커가 한 커넥션에 한번에 최대로 보낼 수 있는 Batch 메시지 개수를 설정하는 옵션이 있다. 그 옵션이 바로, max.in.flight.requests.per.connection 이고 기본값은 5이다. 그래서 아래 그림과 같이 전송한다고 해보자.
- Topic A - Partition 0에 보낼 배치 메시지를 5개를 모아서 보내는 것이다. 근데 만약, 이 전송을 하는 과정 중에 뭔가 잘못되서 재시도를 했다고 해보자. 예를 들어, Batch 0번을 보내고 1, 2, 3번을 보내야 하는데 0번을 보내는 중에 문제가 발생해서 0번이 안들어가지면 순서가 꼬인다는 것이다.
- 1번이 먼저 들어와서 2,3,4번이 들어오고 이제 0번을 못 보냈으니 재시도를 해서 0번을 보내면 원래라면 0 ~ 4번까지 보내져야 할 것이 1 ~ ,4,0번 순서로 들어온 것이다.
- 이런 경우가 발생할 수 있는데 이럴때 메시지 순서를 보장하려면, Producer에서 enable.idempotence를 true로 설정하면 된다.
- 이 옵션을 키게 되면, 하나의 Batch가 실패하면 같은 Partition으로 들어오는 후속 Batch들도 모두 실패하게 한다.
Page Cache, Flush
- 메시지는 Partition에 기록된다.
- Partition은 Segment File로 구성되어 있다. (기본값: 1GB마다 새로운 Segment 파일 생성)
- 성능을 위해 Segment는 OS Page Cache에 기록된다.
- Segment 파일에 저장된 메시지의 데이터 형식은 Broker가 Producer로부터 수신한 것, 그리고 Consumer에게 보내는 것과 정확히 동일하므로 Zero-Copy가 가능하다.
- Zero-Copy란, 데이터가 네트워크를 통해서 들어올텐데 그 네트워크를 통해 들어오는 데이터는 Network Buffer에 담겨서 들어온다. 이 Buffer에서 Broker를 거쳐서 데이터를 복사해서 OS Page Cache에 저장되는 게 아니라, 다이렉트로 Network Buffer에서 OS Page Cache로 전송되는 것을 의미한다. 이러면, Broker Heap 메모리를 절약하고 CPU 개입이 필요없어 지기 때문에 처리량에서 매우 유리하다.
- Page Cache는 다음과 같은 경우, 디스크로 Flush 된다.
- Broker가 완전히 종료
- OS Background "Flusher Thread" 실행 (OS 레벨에서 자동으로 해주는 작업)
Flush 되기 전에 Broker 장애가 발생하면?
- OS가 데이터를 디스크로 Flush 하기 전에 Broker의 시스템에 장애가 발생하면 해당 데이터가 손실될 수 있다.
- Partition이 Replication되어 있다면, Broker가 다시 온라인 상태가 되면 필요시 Leader Replica에서 데이터가 복구됨
- Replication이 없다면, 데이터는 영구적으로 손실될 수 있다.
Kafka 자체 Flush 정책
- 마지막 Flush 이후의 메시지 수(log.flush.interval.messages) 또는 시간(log.flush.interval.ms)으로 Flush(fsync)를 트리거하도록 설정할 수 있다.
- 그러나, Kafka는 운영 체제의 background Flush 기능(예: pdflush)을 더 효율적으로 허용하는 것을 선호하기 때문에 이러한 설정은 기본적으로 무한(기본적으로 fsync 비활성화)으로 설정
- 이러한 설정을 기본값으로 유지하는 것을 권장
- *.log 파일을 보면 디스크로 Flush된 데이터와 아직 Flush 되지 않은 Page Cache (OS Buffer)에 있는 데이터가 모두 표시된다.
- Flush된 항목과 Flush되지 않은 항목을 표시하는 Linux 도구(예: vmtouch)도 있다.
정리를 하자면
- Producer Acks: 0, 1, all(-1)
- Batch 처리를 위한 옵션 : linger.ms, batch.size
- 메시지 순서를 보장하려면, Producer에서 enable.idempotence를 true로 설정
- 성능을 위해 Segment는 OS Page Cache에 기록된다.
728x90
반응형
LIST
'Apache Kafka' 카테고리의 다른 글
p9. Replica Recovery (0) | 2025.03.16 |
---|---|
p8. Replica Failure (0) | 2025.03.15 |
p6. Replication (0) | 2025.03.15 |
p5. Consumer (0) | 2025.03.15 |
p4. Producer (0) | 2025.03.15 |