Kafka에서의 Exactly Once Delivery 구현

메시지 시스템을 사용하다 보면 메시지의 전달 보장 방식에 대해 고려해야 합니다. 일반적으로 다음 세 가지 전달 방식이 있습니다.

  1. At Least Once Delivery: 메시지가 최소 한 번 전달됩니다. 중복 메시지가 발생할 수 있습니다.
  2. At Most Once Delivery: 메시지가 최대 한 번 전달됩니다. 메시지가 손실될 수 있습니다.
  3. Exactly Once Delivery: 메시지가 정확히 한 번 전달됩니다. 중복이나 손실이 없습니다.

Kafka를 사용할 때, 메시지의 정확한 전달을 보장하는 것은 중요한 이슈입니다. 특히 Consumer 측에서 메시지를 처리하는 과정에서 중복이나 손실 없이 메시지를 정확히 한 번씩 처리하도록 구현하는 방법을 알아보겠습니다.


Kafka의 기본 전달 보장 방식

Kafka는 기본적으로 At Least Once Delivery를 제공합니다. 이는 메시지가 최소 한 번 소비자에게 전달됨을 의미하며, 네트워크 장애나 처리 오류로 인해 중복 메시지가 발생할 수 있습니다.


Exactly Once Delivery를 위한 설정과 구현

1. Idempotent Producer 설정

Producer 측에서 동일한 메시지를 여러 번 전송하더라도 중복 없이 처리되도록 설정할 수 있습니다.

  • enable.idempotence 옵션을 true로 설정합니다.

    Properties props = new Properties();
    props.put("enable.idempotence", true);
  • 이 설정을 통해 프로듀서는 메시지 전송 시 고유한 PID(Producer ID)와 시퀀스 넘버를 사용하여 중복 전송을 방지합니다.

2. Transactions 활용

Kafka는 트랜잭션 기능을 통해 메시지의 원자성을 보장합니다.

  • 트랜잭션 초기화

    producer.initTransactions();
  • 트랜잭션 시작과 종료

    try {
        producer.beginTransaction();
        // 메시지 전송 로직
        producer.send(record);
        producer.commitTransaction();
    } catch (Exception e) {
        producer.abortTransaction();
    }

3. Consumer 측의 처리 보장

Consumer에서 Exactly Once Semantics(EOS)를 구현하기 위해서는 다음을 고려해야 합니다.

  • Kafka Streams API 사용

    Kafka Streams는 EOS를 기본적으로 지원하며, 상태 저장 프로세싱에 유용합니다.

  • 오프셋 커밋 관리

    수동으로 오프셋을 커밋하여 메시지 처리와 오프셋 관리의 원자성을 보장합니다.

    consumer.commitSync();
  • 데이터베이스 트랜잭션과 연계

    메시지 처리 결과를 데이터베이스에 저장할 때, Kafka 오프셋 커밋과 데이터베이스 트랜잭션을 연계하여 원자성을 확보합니다.

+ Recent posts