GW LABS

실전 카프카 개발부터 운영까지 (5) - 프로듀서의 내부 동작 원리와 구현 본문

Book-Review/Programing

실전 카프카 개발부터 운영까지 (5) - 프로듀서의 내부 동작 원리와 구현

GeonWoo Kim 2022. 9. 4. 11:26

5.1 파티셔너

  • 토픽은 성능 향상을 위한 병렬 처리가 가능하도록 파티션으로 나뉘고, 최소 하나 이상의 파티션으루 구성
  • 메시지는 토픽 내 파티션 로그 세그먼트에 저장
  • 토픽의 어느 파티션에 메시지를 저장할지 결정하는 것이 파티셔너
    • 메시지의 키를 해싱하여 처리
  • 트래픽이 많아질 경우 파티션을 늘릴 수 있는데, 이 경우 해시 테이블이 변경되기 때문에 동일 파티션이 아닌 다른 파티션으로 메시지가 전송 될 수 있음
    • 되도록이면 파티션 수를 변경하지 않는 것이 좋음

 

5.1.1 라운드 로빈 전략

  • 키값을 지정하지 않고 메시지가 전송되면 라운드 로빈 방식으로 레코드 전송
  • 배치 전송 옵션을 사용할 경우 라운드 로빈 옵션은 지연시간과 압축 비효율을 발생시킬 수 있음

 

5.1.2 스티키 파티셔닝 전략

  • 하나의 파티션에 리코드 수를 먼저 채워서 카프카로 빠르게 배치전송하는 전략
  • 배치옵션 수를 채워지는 순간 전송처리 하기때문에 성능에서 이점
    • 메시지 순서가 중요하지 않은 경우에는 적용필요

 

5.2 프로듀서의 배치

  • 배치 전송 옵션
    • buffer.memory: 카프카로 메시지들을 전송하기 위해 담아두는 프로듀서의 버퍼 메모리 옵션
    • batch.size: 배치 전송을 위해 메시지들을 무끈 단위를 설정하는 배치 크기 옵션
    • linger.ms: 배치 전송을 위해 버퍼 메모리에서 대기하는 메시지들의 최대 대기시간
    • buffer.memory 크기는 batch.size보다 항상 커야한다!
      • buffer.memory = (topic N + 1) * batch.size
  • 처리량을 높일지, 지연 없는 전송을 해야할지 상황별로 설정해야한다.

 

5.3 중복 없는 전송

  • 적어도 한 번 전송
    • 프로듀서가 ACK를 받지 못하면 다시 한번 전송한다.
    • 브로커가 메시지를 저장하고 있더라도 전송하기 때문에 중복이 발생할 수 있다.
  • 최대 한 번 전송
    • 프로듀서가 ACK를 받지 못하더라도 재전송하지 않는다.
    • 브로커가 메시지를 저장하지 않았다면 메시지가 유실된다.
    • 대량 로그 처리, IOT 서비스 등에서 주로 사용된다.
  • 중복 없는 전송
    • 적어도 한번 전송 과정과 비슷하나 PID와 메시지 번호를 이용해서 이미 저장된 메시지인지 확인한다.
    • 이미 저장된 메시지라면 브로커가 ACK만 보내준다.
    • 성능이 20%가량 떨어지지만 중복제거가 필요하다면 무조건 적용해야 하지 않을까…
    • 중복 없는 전송을 위한 프로듀서 설정
      • enable.idempotence: 프로듀서가 중복 없는 전송을 허용할지 결정하는 옵션
      • max.in.flight.requets.per.connection: ACK를 받지 않은 상태에서 하나의 커넥션에서 보낼 수 있는 최대 요청 수
      • acks: 프로듀서 acks와 관련된 옵션이며 all로 설정해야 함
      • retries: ACK를 받지 못한 경우 재시도를 해야 하므로 설정애햐 함

 

5.4 정확히 한 번 전송

  • DB의 트랜잭션과 동일한 프로세스를 보장하기 위한 기능. 트랜잭션API를 사용할 수 있다.

 

5.4.1 디자인

  • 트랜잭션 코디네이터가 커밋 또는 중단을 관리
  • 내부에 __transaction_state라는 토픽을 통해서 트랜잭션을 관리
    • transaction.state.log.num.partitions=50
    • transaction.state.log.replication.factor=3
  • 프로듀서에서는 트랜잭션을 열고 닫는 코드와 중복 없는 전송 설정과 함께 TRANSACTIONAL_ID_CONFIG를 설정해야 한다.

 

5.4.3 단계별 동작

  1. 트랜잭션 코디네이터 찾기(FindCoordinatorRequest)
  2. 프로듀서 초기화
    1. InitPidRequest를 트랜잭션 코디네이터로 전송
  3. 트랜잭션 시작
  4. 트랜잭션 정보를 트랜잭션 코디네티터에 전송하여 기록
  5. 메시지 전송
  6. 트랜잭션 종료 요청
Comments