[아파치 카프카 애플리케이션 프로그래밍] 카프카 프로듀서

jj J·2023년 6월 29일
0

Kafka

목록 보기
3/3

프로듀서

  • 카프카에 필요한 데이터를 선언하고 브로커의 특정 토픽의 파티션에 전송
  • 리더 파티션을 갖고 있는 카프카 브로커와 직접 통신

프로듀서 내부 구조

  • ProducerRecord : 프로듀서에서 생성하는 레코드. 오프셋 미포함
    • 오프셋은 카프카 클러스터에 저장 후 지정됨
  • Partitioner : 어느 파티션으로 전송할지 지정하는 파티셔너
    • 메시지 키에 따라 동작
    • 메시지 키를 해시해 키가 동일하면 동일한 파티션으로 전송한다
  • Accumulator : 배치로 묶어 전송할 데이터를 모으는 버퍼
    • 데이터 처리량이 많을 때 성능적 이점
  • Sender : 브로커로 데이터 전송

파티셔너

  • default : UniformStickyPartitioner
  • 메시지 키가 있을 경우 동작
    • 동일한 메시지 키가 존재하는 레코드는 동일한 파티션 번호에 전달됨
    • 만약 파티션 개수가 변경될 경우 메시지 키와 파티션 번호 매칭이 깨지게 됨
      • 처음부터 충분한 개수의 파티션을 확보해놔야 위 문제를 줄일 수 있다
    • UniformStickyPartitioner와 RoundRobinPartitioner 둘 다 메시지 키가 있을 때는 메시지 키의 해시값과 파티션을 매칭하여 레코드 전송
  • 메시지 키가 없을 경우 동작
    • 메시지 키가 없을 때는 파티션에 최대한 동일하게 분배함
    • UniformStickyPartitioner는 RoundRobinPartitioner의 단점을 개선한 버전
    • RoundRobinPartitioner
      • ProducerRecord가 들어오는 대로 파티션을 순회하면서 전송
      • Accumulator에서 묶이는 정도가 적기 때문에 전송 성능이 낮음
    • UniformStickyPartitioner
      • Accumulator에서 레코드들이 배치로 묶일 때까지 기다렸다가 전송
      • 배치로 묶일 뿐 결국 파티션을 순회하면서 보내기 때문에 모든 파티션에 분배되어 전송됨
      • RoundRobinPartitioner에 비해 향상된 성능을 가짐
  • 커스텀 파티셔너
    • 메시지 키 뿐만 아니라 메시지 값까지 확인해서 특정 파티션으로 보내는 로직을 커스텀하게 구현해 쓸 수 있다

프로듀서 주요 옵션(필수)

  • bootstrap.servers
    • 프로듀서가 데이터를 전송할 대상 카프카 클러스터에 속한 브로커의 호스트 이름:포트를 1개 이상 작성
    • 2개 이상 브로커 정보를 입력해 일부 브로커에 이슈가 발생하더라도 접속하는 데 이슈가 없도록 설정 가능
  • key.serializer
    • 레코드의 메시지 키를 직렬화하는 클래스 지정
  • value.serializer
    • 레코드의 메시지 값을 직렬화하는 클래스 지정
    • 웬만하면 String으로 직렬화한다
      • 왜냐하면, kafka-console-consumer를 사용하면 String으로 역직렬화가 가능하기 때문
      • 또한, 다양한 Consumer에서 가져가 역직렬화할 때, String으로 직렬화 기준을 통일하면 디스크/네트워크 용량 측면에서 손실은 있지만 운영상 이점이 있기 때문

프로듀서 주요 옵션(선택)

  • acks
    • 프로듀서가 전송한 데이터가 브로커들에 정상적으로 저장되었는지 전송 성공 여부를 확인하는 데 사용하는 옵션. 기본값은 1
    • 전송만 성공했는지, 리더 파티션에만 저장되었는지, 팔로 파티션까지 복제가 되었는지 등 확인
  • linger.ms
    • 배치를 전송하기 전 까지 기다리는 최소 시간. 기본값은 0
    • 일부 지연을 감수하고 최대한 많은 데이터를 한번에 보내고 싶으면 옵션 지정 가능
  • retries
    • 브로커로부터 에러를 받고 난 뒤 재전송을 시도하는 횟수. 기본값은 2147483647
    • 재전송 필요없으면 값을 줄이거나 0으로 설정
  • max.in.flight.requests.per.connection
    • 한 번에 요청하는 최대 커넥션 개수. 설정된 값만큼 동시에 전달 요청을 수행
    • sender에서 브로커로 데이터 전송 시 커넥션을 생성해서 진행하는데, 브로커로 동시에 전송할 양이 많다면 해당 설정값을 늘려 대응할 수 있음
  • partitioner.class
    • 레코드를 파티션에 전송할 때 적용하는 파티셔너 클래스
    • 2.5.0부터는 UniformStickyPartitioner가 기본값
  • enable.idempotence
    • 멱등성 프로듀서로 동작할지 여부
    • 데이터 중복 전송을 막기 위함
  • transactional.id
    • 프로듀서가 레코드를 전송할 때 레코드를 트랜잭션 단위로 묶을지 여부를 설정
    • 기본값은 null

ISR(In-Sync-replicas)

  • ISR : 리더 파티션과 팔로 파티션이 모두 싱크 된 상태
  • ISR이라는 용어가 나온 이유는 팔로 파티션이 리더 파티션으로부터 데이터를 복제 하는데 시간이 걸리기 떄문
  • 이 복제 시간 차 때문에 리더와 팔로 간 오프셋 차이가 발생함

acks

  • acks 옵션을 통해 카프카 클러스터에 얼마나 신뢰성 높게 저장할지 지정할 수 있다
  • 신뢰성과 성능은 trade-off 관계

acks=0

  • 프로듀서가 리더 파티션으로 데이터를 전송했을 때 리더 파티션으로 데이터가 저장되었는지 확인하지 않는다는 뜻
  • 리더 파티션은 데이터가 저장된 후에 데이터가 몇번째 오프셋에 저장되었는지 리턴하는데
  • acks가 0으로 설정되어 있으면 저장 여부에 대한 응답을 받지 않는다
  • 데이터 전송 속도는 1 또는 all보다 훨씬 빠르다
  • 데이터 일부 유실 발생해도 속도가 중요한 경우에는 이 옵션값 사용하면 됨

acks=1

  • 프로듀서는 보낸 데이터가 리더 파티션에만 정상 적재되었는지 확인함
  • 리더 파티션에 정상 적재되지 않았다면, 적재될때까지 재시도 가능
  • 리더 파티션에 적재되었음을 보장해도 데이터는 유실될 수 있다
  • 복제 개수를 2 이상으로 운영할 경우 리더에 적재 완료되어도 팔로에는 아직 동기화되지 않을 수 있는데, 팔로에서 데이터를 복제하기전에 리더에 장애가 발생하면 동기화되지 못한 데이터는 유실될 수 있기 때문

acks=-1(all)

  • 프로듀서는 보낸 데이터가 리더 파티션과 팔로워 파티션에 모두 정상 적재되었는지 확인함
  • 일부 브로커에 장애가 발생해도 안전히 데이터를 전송하고 저장할 수 있음을 보장할 수 있다
  • 대량 처리시 속도가 너무 느려 처리량이 안좋음
  • min.insync.replicas 옵션값에 따라 팔로워 파티션을 몇개까지 검증할지 정해지고, 안정성이 달라짐(ISR 중 몇개의 파티션에 데이터가 적재되었는지)
    • 2로 설정해 1개의 팔로 파티션만 확인해도 충분
    • 모든 서버가 동시에 장애가 날 확률이 잘 없기 때문

출처 : 인프런 - [아파치 카프카 애플리케이션 프로그래밍] 개념부터 컨슈머, 프로듀서, 커넥트, 스트림즈까지!

profile
매일 발전

0개의 댓글