아파치 카프카(Apache Kafka)의 성능 최적화 [1]

busybean3·2021년 9월 9일
0
post-thumbnail

이번 포스팅은 아파치 카프카의 성능을 최적화 할 수 있는 파라미터 tunning 방법을 알아봅시다.

시작하며... 🚀

4개의 성능 목표를 최적화하기 위해 변경해야 하는 Kafka 구성 매개변수가 있습니다. 사실 Kafka 디자인 자체는 사용자에게 구성 유연성을 제공하며 Kafka 배포가 서비스 목표에 최적화되어 있는지 확인하려면 일부 구성 매개변수의 설정을 조정하고 자체 환경에서 벤치마킹을 조사해야 합니다. 이상적으로는 프로덕션으로 이동하기 전에 또는 적어도 더 큰 클러스터 크기로 확장하기 전에 수행해야 합니다.

첫 번째 단계는 최적화할 성능 목표를 결정하는 것입니다. Throughput, Latency, Durability, Availability이라는 서로 절충점을 자주 포함하는 4가지 목표를 고려할 것입니다. 최적화하려는 목표를 파악하려면 클러스터가 제공할 사용 사례를 기억해보고, 해당 사용 사례를 충족하기 위해 절대적으로 실패할 수 없는 애플리케이션, 비즈니스 요구 사항에 대해 생각해 보셔야합니다. 그 다음 스트리밍 플랫폼으로서의 Kafka가 비즈니스 파이프라인에 어떻게 들어맞는지 생각해 보는 순으로 진행해야 합니다.

우선 성능 목표 4가지를 알아보며 각 목표에 비즈니스 요구들을 알아봅시다.

성능 목표 4가지

성능 목표는 4가지로 정리할 수 있습니다.

  1. Throughput : 처리량으로 불리우며, 카프카가 얼마나 많은 데이터를 처리할 수 있는지에 대한 메트릭이다.
  2. Latency : 지연 시간으로 불리우며, 카프카가 얼마나 빠르게 하나의 메시지를 빠르게 전달하는지의 메트릭이다.
  3. Durability : 내구성, 영속성있는 등으로 불리우며, 카프카가 얼마나 메시지의 유실을 최소화하는지의 메트릭이다.
  4. Availability : 가용성으로 불리우며, 카프카가 얼마나 서버의 다운에 대해서 최소화하는지의 메트릭이다.

이제 각 성능 목표는 4가지로 정리했습니다. 모든 성능 목표를 최적화 할 수 있다면 매우 좋은 방법이겠지만 그렇지 못합니다😂.

목표별 trade-off 관계가 되는 것이 있는데, Throughput vs Latency , Durability vs Availability 이런식으로 형성됩니다.

비즈니스 요구 사항별 서비스 목표

이번에는 성능 목표로 4가지를 알아보았는데 각 성능 목표를 가지는 비즈니스 요구 사항을 알아보며 어떤 상황일때 어떤 성능 목표를 가지고 파라미터 튜닝을 통해서 최적화 해야하는지 계획을 세울수 있도록 알아보겠습니다.

  • 데이터가 생산자에서 브로커로 또는 브로커에서 소비자로 이동하는 속도인 높은 Throughput 을 위해 최적화 하시겠습니까? 일부 사용 사례에는 초당 수백만 건의 쓰기가 있습니다. Kafka의 설계로 인해 대용량 데이터를 작성하는 것은 어려운 일이 아닙니다. 기존 데이터베이스나 키-값 저장소를 통해 데이터 볼륨을 푸시하는 것보다 빠르며 적당한 하드웨어로 수행할 수 있습니다.

  • 메시지를 종단 간(생성자에서 브로커, 소비자로) 이동하는 데 경과된 시간인 짧은 Latency 을 위해 최적화 하시겠습니까? 짧은 대기 시간 사용 사례의 한 예는 메시지 수신자가 가능한 한 짧은 대기 시간으로 메시지를 받아야 하는 채팅 애플리케이션입니다. 다른 예로는 사용자가 네트워크에서 친구의 게시물을 팔로우하는 대화형 웹 사이트 또는 사물 인터넷을 위한 실시간 스트림 처리가 있습니다.

  • 커밋된 메시지가 손실되지 않도록 보장하는 높은 Durability 을 위해 최적화 하시겠습니까? 높은 내구성을 위한 한 가지 사용 사례는 Kafka를 이벤트 저장소로 사용하는 이벤트 기반 마이크로서비스 파이프라인입니다. 다른 하나는 미션 크리티컬 비즈니스 콘텐츠를 위한 스트리밍 소스와 일부 영구 스토리지(예: AWS S3) 간의 통합입니다.

  • 예기치 않은 장애가 발생할 경우 가동 중지 시간을 최소화하는 고 Availability 최적화를 원하십니까 ? Kafka는 분산 시스템이며 오류를 허용하도록 설계되었습니다. 고가용성을 요구하는 사용 사례에서는 가능한 한 빨리 장애로부터 복구할 수 있도록 Kafka를 구성하는 것이 중요합니다.

카프카 관련 설정 🏎

이번에는 중요한 최적화를 위한 옵션들을 알아보고 시작해야겠습니다.

총 3개를 분리해서 각각 관련 설정들을 정리하고 옵션들이 무엇이 있는지 알아보겠습니다.

Producer 관련 설정들

첫번째로는 Producer의 관련 설정들을 알아보겠습니다.

  • batch.size : 같은 파티션으로 보내는 여러 데이터를 함께 배치로 보내려고 시도합니다. 이러한 동작은 클라이언트와 서버 양쪽에 성능적인 측면에서 도움이 됩니다. 이 설정을 통해서 배치 크기 바이트를 조정합니다.
  • linger.ms : 배치 형태의 메시지를 보내기 전에 추가적인 메시지들을 위해 기다리는 시간을 조정합니다. 카프카 프로듀서는 지정된 배치 사이즈에 도달하면 이 옵션과 관계없이 즉시 메시지를 전송하고, 배치 사이즈에 도달하지 못한 상황에서 linger.ms 제한 시간에 도달했을 때 메시지들을 전송합니다.(DEFAULT 0)
  • compression.type : 데이터를 압축해서 보낼 수 있는데, 어떤 타입으로 압출할지를 정할 수 있습니다. 옵션으로는 none, gzip, snappy, lz4 같은 다양한 포맷 중 하나를 선택할 수 있습니다.
  • acks : 프로듀서가 카프카 토픽의 리더에게 메시지를 보낸 후 요청을 완료하기 전 ack의 수입니다.
    • acks=0 : 프로듀서는 서버로부터 어떠한 ack도 기다리지 않습니다. 이 경우 서버가 데이터를 받았는지 보장하지 않고, 클라이언트는 전송 실패에 대한 결과를 알지 못하기 때문에 재요청 설정도 적용되지 않습니다. 메시지가 손실될 수 있지만, 서버로부터 ack에 대한 응답을 기다리지 않기 때문에 매우 빠르게 메시지를 보낼 수 있어 높은 처리량을 얻을 수 있습니다.
    • acks=1 : 리더는 데이터를 기록하지만, 모든 팔로워는 확인하지 않습니다. 이 경우 일부 데이터의 손실이 발생할 수 있습니다.
    • acks=all or -1 : 리더는 ISR의 팔로워로부터 데이터에 대한 ack를 기다립니다. 하나의 팔로워가 있는 한 데이터는 손실되지 않으며, 데이터 무손실에 대해 가장 강력하게 보장합니다.
  • retries : 일시적인 오류로 인해 전송에 실패한 데이터를 다시 보내는 횟수입니다.
  • max.in.flight.requests.per.connection : 블록되기 전에 클라이언트가 보내고 받지 못한 요청의 최대 개수입니다.
  • buffer.memory : 프로듀서가 카프카 서버로 데이터를 보내기 위해 잠시 대기할 수 있는 전체 메모리 바이트입니다.

Broker 관련 설정들

두번째로는 Broker의 관련 설정들을 알아보겠습니다.

  • default.replication.factor : 카프카내에 Replication Factor를 설정하는 옵션입니다.
  • num.replica.fetchers : 소스 브로커의 메시지를 복제하는 데 사용되는 스레드 수를 지정하십시오. 이 값을 늘리면 브로커의 I/O 조작에서 병렬 처리가 늘어날 수 있습니다.
  • auto.create.topics.enable : 서버에서 주제의 자동 작성을 사용으로 설정하려면 이것을 사용하십시오.
  • min.insync.replicas : 프로듀서가 acks=all로 설정하여 메시지를 보낼 때, write를 성공하기 위한 최소 복제본의 수를 의미합니다.
  • unclean.leader.election.enable : ISR(in-sync replica)가 아닌 OSR(out-of sync replica)를 가지고 있는 broker를 leader로 선출 할 수 있도록 설정하는 옵션입니다.
  • broker.rack : 내결함성을 위한 rack aware replication 할당에 사용됩니다
  • log.flush.interval.messages : 메시지가 플러시되기 전에 누적될 수 있는 최대 메시지 수를 지정하십시오.
  • log.flush.interval.ms : 메시지가 플러시되기 전에 로그에서 누적할 수 있는 최대 시간을 지정하십시오.
  • num.recovery.threads.per.data.dir : 각 데이터 디렉토리에 대한 로그 복구에 사용되는 스레드의 최대 수를 지정하십시오.

Consumer 관련 설정들

세번째로는 Consumer의 관련 설정들을 알아보겠습니다.

  • fetch.min.bytes : 한번에 가져올 수 있는 최소 데이터 사이즈입니다. 만약 지정한 사이즈보다 작은 경우, 데이터가 누적될 때까지 기다립니다.
  • fetch.max.wait.ms : consumer에서 데이터를 가져오는 최소 시간으로 새로운 데이터가 입력되어도, 해당 시간 이전에는 가져가지 않습니다.
  • auto.commit.enable : 카프카에서 초기 오프셋이 없거나 현재 오프셋이 더 이상 존재하지 않은 경우에 다음 옵션으로 리셋합니다.
    • earliest : 가장 초기의 오프셋값으로 설정
    • latest : 가장 마지막의 오프셋값으로 설정
    • none : 이전 오프셋값을 찾이 못하면 에러
  • session.timeout.ms : 컨슈머와 브로커 사이의 세션 타임 아웃 시간. 브로커가 컨슈머가 살아있는것으로 판단하는 시간으로, 만약 컨슈머가 그룹 코디네이터에게 하트비트를 보내지 않고 시간이 지나면 해당 컨슈머는 종료되거나 장애가 발생한 것으로 판단하고 컨슈머 그룹은 리밸런스를 시도합니다.

이제 진짜로 왜 이런 trade-off가 발생하는지 다음 포스팅을 통해 알아보며 각 성능 목표별로 어떻게 파라미터를 튜닝하며 성능을 최적화 하는지 알아보겠습니다.

REFERENCE

[1]. https://devidea.tistory.com/90
[2]. https://firststep-de.tistory.com/35
[3]. https://www.ibm.com/docs/ko/oala/1.3.5?topic=SSPFMY_1.3.5/com.ibm.scala.doc/config/iwa_cnf_scldc_cnf_kfk_t.html
[4]. https://www.popit.kr/kafka-%EC%9A%B4%EC%98%81%EC%9E%90%EA%B0%80-%EB%A7%90%ED%95%98%EB%8A%94-producer-acks/
[5]. https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=freepsw&logNo=221028179182
[6]. https://www.confluent.io/blog/optimizing-apache-kafka-deployment/

profile
엉덩이 무거운 개발자가 되기 위해서 몸무게를 찌웠다...

0개의 댓글