ohjongsung's Dev Story

Ohjongsung's Dev Story

카프카 튜닝 방안 정리

2020년 01월 04일

카프카는 사용하려는 서비스 목적에 따라 성능 목표를 크게 Throughput, Latency, Durability, Availability 네가지로 분류할 수 있다. 각 목표는 상호 trade-off 관계로 모든 목표를 동시에 모두 최적화 할 수 없다.

Throughtput 최대화 방안

프로듀서

  • 파티션 수 증가
  • batch.size 증가 : 한번에 보내는 양을 증가시켜 전송 횟수 감소
  • Linger.ms 조정 : 프로듀서가 전송전 대기 시간으로 batch.size 가 가득 찰 수 있도록 조정
  • 기본 값 0 : 데이터를 수집하는 순간 broker 로 전송 (지연 시간, 처리량 감소)
  • compression.type : 메시지 압축
  • buffer.memory : 프로듀서가 보내지 못한 메시지를 보관하는 메모리 크기 조정
    • 메모리가 full이 되면, 메시지 전송을 막음
    • 메모리에 여유가 생기거나, max.block.ms 를 초과하면 전송
    • 파티션이 많지 않으면, 조정할 필요 없음.
    • 파티션이 많다면, 메모리를 늘려서 블락없이 더 많은 데이터가 전송되도록 설정

컨슈머

  • 컨슈머과 파티션을 1 : 1
  • fetch.min.bytes : 컨슈머가 가져오는 최소 데이터 사이즈 (기본값 1 byte)
    • 이 값보다 적은 데이터가 있으면 브로커에서 보내지 않음
    • 값 증가시키면 프로듀서의 batch.size 증가와 동일 효과
  • fetch.max.wait.ms : 컨슈머에서 데이터를 가져오는 최소 시간 (기본값 500 ms)
    • 새로운 데이터가 입력되어도, 해당 시간 이전에는 가져가지 않는다.
    • 내부적으로 컨슈머가 fetch 요청을 해도, 브로커가 보내지 않음

Latency 최소화 방안

브로커

  • 파티션 개수 제한
  • 너무 많은 파티션은 메시지 지연을 유발, 파티션 복사를 위한 시간만큼 지연 (ACK > 1)
  • 브로커 수 증가, 파티션 수 적게
    • 하나의 브로커에서 감당하는 파티션서를 감소시켜 복제에 소요되는 시간을 최소화
  • Num.replica.fetchers
    • Follower broker 의 I/O 병렬 수준을 정의 (기본값 1)
    • Leader broker 에서 데이터를 복제하는 thread 의 개수

프로듀서

  • Linger.ms : 프로듀서가 전송전에 기다리는 시간
    • batch.size 가 꽉 찰 수 있도록 시간 설정
    • 기본 값 0 : 데이터를 수집하는 순간 broker 로 전송 (지연 시간, 처리량 감소)
  • compression.type :압축이 필요한지 검토
    • CPU : 압축을 위한 자원 사용
    • NW : 압축된 경우 NW bandwidth 사용량 줄어듬
    • 압축 성능에 따라 cpu 사용, NW bandwidth 줄여서 지연 최소화 가능
  • Acks
    • 언제 broker로부터 메시지 전송 결과를 받을 것인지 정의
    • 1 : 데이터 복제 없이, 원본만 저장되면 결과 리턴

컨슈머

  • fetch.min.bytes (기본값 1)
    • broker 에서 데이터를 가져오는 최소 size
    • 1 : 1byte 만 있어도 요청시 바로 전송 (지연 없음)

Durability 보장 방안 (메시지 유실 최소화)

브로커

  • replication.factor
    • 3 : 높은 수준의 durability 지원
  • default.replication.factor
    • auto.create.topics.enable 가 true 인 경우, 자동으로 생성되는 topic 의 복제수 설정
    • 운영상의 안정성을 위해 false 설정을 권장
  • acks = all (acks = -1 동일)
    • 모든 replica 에 복제가 완료된 후, producer 에 ack 리턴
  • broker.rack
    • 하나의 rack 에 brocker 가 동작하지 않도록 설정
    • cloud 기반 서비스에서 brocker 가 각각 다른 zone 에 구동되도록 함
    • 안정성은 높아지지만 데이터 복제시 NW 부하 증가
  • unclean.leader.election.enable
    • broker 가 죽었을 때, OSR replica 도 leader 로 선택될 수 있도록 설정 (true)
    • OSR (our-of sync replica) : 죽은 broker 의 최신 메세지를 복하지 못한 replica 즉, 데이터 유실 가능
    • 유실보다 서비스 가용성을 높이는 경우 (true)
    • 유실을 최소화하는 경우 (false)
  • log.flush.interval.ms / log.flush.interval.messages
    • 입력된 메시지를 메모리(페이지 캐시)에서 디스크로 저장하는 수준
    • 값이 클수록 disk i/o 적게 발생 → 메모리 데이터 유실 가능
    • 값이 작을수록 disk i/o 많이 발생 → 메모리 데이터 유실 거의 없음

프로듀서

  • acks=all (acks = -1 동일)
    • 모든 replica 에 복제가 완료된 후, producer 에 ack 리턴
    • min.insync.replicas : acks=all 일때 broker 가 ack 를 보내기 위한 최소 복제본의 수
  • retries
    • 전송 실패 시 자동으로 재전송하는 회수
    • 메시지 중복 가능성 증가 : 일시적 오류로 프로듀서가 2번 전송 가능
    • 메시지 순서 변경 가능
      • 한번에 여러 번의 request 가 nw 에서 대기중인 경우, fail 된 request 다음 메시지가 먼저 전송되는 경우 발생
      • max.in.flight.requests.per.connection = 1 로 설정 (한번에 1개 요청)

컨슈머

  • 메시지 중복 읽기 또는 유실 가능한 상황
  • 해결 방안
    • auto.commit.enable = false 사용, 메뉴얼 커밋

Availability 보장 방안 (장애 복구를 빠르게)

브로커

  • 너무 많은 파티션 수 제한
    • 파티션 별 리더 선출에 많은 시간 소요
  • min.insync.replicas
    • 프로듀서가 응답을 받기 위한 최소 복제 수
    • 값이 크면, 복제 실패시 프로듀서 장애 유발 → durability 높음
    • 값이 1 이면, 원본만 저장되면 프로듀서 정상 동작 → durability 낮음
  • unclean.leader.election.enable
    • broker 가 죽었을 때, OSR replica 도 leader 로 선택될 수 있도록 설정 (true)
    • OSR (our-of sync replica) : 죽은 broker 의 최신 메세지를 복하지 못한 replica 즉, 데이터 유실 가능
    • 유실보다 서비스 가용성을 높이는 경우 (true)
    • 유실을 최소화하는 경우 (false)
  • num.recovery.threads.per.data.dir
    • 브로커가 시작/중지할 때, 다른 브로커와 sync 를 맞추기 위해 log data file 을 스캔하는 쓰레드 개수
    • 값이 크면 한번에 여러 log file 을 동시 처리 가능 (raid 구성인 경우)
      • 즉 브로커 구동 속도가 빠름

컨슈머

  • session.timeout.ms (기본 값 10000 ms)
    • 컨슈머가 비정상적으로 종료되었을 경우, 브로커가 장애로 인지하는 최소시간
    • 장애유형
      • Hard failure : SIGKILL (강제종료)
      • Soft failure : session time out (대부분의 경우)
        • poll 호출 후, 컨슈머의 처리시간이 오래 걸리는 경우
        • JVM GC 로 인한 멈춤 현상
    • 값이 적을수록 빠르게 장애 감지 (복구 빠름)
    • 장애가 더 자주 나타남 (조금만 지연되어도, failure 로 판단)
    • 가능한 낮은 값을 설정하여, Hard failure 를 빠르게 감지하도록 설정
    • 너무 낮게 설정하면, Soft failure 까지 감지하여 너무 잦은 리밸런싱 발생