본문 바로가기

Programming/Apache Kafka

아파치 카프카 실습 (Apache Kafka) / 카프카 프로듀서 - 상세 개념 (acks, 멱등성 프로듀서, 트랜잭션 프로듀서)

반응형

카프카 프로듀서

프로듀서는 카프카에 데이터를 저장하는 첫 단계이다.

카프카 클러스터는 3대 이상의 브로커로 이루어져 있어서 일부 브로커에 이슈가 생기더라도 데이터의 유실을 막을 수 있다.

그러나 유실을 막기 위해서는 프로듀서에서 제공하는 다양한 옵션을 함께 사용해야 한다.

프로듀서의 고급 활용법과 옵션별 동작 방식에 대해 자세하게 알아보자.

 

1. acks 옵션

카프카 프로듀서의 acks옵션은 0,1,all(또는 -1) 값을 가질 수 잇다.

이 옵션을 통해 프로듀서가 전송한 데이터가 카프카 클러스터에 얼마나 신뢰성 높게 저장할지 지정할 수 있다.

acks옵션에 따라 성능이 달라질 수 있다.

 

# acks = 0

acks를 0으로 설정하는 것은 프로듀서가 리더 파티션으로 데이터를 전송했을 때 리더 파티션으로 데이터가 저장되었는지 확인하지 않는다는 뜻이다.

리더 파티션은 데이터가 저장된 이후에 데이터가 몇 번째 오프셋에 저장되었는지 리턴하는데,

acks가 0으로 설정되어 있다면 프로듀서는 리더 파티션에 데이터가 저장되었는지 여부에 대한 응답 값을 받지 않는다.

acks가 0일 때 프로듀서는 전송 하자마자 데이터가 저장되었음을 가정하고 다음 데이터를 전송하기 때문에 데이터 전송이 실패한 경우를 알 수 없다.

따라서 retries가 2 이상으로 설정되어 있더라도 무의미하다.

데이터가 일부 유실이 발생하더라도 전송 속도가 중요한 경우에는 acks를 1또는 all로 했을 경우보다 훨씬 바르기에 이 옵션을 사용하면 좋다.

 

# acks = 1

acks를 1로 설정할 경우 프로듀서는 보낸 데이터가 리더 파티션에만 정상적으로 적재되었는지 확인한다.

리더 파티션에 정상적으로 적재되지 않았다면 적재될 때까지 재시도할 수 잇다.

복제 개수를 2 이상을 운영할 경우 리더 파티션에 적재가 완료되어 있어도 팔로워 파티션에는 아직 데이터가 동기화되지 않을 수 있는데,

팔로워 파티션이 데이터를 복제하기 직전에 리더 파티션이 있는 브로커에 장애가 발생하면 동기화되지 못한 일부 데이터가 유실될 수 있다.

acks=1 로 설정하면 리더 파티션에 데이터가 적재될 때까지 기다린 뒤 응답 값을 받기 때문에 acks=0 보다 전송 속도가 느리다.

 

# acks = all 또는 acks= -1

acks를 all 또는 -1로 설정한 경우 프로듀서는 보낸 데이터가 리더 파티션과 팔로워 파티션에 모두 정상적으로 적재되었는지 확인한다.

리더 파티션뿐만 아니라 팔로워 파티션까지 데이터가 적재되었는지 확인하기 때문에 0 또는 1 옵션보다는 속도가 느리다.

그러나 정상 적재되었는지 기다리기 때문에 일부 브로커에 장애가 발생하더라도 프로듀서는 안전하게 데이터를 전송하고 저장할 수 있음을 보장한다.

acks를 all로 설정한 경우 토픽 단위로 설정 가능한 min.insync.replicas 옵션값에 따라 데이터의 안정성이 달라진다.

all 옵션값은 모든 리더 파티션과 팔로워 파티션의 적재를 뜻하는 것은 아니고 ISR에 포함된 파티션들을 뜻하는 것이기 때문이다.

 

 

2. 멱등성(idempotence) 프로듀서

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

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

프로듀서가 보내는 데이터의 중복 적재를 막기 위해 enable.idempotence옵션을 사용하여 정확히 한번 전달을 지원한다.

멱등성 프로듀서는 데이터를 브로커로 전달할 때 프로듀서 PID(Producer unique ID)와 시퀀스 넘버를 함께 전달한다.

그러면 브로커는 프로듀서의 PID와 시퀀스 넘버를 확인하여 동일한 메시지의 적재 요청이 오더라도 단 한 번만 데이터를 적재함으로써 프로듀서의 데이터는 정확히 한번 브로커에 적재되도록 동작한다.

 

 

 

 

3. 트랜잭션(transaction) 프로듀서

카프카의 트랜잭션 프로듀서는 다수의 파티션에 데이터를 저장할 경우 모든 데이터에 대해 동일한 원자성을 만족시키기 위해 사용된다.

원자성을 만족시킨다는 의미는 다수의 데이터를 동일 트랜잭션으로 묶음으로써 전체 데이터를 처리하거나 전체 데이터를 처리하지 않도록 하는 것을 의미한다.

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

트랜잭션은 파티션의 레코드로 구분한다. 

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

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

트랜잭션 레코드는 실질적인 데이터는 가지고 있지 않으며 트랜잭션이 끝난 상태를 표시하는 정보만 가지고 있다.

대신 레코드의 특성은 그대로 가지고 있기 때문에 파티션에 저장되어 오프셋을 한 개 차지한다.

 

트랜잭션 프로듀사가 COMMIT이라는 트랜잭션 레코드를 추가로 전송

 

트랜잭션 컨슈머는 트랜잭션이 끝난 레코드가 있을 경우에만 데이터를 가져간다.

 

 

 

 

해당 내용 출처 아파치 카프카 애플리케이션 프로그래밍 with 자바

반응형