5.3 중복 없는 전송
- 카프카는 개발 편의를 높이기 위해 중복 없이 전송할 수 있는 기능을 제공한다.
- 메시징 시스템들은 다음 전송 방식을 제공한다.
- 적어도 한 번 전송
- 최대 한 번 전송
- 정확히 한 번 전송
적어도 한 번 전송
- 프로듀서가 브로커의 특정 토픽으로 메시지 A를 전송
- 브로커는 메시지 A를 기록하고 잘 받았다는 ACK를 프로듀서에 응답
- 브로커의 ACK를 받은 프로듀서는 다음 메시지 B를 브로커에 전송
- 브로커는 B를 기록하고 ACK를 보내려 하지만 오류나 장애로 인해 보내지 못함
- 프로듀서는 브로커가 메시지 B를 받지 못했다고 판단해 B를 재전송
- 브로커가 B를 기록했지만 ACK를 받지 못한 프로듀서가 다시 메시지 B를 전송하기 때문에 메시지 중복 위험이 있다.
최대 한 번 전송
- 프로듀서가 브로커의 특정 토픽으로 메시지 A를 전송
- 브로커는 A를 기록하고 프로듀서에 ACK를 응답
- 브로커의 ACK를 받은 프로듀서는 다음 메시지 B를 브로커에 전송
- 브로커는 B를 기록하지 못하고 ACK를 프로듀서에게 전송하지 못함
- 프로듀서는 브로커가 메시지 B를 잘 받았다고 가정하고 메시지 C를 전송
- ACK가 없어도 재전송을 하지 않기에 메시지가 유실될 수 있지만 중복 전송은 없다.
정확히 한 번 전송
- 카프카 0.11 버전에선 중복 없는 전송 기능이 추가되었다.
- 프로듀서가 브로커의 특정 토픽으로 메시지 A를 전송 (PID: 0, 메시지 번호: 0)
- 브로커는 메시지 A를 저장하고 PID와 메시지 번호를 메모리에 기록하고 ACK를 응답
- 프로듀서는 다음 메시지 B를 브로커에 전송 (PID: 0, 메시지 번호: 1)
- 브로커는 B를 저장하고 PID와 메시지 번호를 메모리에 기록하지만 ACK를 전송하지 못함
- 브로커로부터 ACK를 받지 못한 프로듀서는 브로커가 B를 받지 못했다고 판단해 B를 재전송
- 프로듀서가 B를 재전송한 후 브로커 동작의 차이가 있다.
- 메시지 B 헤더에서 PID와 메시지 번호를 비교해 이미 브로커에 저장되어 있는 것을 확인한 후 중복 저장하지 않고 ACK만 보낸다.
- PID는 프로듀서에 의해 자동 생성된다.
- 카프카 내부적으로만 사용되며 사용자에게 따로 노출되지 않는다.
- PID와 시퀸스 번호는 리플리케이션 로그에도 저장되기에 리더가 변경되더라도 문제 없다.
- 중복 없는 전송을 위해 프로듀서에 다음 설정이 필요하다.
enable.idempotence
= true
max.in.flight.requests.per.connection
= 1 ~ 5
- ACK를 받지 않는 상태에서 하나의 커넥션에서 보낼 수 있는 최대 요청 수
- 기본값은 5이며 5이하여야 한다.
acks
= all
- 프로듀서 acks와 관련된 옵션
- 기본값은 1이며 all로 설정해야 한다.
retires
= 5
- ACK를 받지 못하면 재시도하는 횟수
- 0보다 크게 설정해야 한다.