Kafka 처리량 마스터하기: 필수 프로듀서 튜닝 기법
프로듀서 튜닝을 마스터하여 Kafka 스트림에서 최대 성능을 발휘하세요. 이 포괄적인 가이드는 `batch.size`, `linger.ms`, 메시지 압축이 프로듀서 처리량에 미치는 중요한 영향을 자세히 설명합니다. 분산 이벤트 스트리밍 플랫폼에서 네트워크 오버헤드를 줄이고 병목 현상을 제거하기 위한 실행 가능한 구성 설정과 모범 사례를 알아보세요.
Kafka 처리량 마스터하기: 필수 프로듀서 튜닝 기법
Kafka 프로듀서 처리량은 일반적으로 배치, 압축, 확인 응답 및 파티셔닝에 의해 결정됩니다. 브로커 측도 중요하지만, 작은 압축되지 않은 요청을 하나씩 보내는 프로듀서는 강력한 클러스터를 낭비할 수 있습니다.
실용적인 목표는 간단합니다. 지연 시간 및 내구성 요구 사항을 위반하지 않고 더 적고 더 가득 찬 요청을 보내는 것입니다. 즉, 다른 워크로드에서 단일 "빠른" 구성을 복사하는 대신 측정을 통해 튜닝해야 합니다.
Kafka 프로듀서 처리량 기본 사항 이해
Kafka에서 프로듀서 처리량은 클라이언트가 레코드를 얼마나 효율적으로 수집하고, 요청으로 패키징하고, 올바른 브로커 파티션으로 보내는지에 따라 결정됩니다. 배치는 메시지당 오버헤드를 줄이지만 지연 시간 동작도 변경합니다. 몇 밀리초를 기다리는 배치는 분석 파이프라인에는 좋을 수 있지만 대화형 요청 경로에는 허용되지 않을 수 있습니다.
처리량 분석을 위한 주요 지표
튜닝할 때 다음 영역에 집중하세요.
- 배치 크기: 전송 전에 누적되는 데이터 양(바이트).
- 지연 시간: 프로듀서가 불완전한 배치를 보내기 전에 더 많은 메시지를 기다리는 시간.
- 압축: 전송 전에 데이터를 압축하는 데 관련된 오버헤드.
핵심 튜닝 매개변수 1: 배치 크기 (batch.size)
batch.size 구성 매개변수는 지연 시간에 관계없이 프로듀서가 브로커로 보내기 전에 누적할 배치의 최대 크기(바이트)를 지정합니다.
batch.size가 처리량에 미치는 영향
- 더 큰
batch.size: 일반적으로 더 높은 처리량으로 이어집니다. 네트워크 사용률이 최대화되어 메시지당 오버헤드가 줄어들기 때문입니다. 더 적은 네트워크 요청에 더 많은 레코드를 넣을 수 있습니다. - 더 작은
batch.size: 더 낮은 처리량으로 이어질 수 있습니다. 프로듀서가 많고 작은 비효율적인 요청을 보내 네트워크 오버헤드가 증가하고 잠재적으로 지연 시간이 높아지기 때문입니다.
실행 가능한 팁: 64KB 또는 128KB와 같은 적당한 증가부터 시작한 다음 배치 크기 및 요청 속도 지표를 관찰하세요. 매우 큰 배치는 일부 워크로드에 도움이 될 수 있지만 활성 파티션당 더 많은 메모리를 소비하고 최악의 경우 지연 시간을 증가시킬 수 있습니다.
예제 구성 (프로듀서 속성)
# 배치 크기를 64KB로 설정
batch.size=65536
과도한 크기 지정에 대한 경고:
batch.size는 처리 중인 레코드가 있는 파티션별로 할당됩니다. 많은 파티션에 쓰는 프로듀서는 이 값을 공격적으로 올리면 예상보다 훨씬 더 많은 메모리를 사용할 수 있습니다.
핵심 튜닝 매개변수 2: 지연 시간 (linger.ms)
linger.ms 매개변수는 프로듀서가 현재 배치를 강제로 보내기 전에 추가 레코드가 도착하여 배치를 채울 때까지 기다리는 시간을 제어합니다. 이는 지연 시간/처리량 균형을 관리하기 위한 기본 제어입니다.
linger.ms가 처리량에 미치는 영향
- 더 높은
linger.ms: 프로듀서가 배치를 채울 시간이 더 많기 때문에 종종 처리량이 증가합니다. - 더 낮은
linger.ms: 종종 프로듀서 측 대기 시간을 줄이지만 더 작은 요청을 생성할 수 있습니다.
처리량 중심 서비스의 경우 5 또는 10과 같은 작은 값부터 시도한 다음 지연 시간 예산이 허용하는 경우 위로 이동하세요. 요청/응답 경로의 경우 값을 낮게 유지하고 증가시키기 전에 꼬리 지연 시간 영향을 증명하세요.
예제 구성 (프로듀서 속성)
# 배치를 채우기 위해 최대 50밀리초 대기
linger.ms=50
핵심 튜닝 매개변수 3: 메시지 압축
완벽한 크기의 배치를 사용하더라도 네트워크를 통해 데이터를 전송하는 데 소요되는 시간은 전체 처리량에 영향을 미칩니다. 메시지 압축은 브로커로 전송되는 데이터의 물리적 크기를 줄여 네트워크 전송 시간을 단축하고 종종 동일한 시간 내에 더 많은 메시지를 처리할 수 있도록 합니다.
압축 유형 및 선택
compression.type 설정은 사용되는 알고리즘을 결정합니다. 일반적인 옵션은 다음과 같습니다.
| 알고리즘 | 특징 |
|---|---|
none |
압축 없음. 압축 CPU 비용을 피하지만 네트워크를 통해 더 많은 바이트를 보냅니다. |
gzip |
매우 좋은 압축률. 적당한 CPU 오버헤드. |
snappy |
매우 빠른 압축/해제. 낮은 CPU 오버헤드, 적당한 압축률. 종종 최상의 균형. |
lz4 |
많은 워크로드에 실용적인 균형을 제공하는 빠른 압축/해제. |
zstd |
많은 최신 시스템에서 강력한 압축률과 우수한 속도이지만 CPU 비용을 테스트하세요. |
압축은 네트워크 대역폭이나 브로커 I/O가 제약 조건일 때 종종 유효 처리량을 향상시킵니다. 프로듀서가 이미 CPU 바운드인 경우 해가 될 수 있습니다. 프로듀서 CPU, 브로커 네트워크 바이트, 요청 지연 시간 및 소비자 압축 해제 비용을 측정하세요.
예제 구성 (프로듀서 속성)
# 최적의 균형을 위해 snappy 압축 사용
compression.type=snappy
# GZIP을 사용하는 경우 레벨을 추가로 조정할 수 있습니다 (1이 가장 빠름/가장 낮은 압축)
# gzip.compression.level=6
최대 처리량을 위한 고급 기술
기본 배치 매개변수가 설정되면 몇 가지 다른 구성이 처리량 한계를 높이는 데 도움이 될 수 있습니다.
1. 프로듀서 스레드 수 증가 (해당하는 경우)
애플리케이션 로직이 허용하는 경우 병렬 처리(동시에 데이터를 보내는 스레드 수)를 늘리면 처리량을 직접 확장할 수 있습니다. 각 스레드는 자체 독립적인 프로듀서 인스턴스와 버퍼를 관리하여 다른 파티션 또는 토픽에 동시에 데이터를 제출할 수 있습니다.
2. Acks 구성
acks 설정은 내구성 보장을 제어합니다. 프로듀서가 전송 성공으로 간주하기 전에 얼마나 많은 브로커가 수신을 확인해야 하는지입니다.
acks=0: 파이어 앤 포겟. 높은 처리량 잠재력이지만 프로듀서는 브로커 확인을 기다리지 않습니다.acks=1: 리더 복제본이 확인합니다. 좋은 균형.acks=all(또는-1): 모든 동기화된 복제본이 확인합니다. 가장 높은 내구성, 가장 낮은 처리량.
중요한 비즈니스 이벤트의 경우 멱등성과 함께 acks=all을 사용하는 것이 처리량 비용을 감수할 가치가 있는 경우가 많습니다. 일회용 텔레메트리의 경우 acks=1이 허용될 수 있습니다. acks=0은 기본 튜닝 트릭이 아니라 의식적인 데이터 손실 절충이어야 합니다.
3. 버퍼 메모리 (buffer.memory)
이 설정은 프로듀서에서 버퍼링을 위해 할당된 총 메모리를 정의합니다. 이 버퍼가 가득 차면 프로듀서는 공간이 확보될 때까지(성공적인 전송 또는 시간 초과/레코드 삭제를 통해) 차단됩니다.
피크 데이터 수신 속도가 지속적인 전송 속도를 초과하는 경우 buffer.memory를 늘려 프로듀서가 즉시 차단되지 않고 버스트를 흡수할 수 있도록 합니다.
# 내부 버퍼에 64MB 할당
buffer.memory=67108864
결과를 변경하는 기타 설정
max.in.flight.requests.per.connection은 프로듀서가 하나의 연결에서 가질 수 있는 확인되지 않은 요청 수를 제어합니다. 값이 높을수록 처리량이 향상될 수 있지만 순서 및 재시도 동작이 중요합니다. 최신 Kafka 클라이언트에서 멱등성이 활성화되면 클라이언트는 안전을 유지하기 위해 관련 설정을 제한합니다.
retries 및 delivery.timeout.ms는 전송 실패 전에 프로듀서가 계속 시도하는 시간을 결정합니다. 오류를 무시하는 처리량 테스트는 오해의 소지가 있습니다. 압력이 가해질 때 레코드를 삭제하기 때문에 빠르게 보이는 구성은 대부분의 시스템에서 처리량 향상이 아닙니다.
request.timeout.ms는 브로커 및 네트워크 현실에 맞아야 합니다. 너무 낮으면 짧은 브로커 일시 중지 중에 재시도 폭풍이 발생할 수 있습니다. 너무 높으면 실제 실패가 표면화되는 데 너무 오래 걸릴 수 있습니다.
파티션 수도 중요합니다. 단일 파티션은 한 번에 하나의 리더 브로커에 의해 처리되므로 하나의 핫 키는 클러스터에 여유 용량이 있더라도 토픽의 병목 현상이 될 수 있습니다. 모든 레코드가 동일한 키를 사용하는 경우 프로듀서 튜닝으로는 파티션 간에 쓰기가 분산되지 않습니다. batch.size를 비난하기 전에 파티션별 바이트 입력 및 요청 처리기 지표를 확인하세요.
실용적인 시작 구성
약간의 추가 지연 시간이 허용되는 대용량 이벤트 파이프라인의 경우 합리적인 첫 번째 시도는 다음과 같습니다.
acks=all
enable.idempotence=true
compression.type=lz4
batch.size=131072
linger.ms=10
buffer.memory=67108864
delivery.timeout.ms=120000
지연 시간이 더 낮은 서비스 경로의 경우 더 보수적으로 시작하세요.
acks=all
enable.idempotence=true
compression.type=snappy
batch.size=32768
linger.ms=1
buffer.memory=33554432
이는 보편적인 최상의 설정이 아닙니다. 측정을 위한 시작점입니다. 레코드가 작은 JSON 이벤트인 경우 압축이 많은 도움이 될 수 있습니다. 레코드가 이미 압축된 이미지 또는 아카이브인 경우 압축으로 인해 CPU가 낭비될 수 있습니다. 프로듀서가 수십 개의 파티션에 고르게 쓰는 경우 예상보다 빨리 메모리 압력이 나타날 수 있습니다.
튜닝 중에 확인해야 할 지표
애플리케이션 처리량만으로 프로듀서 튜닝을 판단하지 마세요. 프로듀서 지표도 확인하세요.
record-send-rate: 초당 전송된 레코드 수.record-error-rate: 실패한 전송.request-latency-avg및 지표 시스템이 캡처하는 경우 높은 백분위수 지연 시간.batch-size-avg: 더 큰batch.size가 실제로 사용되고 있는지 여부.buffer-available-bytes또는 버퍼 고갈 신호.record-queue-time-avg: 레코드가 전송되기 전에 대기하는 시간.
브로커 측에서는 네트워크 바이트, 요청 처리기 유휴 시간, 복제본 미달 파티션, 디스크 I/O 및 프로듀스 요청 지연 시간을 확인하세요. 프로듀서는 토픽 리더, 디스크, 복제 및 네트워크가 허용하는 만큼만 빠를 수 있습니다.
세 가지 일반적인 튜닝 시나리오
클릭스트림 또는 메트릭 이벤트의 경우 레코드는 종종 작고 빈번합니다. 압축을 활성화하고 batch.size를 높이며 약간의 지연을 허용하면 일반적으로 처리량이 향상됩니다. 주요 위험은 데이터가 다운스트림 분석에 도달하기 전에 너무 많은 지연을 추가하는 것입니다. 해당 워크로드에서는 linger.ms=10, compression.type=lz4 또는 zstd로 시작한 다음 소비자 지연을 확인하는 것이 좋습니다.
결제, 주문 또는 감사 이벤트의 경우 일반적으로 원시 처리량보다 내구성이 더 중요합니다. acks=all을 유지하고 멱등성을 활성화하며 acks=0을 피하세요. 처리량이 충분하지 않은 경우 전달 보장을 약화시키기 전에 파티셔닝, 프로듀서 동시성, 브로커 용량 및 메시지 크기를 확인하세요. 감사 이벤트 손실은 허용 가능한 성능 최적화가 거의 아닙니다.
매우 큰 레코드의 경우 배치가 동일한 방식으로 도움이 되지 않을 수 있습니다. Kafka는 일반적으로 합리적인 크기의 메시지에 가장 적합합니다. 프로듀서가 거대한 페이로드를 보내는 경우 페이로드를 객체 스토리지에 저장하고 Kafka를 통해 참조를 보내는 것을 고려하세요. 이것이 불가능한 경우 max.request.size, 브로커 message.max.bytes, 토픽 max.message.bytes 및 소비자 가져오기 제한을 함께 검토하세요. 프로듀서 튜닝만으로는 파이프라인의 모든 부분을 통해 과도한 크기의 레코드를 푸시하는 설계를 수정할 수 없습니다.
자신을 속이지 않고 테스트하기
좋은 처리량 테스트는 프로덕션과 유사한 레코드 크기, 키, 압축, 파티션 수 및 브로커 복제를 사용합니다. 하나의 고정 문자열을 하나의 테스트 토픽으로 보내는 것은 실제 서비스를 나타내지 않습니다.
테스트할 때 다음과 같은 메모를 보관하세요.
레코드 크기: 900-1400바이트 JSON
키: customer_id, 거의 균등한 분포
토픽 파티션: 24
복제 계수: 3
프로듀서 인스턴스: 6
acks: all
압축: lz4
batch.size: 131072
linger.ms: 10
관찰된 문제: 15분 후 p99 전송 지연 시간 상승, 프로듀서 CPU 한계 근접
이러한 기록은 다음 튜닝 단계를 명확하게 만듭니다. CPU가 한계에 가까우면 압축을 변경하는 것이 도움이 될 수 있습니다. 배치가 여전히 작으면 지연 시간을 늘리거나 파티션당 트래픽이 너무 적은지 확인하세요. 하나의 브로커가 뜨거우면 파티션 리더십과 키 분포를 검사하세요.
또한 정상 상태를 확인할 수 있을 만큼 충분히 오래 테스트를 실행하세요. 짧은 테스트는 페이지 캐시에 맞고 로그 세그먼트 롤링 동작을 놓치며 나중에 나타나는 소비자 지연을 피할 수 있습니다. Kafka 성능 문제는 종종 첫 번째 버스트 중이 아니라 버퍼가 채워진 후에 나타납니다.
프로듀서 튜닝이 잘못된 수정인 경우
때로는 느린 전송을 보고하는 구성 요소이기 때문에 프로듀서가 비난을 받지만 근본 원인은 다른 곳에 있습니다. 브로커 디스크가 포화 상태이면 linger.ms를 아무리 신중하게 튜닝해도 프로듀스 지연 시간이 증가합니다. 토픽에 파티션이 너무 적으면 프로듀서가 충분한 리더에 쓰기를 분산할 수 없습니다. 모든 레코드가 동일한 키를 사용하면 하나의 파티션이 뜨거워지고 나머지 토픽은 거의 유휴 상태가 됩니다.
클라이언트 설정을 변경하기 전에 병목 현상이 패턴을 따르는지 확인하세요.
하나의 파티션이 뜨거움: 키 분포 또는 파티션 수 문제
하나의 브로커에 있는 모든 파티션이 느림: 브로커 디스크, 네트워크 또는 컨트롤러 문제
프로듀서 CPU 높음: 압축, 직렬화 또는 애플리케이션 오버헤드
프로듀서 버퍼 고갈: 브로커가 데이터를 충분히 빨리 수락할 수 없거나 트래픽 버스트가 너무 큼
튜닝 후에만 소비자 지연 증가: 프로듀서가 이제 다운스트림 처리를 능가함
마지막 경우는 놓치기 쉽습니다. 프로듀서 처리량을 개선하면 느린 소비자 그룹, 과도한 정리가 있는 압축된 토픽 또는 더 빨리 수집할 수 없는 다운스트림 데이터베이스가 드러날 수 있습니다. 건강한 Kafka 튜닝 연습은 전송 클라이언트뿐만 아니라 전체 파이프라인을 살펴봅니다.
반복적 튜닝이 핵심
Kafka 프로듀서 튜닝은 작은 실험 루프로 가장 잘 작동합니다. 한 가지를 변경하고, 현실적인 부하 테스트를 실행하고, 처리량, 지연 시간, 오류율 및 리소스 사용량을 비교하세요.
대부분의 높은 처리량 사용 사례의 경우 최적의 구성은 다음과 같습니다.
- 적당한
linger.ms설정 (예: 5ms - 50ms). - 큰
batch.size설정 (예: 128KB). - 효율적인 압축 활성화 (
snappy등).
한 가지만 기억한다면 트레이드오프를 기억하세요. 더 큰 배치와 압축은 일반적으로 오버헤드를 줄이지만 지연 시간과 CPU 사용량을 증가시킬 수 있습니다. 올바른 설정은 내구성 요구 사항을 충족하고 오류를 숨기지 않고 실제 트래픽을 따라잡을 수 있는 설정입니다.