본문 바로가기
  • 노션에서 삽질한 내용을 정리하는 블로그
자기발전소/# Kafka_Confluent

[Kafka] Idempotent Producer

by iamlucia 2022. 4. 10.

Idempotent Producer에 대하여 정리하는 글

 Idempotent producer란 : 프로듀서로부터 들어오는 데이터가 카프카에 "정확히 딱 한번"만 쓰여지게 한다.

 

1. Exactly-once is a really hard problem 

"정확히 한 번 전송" 의 구현이 왜 어려운가하면,
딱 한 사이드에만 무언가를 설정해서 구현할 수 있는 것이 아니고
카프카 메세징 시스템과 클라이언트 어플리케이션 간에 cooperate가 되어야
EOS (Exactly once semantics) 가 가능하기 때문이다. 

1-1. Producer 단에서 어떻게 설정해야 할까 

1) Idempotent Producer가 필요한 이유 

대체적으로 프로듀서가 메세지를 전송할 때 메세지 유실을 방지하기 위해 아래와 같이 설정한다.

  •   acks=all
  •   retries > 0

이를 통해 producer가 카프카로부터 ack 를 받을 때까지 여러번 retry 하고 각 레코드가 제대로 produce되었는지를 확인하게 된다. 

그런데, 이렇게 Produce하는 과정에서 아래와 같이 예기치않은 에러가 발생하는 경우 메세지 중복의 이슈가 발생할 수 있다.

 예) m1을 이미 다 받은 leader와 follower1,follwer2에 m2 배치를 전송하는 상황:
갑자기 leader가 fail되어 
follower1(m1,m2다 받은 상태)이 leader로 선정되는 경우,
Producer 입장에서는 m
2에 대한 acks를 다 받지 못해서 (왜냐하면, follower2는 아직 m2를 commit하지 못해서 producer쪽에 ack를 보내지 못한 상황) m2를 재전송하게 되고 이때 leader는(구 follower1) m2를 두번 받게 된다.

이에 대한 해결책이 Idempotent Producers이다. 

2) 중복이벤트가 발생하지 않도록 설정하기 

중복방지를 위해서는 아래의 설정이 추가로 필요하다. 
  •   enbale.idempotence=true
  •   acks=all
이와 같이 프로듀서를 설정하는 경우, 일시적인 브로커 fail로 producer가 메세지 전송을 retry하더라도
메세지가 중복되지 않도록 한다.

3) 어떻게 중복처리를 방지할까 

메세지 포맷에 producer id와 sequence number를 헤더에 추가함으로써 가능한 매커니즘이다.
  •  Producer ID: 프로듀서 세션에 대한 고유한 id
  •  Sequence number:  프로듀서가 보내는 각 메세지별로 부여되는 순차적으로 증가하는 sequence number

브로커는 PID와 Sequence Number를 매핑하여  메모리에 저장하는데, { PID : sequence number } 이는

.snapshot 이라는 파일 로그에  스냅샷된다. 브로커가 fail되었다가 복구되었을 때 로그를 읽어서 현재 매핑된 PID: Sequence Number를 catch-up 할 수 있지만, 이는 오래 걸릴 수 있다. 하지만 .snapshot 파일을 사용하면 해당 프로세스의 시간은 단축된다.

 

4) Idempotent Producer의 Trade-off는 ? 

Idempotent Producer를 활성화하는 것은 성능에 영향을 미치지만, 무시가능한 수준이다. 

Idempotence 를 활성화하는 경우, max.in.flight.requests.per.connection 옵션은 5보다 같거나 적고, retries는 0 보다는 충분히 커야 하고, acks 는 all 로 설정되어야 한다. 만약 이 조건에 맞지 않게 값이 설정되는 경우,  ConfigException이 발생한다. 

 

1-2. Consumer 단에서도 처리를 해주어야 한다.

- The Downstream Consumer : 메세지가 딱 한번만 처리되게 하기 위해서 idempotence 관련 설정이 필요하다. 
이에 대한 설명은 다음 글에서 추가로 덧붙여야겠다