idempotence란?
- producer는 메시지를 전송할 때, producer ID와 메시지 시퀀스를 Header에 저장하여 전송하는 방식
- 메시지 시퀀스: 메시지 고유의 시퀀스 번호. 0부터 시작한다...
- 즉, 고유한 것이니 broker가 중복을 확인하며, 중복된 경우에는 버리고 ack만 전송함.
- 0부터 증가하니, broker가 가진 메시지 시퀀스들에서 1만큼 큰 경우에만 로그를 저장
- producer ID는 각각 고유의 아이디이며, 매 시작시 생성된다.
- 중복없이 전송하는 방식이다.
- 대신에 성능이 감소할 수 있지만, 권장되는 사항이다.
- 사용하려면???....
- enable.idempotence=true
- acks=all
- retries는 0보다 크게
- max.in.flight.requests.per.connection은 1~5로 설정
- 여기에서 메시지 전송 순서를 유지하는 방법...
- a,b,c메시지를 보낸다고 가정...
- a도착후 b가 왔으나 실패, 그리고 c가 온 경우라고 가정...
- 이러면 메시지 시퀀스 번호가 +1이 아니라서 에러가 발생.
- 이를 OutOfOrderSequenceException이 발생한다.
- producer와 broker간의 메시지를 주고 받을때 retry 경우 중복 제거하는 과정이다.
- 하지만 send()로 같은 메시지를 전송하는건 제거 대상이 아님
- 또한 producer 재시작하면 producer id는 바뀌니, 중복 전송 가능
// kafka가 한번에 보낼수 있는 요청의 최대 수
// 높을 수록 더 많은 메시지를 보낼 수 있으나, 중복 매사자 전송 될 수 있다.
props.setProperty(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION , "6" );
// ack에 관한 설정
// acks = 0 은 비동기 , acks=1은 동기( reader patition에게만 ack받음 )
// acks=all은 모든 파티션이 메시지를 받은후 acks를 보낸 경우. 제일 안전하나 성는 저하
props.setProperty(ProducerConfig.ACKS_CONFIG , "0" );
// 메시지 중복 전송을 방지하기 위한 설정
// true로 설정하면 producer가 중복되지 않은, 순차적으로 전송된 메시지를 보장하는 것이 가능
// 기본적으로 위 2개의 설정과 같이 사용함
props.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG , "true");