DevOps/Kafka

[카프카] 멱등성(idempotence) 프로듀서란?

키깡 2024. 9. 17.
728x90

도입

지우(프로듀서)가 하는 말을 포켓몬(컨슈머)이 알아들을 수 없어서,

배틀필드에서 차례대로 시리(브로커)가 포켓몬어로 번역해준다고 하자.

호기롭게 외쳤고, 시리도 들었지만 시리가 통신 오류로 "네 알겠습니다 주인님"을 못했다.

지우가 중꺾마 정신으로 다시 "포켓몬의 백만볼트"를 외치니, 시리는 이제 "포켓몬의 백만볼트"를 두번 삐까츄에게 전달해주고,

삐까츄는 그렇게 탈진해버렸다는 슬픈 이야기...

그렇다면, 어떻게 해야 삐까츄에게 같은 명령이 여러 번 전달되지 않게 할 수 있을까?

프로듀서의 전달방식

프로듀서가 브로커에게 명령을 전달하는 방식에는 아래의 세 가지가 있다.

  • at least once: 적어도 한번 이상 전달 (기본 프로듀서의 동작 방식이며, 데이터가 유실되지 않지만, 이 경우 위 사례처럼 두 번이상 적재하여 중복이 발생할 수 있음.)
  • at most once: 최대 한번 전달
  • exactly once: 정확히 한번 전달

즉 지우는 시리에게서 "네 알겠습니다 주인님"이라는 응답이 안오면 또 전달하는 방법과,
딱 한번만 무조건 전달하는 방법과,
"정확하게 한번만 시리가 받도록" 전달하는 방법이 있다.

어떻게 해야할까?

 

멱등성 프로듀서

  • 동일한 데이터를 여러 번 전송하더라도 브로커에 단 한번만 저장됨을 의미.
  • 프로듀서가 보내는 데이터의 중복 적재를 막기 위해 0.11.0 이후 버전 부터는 프로듀서에서 enable.idempotence 옵션을 사용하여 정확히 한번 전달(exactly once) 지원함.
    • 옵션값의 기본값은 false
    • 카프카 3.0.0부터는 enable.idempotence 옵션값의 기본값은 true(acks=all)로 변경

 

멱등성 프로듀서의 동작

  • 멱등성 프로듀서는 데이터를 브로커로 전달할 때 프로듀서 PID와 시퀀스 넘버를 함께 전달함.
  • 그러면 브로커는 프로듀서의 PID와 시퀀스 넘버를 확인하여 동일한 메시지의 적재 요청이 오더라도 단 한 번만 데이터를 적재함으로써 프로듀서의 데이터는 정확히 한번 브로커에 적재되도록 동작함.
  • enable.idempotence를 true로 설정하면 일부 옵션들이 강제로 설정됨.
    • retries(재전송 횟수)는 기본값으로 Integer.MAX_VALUE로 설정되고, acks 옵션은 all로 설정 됨. 

 

즉, 아래와 같다.

이번에는 보내는 지우가 본인의 이름과 몇 번째하는 명령인 지를 실어서 보내주는 거다.

또 응답이 없다. 하지만...

중꺾마 정신으로 다시 보내도 이번에는 알아서 시리가 중복임을 확인하고, 명령을 적진않고, 잘 받았다는 말만 전해준다.

 

멱등성 프로듀서의 한계

멱등성 프로듀서는 동일한 세션에서만 정확히 한번 전달을 보장한다. 여기서 말하는 동일한 세션이라는 것은 PID의 생명주기를 뜻한다. 만약 프로듀서에 이슈가 생겨 재시작하면 PID가 달라지는데, 동일한 데이터를 보내더라도 PID가 달라지면 브로커 입장에서는 알 수 없기 때문에 프로듀서 장애가 발생하지 않을 경우에만 정확히 한 번 적재하는 것을 보장한다.

즉, 죽다 살아나 기억상실이 된 지우는 본인 이름을 기억하지 못하기 때문에(줄여서 기우), 받는 시리 또한 동일인인지 알 길이 없다. 

 

OutOfOrderSequenceException

시리는 지우(첫번째) 다음 지우의 두번째 명령을 기대할 것이다.

이 때, 두번째는 어떠한 오류에 의해서 받지 못하고, 세번째 명령이 먼저 왔다고 하자.

그러면 sequence number가 일정하지 않기 때문에 sequence 순서가 엉망이라고 예외처리를 한다.

댓글