[아파치 카프카 어플리케이션 프로그래밍] 17. 멱등성(idempotence) 프로듀서와 트랜잭션(transaction) 프로듀서

반응형
728x90
반응형

멱등성

여러번 연산을 수행하더라도 동일한 결과를 나타내는 것을 뜻한다.

멱등성 프로듀서는 동일한 데이터를 여러번 전송하더라도 카프카 클러스터에 단 한번만 저장됨을 의미한다. 

기본 프로듀서의 동작 방식은 적어도 한번 전달(at least once delivery)을 지원한다. 

적어도 한번 전달이란, 프로듀서가 클러스터에 데이터를 전송하여 저장할 때 적어도 한번 이상 데이터를 적재할 수 있고 데이터가 유실되지 않음을 뜻한다. 두번 이상 적재되어 중복이 발생할 가능성은 있다.

 

 

멱등성 프로듀서

멱등성 프로듀서는 기본 프로듀서와 달리 데이터를 브로커로 전달할때 프로듀서 PID(Producer unique ID)와 시퀀스 넘버(sequence number)를 함께 전달한다. 그러면 브로커는 프로듀서의 PID와 시퀀스 넘버를 확인하여 동일한 메시지의 적재 요청이 오더라도 단 한번만 데이터를 적재한다.

 

enable.idempotence 옵션

정확히 한번 전달을 지원한다. 기본값은 false이고, true일 경우 멱등성 프로듀서로 동작하게된다.

 

  • 멱등성 프로듀서로 동작하지 않은 경우

프로듀서와 브로커 사이의 네트워크 장애로 데이는 한번 이상 전달될 수 있다.

 

https://velog.io/@jwpark06/%EC%9E%A5%EC%95%A0%EC%97%90-%EB%8C%80%EC%9D%91%ED%95%98%EB%8A%94-Kafka

 

  • 멱등성 프로듀서의 경우

네트워크 장애가 발생하더라도 브로커에 동일한 메시지는 적재하지 않는다.

멱등성 프로듀서가 전송하는 데이터에 PID와 시퀀스 넘버가 있는데, 브로커는 PID와 시퀀스 넘버로 중복을 체크한다.

https://velog.io/@jwpark06/%EC%9E%A5%EC%95%A0%EC%97%90-%EB%8C%80%EC%9D%91%ED%95%98%EB%8A%94-Kafka

 

 

동일한 세션

멱등성 프로듀서는 동일한 세션에서만 정확히 한번 전달을 보장한다.

동일한 세션이란, PID의 생명주기를 뜻한다.

 

만약 멱등성 프로듀서로 동작하는 프로듀서 애플리케이션에 이슈가 발생하여 종료되고 애플리케이션을 재시작하면 PID가 달라진다. 동일한 데이터를 보냈다 하더라도, PID가 달라지면 브로커 입장에서 다른 프로듀서 애플리케이션이 다른 데이터를 보냈다고 판단하여 중복이 발생할 수 있다.

멱등성 프로듀서는 장애가 발생하지 않을 경우에만 정확히 한번 적재하는 것을 보장한다.

 

 

enable.idempotence = true 설정으로 인한 옵션 강제 설정

  • retries : Integer.MAX_VALUE
  • acks : all

프로듀서가 적어도 한번 이상 브로커에 데이터를 보냄으로써 브로커에 단 한번만 데이터가 적재되는 것을 보장하기 위해서다. 

 

정확히 말하자면, 멱등성 프로듀서가 정확히 한번 브로커에 데이터를 적재하기 위해 정말로 한번 전송하는 것이 아닌, 상황에 따라 프로듀서가 여러번 전송하되 브로커가 여러번 전송된 데이터를 확인하고 중복된 데이터는 적재하지 않는 것이다.

 

 

 

OutofOrderSequenceException

멱등성 프로두서의 시퀀스 넘버는 0부터 시작하여 +1씩 증가한다. 브로커에서 멱등성 프로듀서가 전송한 데이터의 PID와 시퀀스 넘버를 확인하는 과정에서 시퀀스 넘버가 일정하는 않은 경우에 발생하는 에러다. 

ex) 시퀀스 넘버 0 다음에 1이 와야 하는데, 다음에 시퀀스 2로 데이터가 존재할 경우

 

 

 

트랜잭션 프로듀서

다수의 파티션에 데이터를 저장할 경우 모든 데이터에 대해 동일한 원자성(atomic)을 만족시키기 위해 사용한다. 원자성을 만족시킨다는 의미는 다수의 데이터를 동일 트랜잭션으로 묶음으로써 전체 데이터를 처리하거나 전체 데이터를 처리하지 않도록 하는 것을 의미한다.

 

컨슈머는 기본적으로 프로듀서가 보내는 데이터가 파티션에 쌓이는 대로 모두 가져가서 처리한다.

그러나 트랜잭션으로 묶인 데이터를 브로커에서 가져갈때는 다르게 동작하도록 설정할 수 있다.

 

프로듀서와 컨슈머는 트랜잭션으로 처리 완료된 데이터만 읽고 쓰도록 설정
  • enable.idempotence = true 설정하고 transactional.id를 임의의 String 값으로 정의한다.
  • 컨슈머의 isolation.level을 read_committed로 설정한다.

 

 

파티션의 레코드 구분

트랜잭션 프로듀서는 사용자가 보낸 데이터를 레코드로 파티션에 저장할 뿐만 아니라 트랜잭션의 시작과 끝을 표현하기 위해 트랜잭션 레코드를 한개 더 보낸다. 

트랜잭션 컨슈머는 파티션에 저장된 트랜잭션 레코드를 보고 트랜잭션이 완료(commit)되었음을 확인하고 데이터를 가져간다.

 

트랜잭션 레코드
  • 실질적인 데이터를 가지고 있지 않으며, 트랜잭션이 끝난 상태를 표시하는 정보만 가지고있다.
  • 레코드의 특성은 그대로 가지고 있으므로, 파티션에 저장되어 오프셋을 한개 차지한다.

 

트랜잭션 컨슈머는 커밋이 완료된 데이터가 파티션에 있을 경우에만 데이터를 가져간다. 만약 데이터만 존재하고 트랜잭션 레코드가 존재하지 않으면 아직 트랜잭션이 완료되지 않았다고 판단하고 데이터를 가져가지 않는다.

 

 

 

 

반응형

Designed by JB FACTORY