Kafka 클라이언트 모범 사례 - Amazon Managed Streaming for Apache Kafka

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Kafka 클라이언트 모범 사례

Apache Kafka 및 Amazon 로 작업할 때는 최적의 성능과 안정성을 위해 클라이언트와 서버를 모두 올바르게 구성하는 MSK것이 중요합니다. 이 가이드에서는 Amazon 에 대한 모범 사례 클라이언트 측 구성에 대한 권장 사항을 제공합니다MSK.

Amazon MSK Replicator 모범 사례에 대한 자세한 내용은 섹션을 참조하세요MSK 복제기 사용 모범 사례.

Kafka 클라이언트 가용성

Apache Kafka와 같은 분산 시스템에서는 고가용성을 보장하는 것이 안정적이고 내결함성 있는 메시징 인프라를 유지하는 데 매우 중요합니다. 브로커는 업그레이드, 패치 적용, 하드웨어 장애 및 네트워크 문제와 같은 계획된 이벤트와 계획되지 않은 이벤트 모두에 대해 오프라인 상태가 됩니다. Kafka 클러스터는 오프라인 브로커에 대한 내성이 있으므로 Kafka 클라이언트도 브로커 장애 조치를 정상적으로 처리해야 합니다. Kafka 클라이언트의 고가용성을 보장하려면 다음 모범 사례를 사용하는 것이 좋습니다.

생산자 가용성
  • 브로커 장애 조치 중에 실패한 메시지 전송을 다시 시도하도록 생산자에게 지시retries하도록 를 설정합니다. 대부분의 사용 사례에는 최대 정수 값 또는 이와 유사한 높은 값을 사용하는 것이 좋습니다. 이렇게 하지 않으면 Kafka의 고가용성이 저하됩니다.

  • 를 설정delivery.timeout.ms하여 메시지 전송과 브로커로부터 확인 수신 사이의 총 시간에 대한 상한을 지정합니다. 이는 메시지가 유효한 기간의 비즈니스 요구 사항을 반영해야 합니다. 장애 조치 작업을 완료하는 데 충분한 재시도를 허용할 수 있도록 시간 제한을 충분히 높게 설정합니다. 대부분의 사용 사례에는 60초 이상의 값을 사용하는 것이 좋습니다.

  • 재전송을 시도하기 전에 단일 요청이 기다려야 하는 최대 request.timeout.ms 로 설정합니다. 대부분의 사용 사례에는 10초 이상의 값을 사용하는 것이 좋습니다.

  • 재시도 스톰 및 가용성 영향을 방지하기 위해 재시도 간의 지연을 구성retry.backoff.ms하도록 를 설정합니다. 대부분의 사용 사례에는 200ms의 최소값을 사용하는 것이 좋습니다.

  • 높은 내구성을 구성acks=all하도록 를 설정합니다. 이는 의 서버 측 구성RF=3과 일치해야 쓰기를 ISR 승인min.isr=2할 수 있습니다. 오프라인에서 단일 브로커 중에 이 , min.isr즉 입니다2.

소비자 가용성
  • 새 소비자 그룹 또는 재생성된 소비자 그룹에 대해 를 latest 처음에 auto.offset.reset로 설정합니다. 이렇게 하면 전체 주제를 소비하여 클러스터 로드가 추가될 위험을 피할 수 있습니다.

  • 를 사용할 auto.commit.interval.ms 때 를 설정합니다enable.auto.commit. 추가 로드 위험을 방지하려면 대부분의 사용 사례에 대해 최소 5초의 값을 사용하는 것이 좋습니다.

  • 소비자의 메시지 처리 코드 내에서 예외 처리를 구현하여 회로 차단기 또는 지수 백오프가 있는 절전 모드와 같은 일시적인 오류를 처리합니다. 이렇게 하지 않으면 애플리케이션 충돌이 발생하여 과도한 리밸런싱이 발생할 수 있습니다.

  • isolation.level 를 설정하여 트랜잭션 메시지를 읽는 방법을 제어합니다.

    기본적으로 read_uncommitted 항상 간결하게 설정하는 것이 좋습니다. 일부 클라이언트 구현에서 누락되었습니다.

    계층형 스토리지를 사용할 read_uncommitted 때는 의 값을 사용하는 것이 좋습니다.

  • 가장 가까운 복제본 읽기를 사용하도록 client.rack를 설정합니다. 네트워크 트래픽 비용과 지연 시간을 최소화하려면 를 az id 로 설정하는 것이 좋습니다. 랙 인식을 통해 Amazon MSK 소비자의 네트워크 트래픽 비용 절감을 참조하세요.

소비자 리밸런싱
  • 구현된 시작 지터를 포함하여 애플리케이션의 시작 시간보다 큰 값으로 session.timeout.ms 설정합니다. 대부분의 사용 사례에는 60초의 값을 사용하는 것이 좋습니다.

  • 를 설정heartbeat.interval.ms하여 그룹 조정자가 소비자를 정상으로 보는 방법을 미세 조정합니다. 대부분의 사용 사례에는 10초의 값을 사용하는 것이 좋습니다.

  • 세션 제한 시간에 의존하여 소비자가 그룹을 떠날 때를 식별하는 SIGTERM대신 애플리케이션에서 종료 후크를 설정하여 에서 소비자를 깨끗하게 닫습니다. Kstream 애플리케이션은 의 값으로 internal.leave.group.on.close 설정할 수 있습니다true.

  • 소비자 그룹 내에서 고유한 값으로 group.instance.id 설정합니다. 호스트 이름, task-id 또는 pod-id가 이상적입니다. 문제 해결 중에 더 결정적인 동작과 더 나은 클라이언트/서버 로그 상관관계를 위해 항상 이 설정을 설정하는 것이 좋습니다.

  • 평균 배포 시간과 일치하는 group.initial.rebalance.delay.ms 값으로 설정합니다. 이렇게 하면 배포 중에 지속적인 리밸런싱이 중지됩니다.

  • 고정 할당기를 partition.assignment.strategy 사용하도록 를 설정합니다. StickyAssignor 또는 를 사용하는 것이 좋습니다CooperativeStickyAssignor.

Kafka 클라이언트 성능

Kafka 클라이언트의 고성능을 보장하려면 다음 모범 사례를 사용하는 것이 좋습니다.

생산자 성능
  • 를 설정linger.ms하여 생산자가 배치가 채워질 때까지 기다리는 시간을 제어합니다. 작은 배치는 한 번에 더 많은 스레드 및 I/O 작업으로 변환되므로 Kafka에 계산 비용이 많이 듭니다. 다음 값을 사용하는 것이 좋습니다.

    지연 시간이 짧은 모든 사용 사례에 대한 최소 값은 5ms입니다.

    대부분의 사용 사례에서는 25ms의 더 높은 값을 사용하는 것이 좋습니다.

    지연 시간이 짧은 사용 사례에서는 0의 값을 사용하지 않는 것이 좋습니다. (값이 0이면 일반적으로 IO 오버헤드로 인해 지연 시간이 발생합니다.)

  • 클러스터batch.size로 전송되는 배치 크기를 제어하도록 를 설정합니다. 이 값을 64KB 또는 128KB 로 늘리는 것이 좋습니다.

  • 더 큰 배치 크기를 사용할 buffer.memory 때 를 설정합니다. 대부분의 사용 사례에는 64MB의 값을 사용하는 것이 좋습니다.

  • 를 설정send.buffer.bytes하여 바이트를 수신하는 데 사용되는 TCP 버퍼를 제어합니다. 지연 시간이 긴 네트워크에서 생산자를 실행할 때 OS가 이 버퍼를 관리하도록 하려면 -1 값을 사용하는 것이 좋습니다.

  • 배치의 압축을 제어하도록 compression.type을 설정합니다. 지연 시간이 긴 네트워크에서 생산자를 실행하는 lz4 또는 zstd를 사용하는 것이 좋습니다.

소비자 성과
  • 를 설정fetch.min.bytes하여 최소 가져오기 크기가 유효한지 제어하여 가져오기 및 클러스터 로드 수를 줄입니다.

    모든 사용 사례에 대해 최소 32바이트를 사용하는 것이 좋습니다.

    대부분의 사용 사례에는 128바이트의 값을 더 높이는 것이 좋습니다.

  • fetch.min.bytes가 무시되기 전에 소비자가 대기하는 시간을 결정하려면 fetch.max.wait.ms 설정합니다. 대부분의 사용 사례에는 1000ms의 값을 사용하는 것이 좋습니다.

  • 소비자 수는 파티션 수와 같을 것을 권장합니다.

  • 를 설정receive.buffer.bytes하여 바이트를 수신하는 데 사용되는 TCP 버퍼를 제어합니다. 대기 시간이 긴 네트워크에서 소비자를 실행할 때 OS가 이 버퍼를 관리하도록 하려면 -1 값을 사용하는 것이 좋습니다.

클라이언트 연결

연결 수명 주기에는 Kafka 클러스터에 대한 계산 및 메모리 비용이 발생합니다. 한 번에 너무 많은 연결이 생성되면 Kafka 클러스터의 가용성에 영향을 미칠 수 있는 로드가 발생합니다. 이러한 가용성 영향으로 인해 애플리케이션이 훨씬 더 많은 연결을 생성하여 계단식 실패로 인해 완전 중단이 발생할 수 있습니다. 합리적인 속도로 생성하면 많은 수의 연결을 달성할 수 있습니다.

높은 연결 생성률을 관리하려면 다음과 같은 완화 조치를 사용하는 것이 좋습니다.

  • 애플리케이션 배포 메커니즘이 모든 생산자/소비자를 한 번에 다시 시작하지는 않지만 더 작은 배치로 시작하는 것이 좋습니다.

  • 애플리케이션 계층에서 개발자는 관리자 클라이언트, 생산자 클라이언트 또는 소비자 클라이언트를 생성하기 전에 무작위 지터(랜덤 절전 모드)가 수행되도록 해야 합니다.

  • 에서 연결을 닫을 SIGTERM때 모든 Kafka 클라이언트가 동시에 닫히지 않도록 무작위 절전 모드를 실행해야 합니다. 무작위 절전 모드는 이 SIGKILL 발생하기 전에 제한 시간 내에 있어야 합니다.

    예제 A(Java)
    sleepInSeconds(randomNumberBetweenOneAndX); this.kafkaProducer = new KafkaProducer<>(this.props);
    예제 B(Java)
    Runtime.getRuntime().addShutdownHook(new Thread(() -> { sleepInSeconds(randomNumberBetweenOneAndTwentyFive); kafkaProducer.close(Duration.ofSeconds(5)); });
  • 애플리케이션 계층에서 개발자는 클라이언트가 단일 톤 패턴으로 애플리케이션당 한 번만 생성되도록 해야 합니다. 예를 들어 lambda를 사용하는 경우 메서드 핸들러가 아닌 전역 범위에서 클라이언트를 생성해야 합니다.

  • 안정적인 상태를 유지하기 위해 연결 수를 모니터링하는 것이 좋습니다. 배포 및 브로커 장애 조치 중에는 연결이 정상creation/close/shift입니다.

Kafka 클라이언트 모니터링

Kafka 클라이언트 모니터링은 Kafka 에코시스템의 상태와 효율성을 유지하는 데 매우 중요합니다. Kafka 관리자, 개발자 또는 운영 팀원이든 관계없이 클라이언트 측 지표를 활성화하는 것은 계획된 이벤트와 계획되지 않은 이벤트 중에 비즈니스 영향을 이해하는 데 매우 중요합니다.

선호하는 지표 캡처 메커니즘을 사용하여 다음 클라이언트 측 지표를 모니터링하는 것이 좋습니다.

를 사용하여 지원 티켓을 생성할 때는 인시던트 중에 관찰된 모든 비정상 값을 AWS포함합니다. 오류(경고 아님)를 자세히 설명하는 클라이언트 애플리케이션 로그 샘플도 포함합니다.

생산자 지표
  • 바이트 속도

  • record-send-rate

  • records-per-request-avg

  • acks-latency-avg

  • request-latency-avg

  • request-latency-max

  • record-error-rate

  • record-retry-rate

  • 오류 속도

참고: 리더 장애 조치 또는 네트워크 재전송과 같은 일시적 문제를 처리하기 위한 Kafka 프로토콜의 일부이므로 재시도 시 발생하는 일시적 오류는 우려 대상이 아닙니다. record-send-rate 는 생산자가 여전히 재시도를 진행하고 있는지 확인합니다.

소비자 지표
  • records-consumed-rate

  • bytes-consumed-rate

  • 가져오기 속도

  • records-lag-max

  • record-error-rate

  • fetch-error-rate

  • 폴링 속도

  • rebalance-latency-avg

  • 커밋 속도

참고: 가져오기 속도와 커밋 속도가 높으면 클러스터에 불필요한 부하가 발생합니다. 더 큰 배치로 요청을 수행하는 것이 가장 좋습니다.

공통 지표
  • connection-close-rate

  • connection-creation-rate

  • 연결 수

참고: 연결 생성/종료가 높으면 클러스터에 불필요한 부하가 발생합니다.