Apache Kafka - 프로듀서의 재시도 메커니즘 & 멱등 프로듀서

이건·2025년 5월 5일
0

Kafka

목록 보기
13/18

Apache Kafka 프로듀서가 브로커에 메시지를 전송할 때 네트워크 문제나 브로커 장애 등으로 실패할 수 있다. 이런 상황에서 데이터 손실을 방지하기 위해 Kafka는 재시도 메커니즘을 제공한다.


프로듀서 재시도가 필요한 이유

프로듀서에서 Kafka 브로커로 데이터 전송이 실패하면 적절한 예외 처리가 없을 경우 데이터가 손실될 수 있다. 대표적인 실패 사례로는 NOT_ENOUGH_REPLICAS 예외가 있다. 이는 min.insync.replicasacks=all 설정을 사용할 때 충분한 레플리카가 없는 경우 발생한다.

이러한 일시적인 실패를 자동으로 처리하기 위해 Kafka는 재시도 메커니즘을 제공한다.


주요 재시도 관련 설정

1. retries

메시지 전송 실패 시 재시도할 횟수를 지정합니다.

  • Kafka 2.0 이하: 기본값 0 (재시도 없음)
  • Kafka 2.1 이상: 기본값 Integer.MAX_VALUE (2,147,483,647)

최신 버전의 Kafka를 사용한다면 사실상 무한 재시도가 기본 설정이지만, 하위 버전 클라이언트를 사용하는 경우 명시적으로 설정해야 한다.

2. retry.backoff.ms

재시도 사이의 대기 시간을 밀리초 단위로 지정한다.

  • 기본값: 100ms
  • 이 설정은 브로커에 과도한 부하를 주지 않기 위해 중요하다.

3. delivery.timeout.ms

Kafka 2.1 버전부터 도입된 설정으로, 메시지 전송 시도의 총 제한 시간을 지정한다.

  • 기본값: 120,000ms (2분)
  • 이 타임아웃 내에 메시지가 성공적으로 전송되지 않으면 최종 실패로 간주된다.
  • 이 설정은 다른 모든 타임아웃 설정을 포괄한다.

4. request.timeout.ms

각 요청에 대한 응답을 기다리는 최대 시간이다.

  • 기본값: 30,000ms (30초)
  • 이 시간 내에 응답이 오지 않으면 재시도가 발생한다.

메시지 순서와 관련된 중요 고려사항

재시도 메커니즘을 사용할 때 주의해야 할 중요한 점은 메시지 순서가 바뀔 수 있다는 것이다. 특히 하위 버전의 Kafka에서는 이 문제가 더 두드러진다.

예를 들어:
1. 메시지 A를 전송 후 실패
2. 메시지 B를 전송 후 성공
3. 메시지 A를 재시도 후 성공

이 경우 원래 순서는 A→B였지만, 브로커에는 B→A 순서로 저장된다.

해결책: max.in.flight.requests.per.connection

메시지 순서를 보장하기 위한 설정이다.

  • 기본값: 5
  • 순서 보장을 위한 설정: 1

하위 버전의 Kafka에서 메시지 순서가 중요하다면 이 값을 1로 설정해야 한다. 이렇게 하면 한 번에 하나의 요청만 처리되므로 순서가 보장된다.

Properties producerProps = new Properties();
producerProps.put("max.in.flight.requests.per.connection", 1);

다만, 이 설정은 처리량(throughput)에 영향을 줄 수 있다. 한 번에 여러 요청을 보낼 수 없기 때문이다.


Kafka 1.0 이상 버전을 위한 대안: 멱등 프로듀서(Idempotent Producer)

멱등 프로듀서는 Apache Kafka에서 메시지 중복 전송 문제를 해결하기 위한 핵심 기능이다. 네트워크 오류나 타임아웃으로 인해 발생할 수 있는 데이터 중복과 순서 문제를 효과적으로 방지한다.

멱등 프로듀서란?

멱등 프로듀서는 동일한 데이터에 대해 쓰기 요청이 반복적으로 일어나도 한 번만 쓰기가 발생한 것과 동일한 결과를 보장하는 기능이다. 즉, 같은 메시지가 여러 번 전송되더라도 Kafka 토픽에는 단 한 번만 기록된다.

중복 메시지 발생 시나리오

일반적인 프로듀서에서 중복 메시지가 발생하는 과정은 다음과 같다:

  1. 정상 요청 시나리오:

    • 프로듀서가 Kafka에 메시지 전송
    • Kafka가 메시지를 로그에 커밋
    • Kafka가 프로듀서에게 확인 응답(ACK) 전송
    • 프로듀서가 확인 응답을 수신하고 작업 완료
  2. 중복 요청 시나리오:

    • 프로듀서가 Kafka에 메시지 전송
    • Kafka가 메시지를 로그에 커밋
    • Kafka가 확인 응답(ACK)을 전송했으나 네트워크 오류로 인해 프로듀서에게 도달하지 못함
    • 프로듀서는 확인 응답을 받지 못해 재시도 설정에 따라 동일 메시지를 다시 전송
    • Kafka는 이를 새로운 요청으로 인식하여 동일 메시지를 다시 커밋
    • 결과적으로 토픽에는 동일한 메시지가 두 번 저장됨

멱등 프로듀서의 작동 원리

멱등 프로듀서는 이러한 중복 문제를 다음과 같은 방식으로 해결한다:

  1. 각 프로듀서에 고유 ID(PID)를 할당한다.
  2. 각 메시지에 단조 증가하는 시퀀스 번호를 부여한다.
  3. 브로커는 PID와 시퀀스 번호 조합을 추적하여 중복 요청을 식별한다.
  4. 중복 요청이 감지되면 브로커는 메시지를 다시 커밋하지 않고 단순히 확인 응답만 반환한다.

이를 통해 네트워크 오류가 발생하더라도 메시지가 정확히 한 번만 토픽에 기록되도록 보장한다.

멱등 프로듀서의 이점

  1. 데이터 중복 방지: 네트워크 오류나 타임아웃으로 인한 메시지 중복을 방지한다.

  2. 메시지 순서 보장: max.in.flight.requests.per.connection 값이 1보다 크더라도 메시지 순서가 보장된다.

  3. 처리량 향상: 순서 보장을 위해 max.in.flight.requests.per.connection을 1로 설정할 필요가 없어 병렬 처리가 가능해진다.

멱등 프로듀서 설정 방법

Kafka 3.0 이상에서는 멱등 프로듀서가 기본적으로 활성화되어 있다. 그러나 이전 버전에서는 명시적으로 설정해야 한다:

Properties producerProps = new Properties();
producerProps.put("enable.idempotence", true);

멱등 프로듀서를 활성화하면 다음 설정들이 자동으로 조정된다:

  • retries: 최대값으로 설정 (사실상 무한 재시도)
  • max.in.flight.requests.per.connection: Kafka 0.11에서는 1, Kafka 1.0 이상에서는 5로 설정
  • acks: "all"로 설정 (모든 복제본에서 확인)

주의사항 및 제한 사항

  1. 멱등 프로듀서를 사용하려면 acks를 "all"로 설정해야 한다.
  2. min.insync.replicas 설정과 함께 사용하면 데이터 내구성이 더욱 향상된다.
  3. 멱등성은 단일 프로듀서 세션 내에서만 보장된다. 프로듀서가 재시작되면 새로운 PID가 할당된다.
  4. 멱등성은 단일 파티션 내에서만 보장된다. 여러 파티션에 걸친 원자적 쓰기를 위해서는 트랜잭션 API를 사용해야 한다.

요약

  1. Kafka 프로듀서의 재시도 메커니즘은 일시적인 실패로부터 데이터 손실을 방지한다.
  2. 최신 버전의 Kafka에서는 기본적으로 무한 재시도와 2분의 전송 타임아웃이 설정되어 있다.
  3. 메시지 순서가 중요하다면:
    • 하위 버전 Kafka: max.in.flight.requests.per.connection=1 설정
    • Kafka 1.0 이상: 멱등 프로듀서 사용 (enable.idempotence=true)
  4. 재시도 관련 설정은 delivery.timeout.ms, retry.backoff.ms, retries 등을 통해 세밀하게 조정할 수 있다.

멱등 프로듀서는 Kafka 0.11 버전부터 도입되었으며, Kafka 3.0부터는 기본값으로 설정되었다. 이는 Kafka 시스템에서 데이터 정확성과 안정성을 크게 향상시키는 중요한 기능이다.

Kafka 3.0 이전 버전을 사용하고 있다면, 명시적으로 멱등 프로듀서를 활성화하는 것이 강력히 권장된다. 이는 단순히 enable.idempotence=true 설정만으로 가능하며, 이를 통해 데이터 파이프라인의 안정성과 신뢰성을 크게 향상시킬 수 있다.

멱등 프로듀서의 내부 구현에 대해 더 자세히 알고 싶다면, "Kafka 5494" 이슈 참조

0개의 댓글