Kafka Producer 간단 정리

라모스·2023년 5월 22일
0

Kafka

목록 보기
2/3
post-thumbnail

프로듀서의 기본 흐름과 Sender의 기본 동작

처리량 관련 속성

  • batch.size: 배치 크기. 배치가 다 차면 바로 전송
  • linger.ms: 전송 대기 시간. (기본값 0)
    • 대기 시간이 없으면 배치가 덜 차도 브로커로 바로 전송
    • 대기 시간을 주면 그 시간 만큼 배치에 메시지 추가가 가능해서 한 번의 전송 요청에 더 많은 데이터 처리 가능

전송 결과 확인 안함

producer.send(new ProducerRecode<>("simple", "value"));

  • 전송 실패를 알 수 없음
  • 실패에 대한 별도 처리가 필요없는 메시지 전송에 사용

전송 결과 확인 함: Future

Future<RecordMetadata> f = producer.send(new ProducerRecord<>("topic", "value"));

try {
    RecordMetadata meta = f.get(); // blocking
} catch (ExecutionException e) {

}
  • 배치 효과 떨어짐 → 처리량 저하
    • 건 별로 확실하게 전송
  • 처리량이 낮아도 되는 경우에만 사용

전송 결과 확인 함: Callback

producer.send(new ProducerRecord<>("topic", "value"),
    new Callback() {
        @Override
        public void onCompletion(RecordMetadata metadata, Exception e) {
        
        }
    }
);
  • 처리량 저하 없음

전송 보장과 acks

  • acks = 0
    • 서버 응답을 기다리지 않음
    • 전송 보장도 zero
  • acks = 1
    • 파티션의 리더에 저장되면 응답 받음
    • 리더 장애시 메시지 유실 가능
  • acks = all (or -1)
    • 모든 리플리카에 저장되면 응답 받음
    • 브로커 min.insync.replicas 설정에 따라 달라짐

acks + min.insync.replicas

  • min.insync.replicas (브로커 옵션)
    • 프로듀서 acks 옵션이 all일 때 저장에 성공했다고 응답할 수 있는 동기화된 리플리카 최소 개수

예를 들어, 리플리카의 개수가 3이고 acks = all, min.insync.replicas = 2 일 땐 그림과 같이 리더에 저장하고 팔로워 중 한 개에 저장하면 성공 응답을 보내준다.

다른 예시로, 리플리카의 개수가 3이고 acks = all, min.insync.replicas = 1인 경우 리더에 저장되면 성공 응답을 보내준다. acks = 1과 동일하게 작동하여 리더 장애시 메시지의 유실 가능성이 있다.

리플리카의 개수가 3이고 acks = all, min.insync.replicas = 3인 경우 리더와 팔로워 2개에 저장되면 성공 응답을 보내준다. 팔로워 중 한 개라도 장애가 나면 리플리카 부족으로 항상 저장에 실패하게 된다.

min.insync.replicas 옵션은 리플리카의 개수와 동일하게 지정하면 안된다.

에러 유형

  • 전송 과정에서 실패
    • 전송 타임 아웃(일시적인 네트워크 오류 등)
    • 리더 다운에 의한 새 리더 선출 진행 중
    • 브로커 설정 메시지 크기 한도 초과
  • 전송 전에 실패
    • 직렬화 실패, 프로듀서 자체 요청 크기 제한 초과
    • 프로듀서 버퍼가 차서 기다린 시간이 최대 대기 시간 초과

실패 대응 - 재시도

재시도 가능한 에러는 재시도를 처리한다.

  • ex) 브로커 응답 타임 아웃, 일시적인 리더 없음 등

재시도 위치

  • 프로듀서는 자체적으로 브로커 전송 과정에서 에러가 발생하면 재시도 가능한 에러에 대해 재전송을 시도한다.
    • retries 속성
  • send() 메서드에서 Exception 발생 시 예외 타입에 따라 send() 재호출
  • 콜백 메서드에서 Exception을 받으면 타입에 따라 send() 재호출
  • 아주 특별한 이유가 없다면 무한 재시도를 사용하지 말자.
    • 재시도를 한다는 것은 다음 보내야 할 메시지가 밀린다는 뜻과 같다.
    • 전체 메시지가 밀리지 않도록 해야 함.

실패 대응 - 기록

  • 추후 처리 위해 기록
    • 별도 파일, DB 등을 이용해서 실패한 메시지를 기록한다.
    • 추후에 수동(or 자동)으로 보정 작업을 진행한다.

기록 위치

  • send() 메서드에서 Exception 발생 시
  • send() 메서드에서 전달한 콜백에서 Exception 받는 경우
  • send() 메서드가 리턴한 Futureget() 메서드에서 Exception 발생 시

재시도와 메시지 중복 전송 가능성

  • 브로커 응답이 늦게 와서 재시도할 경우 중복 전송 가능

enable.idempotence 속성을 사용하면 중복 전송 가능성을 줄일 수 있다.

재시도와 순서

  • max.in.flight.requests.per.connection
    • blocking 없이 한 커넥션에서 전송할 수 있는 최대 전송중인 요청 개수
    • 이 값이 1보다 크면 재시도 시점에 따라 메시지 순서가 바뀔 수 있다.
    • 전송 순서가 중요하면 이 값을 1로 지정하자.

References

profile
Step by step goes a long way.

0개의 댓글