Kafka/Broker

Kafka Cluster의 성능과 고려요소들

재심 2023. 4. 23. 00:00

목차

     

    [개요]

    • Produce & Consume의 Request가 어떻게 처리되는지 알아야 한다.
    • 비효율적인 Request가 Broker 성능에 어떤 영향을 줄지 가늠해보아야 한다.
    • Broker의 내부 동작을 알고 있어야 한다.
      • Controller 선출 방법
      • Broker 장애감지 방법
      • Controller 장애 후 복구 과정에서 파티션 수가 중요한 이유를 알아야 한다

    [Kafka Cluster에 영향을 주는 요소들]

    Client 설정들

    Produce

     

     

    Consume

    • 주어진 처리량에 대해 최적화 되지 않은 클라이언트는 필요이상의 request를 생성한다.
    • Kafka는 기본적으로 커넥션을 계속 사용하는 것을 고려해 놓았기 때문에 하나의 요청에 많은 데이터가 오는 방식이 더 적합하다.
    • batch.size, linger.ms의 값을 적절히 설정
    • max.fetch.wait 값을 적절히 설정

     

    Controller 및 Zookeeper의 리더 선출 방식

    Kafka Cluster

    Controller

    컨트롤러는 다른 브로커들의 활성상태를 감시한다.

    파티션 리더를 선출하는 역할도 하며 이 정보를 주키퍼에 저장한다.

     

    • zookeeper.session.timeout.ms=18s

     

    Broker

    브로커는 셧다운 되면 컨트롤러에 알리며 브로커들도 컨트롤러가 잘 살아있는지 감시한다.

     

    • replica.lag.time.max.mas=30s
    • replica.fetch.min.bytes=1
    • replica.fetch.wait.max.ms=500ms

    Zookeeper

    파티션 리더 및 컨트롤러가 변경되면 주키퍼가 병목지점이 될 수도 있다.

    쓰기 작업이 발생하려면 주키퍼 쿼럼이 유지된 상태여야 한다.

    앙상블에 노드가 많아질수록 더 지연시간이 커질 수 있다. (권장: 3,5,7. 그 이상은 굳이 필요없음)

     

    • tickTime=2s (주키퍼 끼리 통신하는 것의 heartbeat)
    • syncLimit=2 (min.isr과 비슷)
    • fsync.warningthresholdms=1s

    토픽 설정

    파티션 수 결정

    • 트래픽이 적은 토픽은 1개로 시작하여 부족한 경우 브로커 개수의 배수로 늘린다.
    • 트래픽이 많은 토픽은 벤치마크 수행 후 결정한다.
      • 내구성이 필요한지?
      • 클러스터의 규모는?
      • 처리량은 어느정도 되는지?

    Replication Factor

    • Replication Factor 설정을 통해 내구성을 올릴 수 있다.
    • auto.create.topics.enable=true로 설정된 경우 default.replication.factor 값을 적절히 설정해주도록 한다.
    • 너무 많이 잡을 경우 내구성은 오를 수 있지만 지연시간이 증가할 소지가 있다.

    Replica Assignment

    • 토픽 생성 시 결정된다.
    • broker.rack이 있는 경우 broker.rack에 균등하게 알아서 분포된다.
    • 수동배치가 필요한 경우 reassign-partitions 커맨드로 수동 배치 한다.

     

    [Kafka Cluster의 목표별 고려요소들]

    카프카를 사용할 때 크게 4가지로 구분하여 목적에 맞게 클러스터를 세팅하는 것이 좋다.

    • Throughput: 처리량
    • Latency: 지연시간
    • Durability: 카프카에 들어온 메시지를 잃어버리지 않는 것.
    • Availability: 무슨일이 있더라도 항상 서비스가 되어야 하는 것.

    Throughput (처리량)

    많은 데이터를 이동시키는 것.

    간단하게 파티션을 증가시킴으로써 달성할 수 있다. 하지만 마냥 파티션을 늘리면 서버당 더 많은 파일처리가 동시에 필요해지고, 복구시에 한 번에 많은 파일에 접근해야하므로 성능에 악영향을 줄 수 있다.

    클라이언트 입장에서도 더 많은 배치가 필요하기 때문에 메모리 요구사항이 늘어난다.

     

     

    Producer

    • batch.size=250000 (Default: 16384)
    • linger.ms=100 (Default: 0)
    • compress.type=lz4 (Default: none)
    • acks=1 (내구성을 희생)
    • buffer.memory=파티션 수에 따라 적절히 조절

     

    Consumer

    • fetch.min.bytes=1000000 (Default: 1. Fetch당 데이터크기 증가)

     

    Latency (지연)

    가능한 짧은 시간 안에 데이터를 전송할 때  중요시 하는 것.

    시간에 민감한 비즈니스 처리 시 최우선 고려사항.

    Confluent 블로그 참조: Tail Latency at Scale with Apache Kafka (confluent.io)

     

    Producer

    • linger.ms=0 ~ 5 (Default: 0)
    • compression.type=none or lz4 (Default: none)
    • acks=1

    Consumer

    • fetch.min.bytes=1 (Default: 1)

    Broker

    • num.replica.fetchers (Default: 1): 팔로워가 리더의 페이스를 따라가지 못하는 경우 늘려줌

    Durability (내구성)

    데이터 손실이 되면 안되는 상황에서 최우선 고려.

    Replication Factor와 Min ISR 수치를 높여서 보장성을 높일 수 있다. 하지만 복제할 내용이 많아져서 성능상 하락이 있을 수 있음.

     

    Broker

    • Recplication.Factor>=3
    • Min.ISR>=2
    • log.flush.interval.ms / message: 브로커가 페이지 캐시에 있는걸 flush하는 주기
      • 기본적으로 OS가 알아서 Page Cache에 있는 내용을 디스크로 주기적으로 써주는데, 이 주기를 직접 설정하여 갑자기 브로커가 내려갔을 때 손실이 일어나는 것을 방지
      • 가급적이면 설정하지는 않고 OS에 맡기는 걸 추천한다고 한다.

    Producer

    • acks=all
    • enable.idempotence=true (Default: false)

    Consumer

    • enable.auto.commit=false (Default: true)

    Availability (가용성)

    장애가 나도 계속 서비스가 가능한 것을 목표로 한다.

     

    Broker

    • min.ISR = 1
    • num.recovery.threads.per.data.dir = recovery될 때 세그먼트에 있는 것을 page cache에 올려서 최대한 빨리 복구하려고 할 때.
    • unclean.leader.election = true (Default: false). ISR목록에 없는 브로커를 리더로 선출하기 때문에 데이터 유실이 될 수 있다.

     

    [권장사항]

    • 성능의 초점은 가장 중요한 비즈니스의 요구사항에 맞춰 진행한다. (ex: 가용성 우선, TPS우선)
    • 이러한 목표 하에서 여러 튜닝을 진행한다 (배치 크기 등등)
    • 트래픽을 평가하고 파티션 수를 결정할 때는 향후 트래픽이 증가할 수 있음을 고려하고 선정한다.
    • 메시지가 변경되거나하면 이를 고려하여 다시 성능 테스트를 하거나 수치를 점검한다.
    • 모니터링도 수시로 항상 진행한다. 적절한 모니터링 환경이 클라이언트, 클러스터 양쪽에 모두 세팅되어 있어야 한다.