Kafka 파티션 최적화: 확장성과 처리량을 위한 가이드
파티션 최적화를 통해 Kafka 토픽의 최고 성능을 발휘하세요. 이 가이드는 이상적인 파티션 수 결정, 프로듀서/컨슈머 처리량 균형, 확장성 보장, 일반적인 함정 회피를 위한 필수 전략을 다룹니다. 높은 처리량과 낮은 지연 시간의 이벤트 스트리밍을 위해 파티션을 효과적으로 구성하는 방법을 배우세요.
Kafka 파티션 최적화: 확장성과 처리량을 위한 가이드
Kafka 파티션 수는 실제로 운영하기 전까지는 간단해 보이는 설정 중 하나입니다. 파티션이 너무 적으면 컨슈머가 확장될 수 없고, 너무 많으면 브로커가 메타데이터 관리에 더 많은 시간을 소비하고 리밸런싱 시간이 길어지며 운영상의 노이즈가 증가합니다.
보편적인 최적의 숫자는 없습니다. 결제 토픽, 클릭스트림 토픽, 압축된 고객 상태 토픽은 각각 다른 순서 요구사항, 메시지 크기, 보존 설정, 컨슈머 동작을 가집니다. 유용한 질문은 "몇 개의 파티션이 가장 좋은가?"가 아니라 "이 토픽의 처리량, 순서, 성장을 위해 불필요한 브로커 오버헤드 없이 몇 개의 파티션이 필요한가?"입니다.
Kafka 파티션 이해하기
기본적으로 Kafka 토픽은 하나 이상의 파티션으로 나뉩니다. 각 파티션은 순서가 있는 추가 전용 로그입니다. 파티션은 Kafka에서 병렬 처리의 단위입니다:
- 프로듀서가 파티션에 쓰기: 프로듀서는 직접 파티션을 선택하거나 키를 사용하거나 파티셔너가 레코드를 분산하도록 할 수 있습니다.
- 컨슈머가 파티션에서 읽기: 컨슈머 그룹의 각 컨슈머는 하나 이상의 파티션을 독점적으로 읽도록 할당받습니다. 이는 파티션 내의 메시지가 해당 그룹 내의 단일 컨슈머 인스턴스에 의해 순서대로 처리되도록 보장합니다.
- 브로커가 파티션 호스팅: Kafka 브로커는 리더와 복제본을 저장합니다. 여러 파티션이 있는 토픽은 브로커 간에 저장소와 트래픽을 분산할 수 있습니다.
파티션의 주요 특성:
- 파티션 내에서 순서 보장: 단일 파티션 내의 메시지는 항상 순서가 유지됩니다. 그룹 내의 컨슈머는 이 순서를 유지합니다.
- 파티션 간 순서 미보장: 동일한 토픽의 다른 파티션 간에는 메시지 순서가 보장되지 않습니다.
- 병렬 처리: 하나의 컨슈머 그룹에서 토픽에 대한 활성 컨슈머의 유용한 수는 파티션 수를 초과할 수 없습니다. 추가 컨슈머는 해당 토픽에 대해 유휴 상태가 됩니다.
파티션 수에 영향을 미치는 요소
Kafka 토픽의 파티션 수를 결정할 때 평가해야 할 몇 가지 중요한 요소가 있습니다:
1. 처리량 요구사항 (프로듀서 및 컨슈머)
- 프로듀서 처리량: 더 많은 파티션은 브로커 간에 쓰기를 분산할 수 있지만, 리더가 균형을 이루고 프로듀서가 레코드를 잘 분산하는 경우에만 가능합니다. 하나의 핫 키가 있는 키 기반 토픽은 여전히 하나의 파티션에 과부하를 줄 수 있습니다.
- 컨슈머 처리량: 단일 컨슈머가 초당 2,000개의 메시지를 처리할 수 있고 토픽이 초당 20,000개의 메시지로 피크를 이룬다면, 그룹 내에서 충분한 컨슈머를 실행할 수 있을 만큼의 파티션이 필요합니다. 정확한 수는 추측이 아닌 측정된 컨슈머 속도에 따라 달라집니다.
2. 확장성 목표
- 미래 성장: Kafka는 파티션을 늘릴 수 있지만, 파티션 수를 줄이는 것은 일반적인 제자리 작업이 아닙니다. 일반적으로 새 토픽을 만들고 마이그레이션합니다.
- 리밸런싱: 파티션을 추가하면 컨슈머 그룹 리밸런스가 트리거될 수 있습니다. 바쁜 컨슈머의 경우 처리 속도가 일시적으로 느려지거나 중단될 수 있습니다.
- 키 동작: 파티션을 늘리면 기본 파티셔닝 동작을 사용하는 많은 프로듀서의 키-파티션 매핑이 변경됩니다. 이는 키가 항상 동일한 파티션에 유지된다고 가정한 시스템에 예상치 못한 영향을 줄 수 있습니다.
3. 브로커 리소스
- 디스크: 더 많은 파티션은 더 많은 로그 세그먼트와 관리해야 할 파일을 의미하며, 특히 복제가 있는 경우 더욱 그렇습니다.
- 네트워크: 복제 및 컨슈머 페치가 트래픽을 추가합니다. 문제는 토픽 수뿐만 아니라 복제본, 보존, 메시지 크기, 컨슈머 팬아웃에도 있습니다.
- CPU 및 메모리: 브로커, 컨트롤러, 클라이언트 모두 많은 파티션 수에 대해 일부 오버헤드를 부담합니다. 최신 Kafka 버전은 이전 버전보다 대규모 클러스터를 더 잘 처리하지만, 파티션 수는 여전히 용량 계획 작업입니다.
4. 메시지 순서 요구사항
- 키 기반 순서: 순서가 중요하고 메시지 키를 사용하는 경우, 동일한 키를 가진 레코드는 일반적으로 동일한 파티션으로 이동합니다. 이는 토픽 전체 순서가 아닌 키별 순서를 제공합니다. 핫 키는 여전히 하나의 파티션에 도달하여 하나의 컨슈머를 병목 현상으로 만들 수 있습니다.
- 엄격한 순서 불필요: 엄격한 메시지 순서가 필요하지 않은 경우, 처리량과 병렬 처리를 우선시하여 파티션 간에 메시지를 더 자유롭게 분산할 수 있습니다.
5. 컨슈머 그룹 확장성
언급한 대로, 파티션 수는 컨슈머 그룹 내에서 토픽을 동시에 읽을 수 있는 최대 컨슈머 수를 결정합니다. 더 많은 컨슈머 인스턴스를 추가하여 소비를 확장해야 하는 경우, 원하는 컨슈머 인스턴스 수만큼의 파티션이 있어야 합니다.
파티션 수를 선택하는 실용적인 방법
최적의 파티션 수를 결정하는 데 도움이 되는 실용적인 전략은 다음과 같습니다:
1. 기준선으로 시작하고 모니터링
유용한 기준선은 컨슈머 병렬 처리에서 시작합니다. 이 토픽에 대해 4개의 컨슈머 인스턴스를 예상한다면, 4개 이상의 파티션으로 시작하면 리밸런스와 성장 여유가 생깁니다.
예: 4개의 컨슈머를 실행할 것으로 예상된다면 8개의 파티션으로 시작할 수 있습니다. 그러면 각 컨슈머가 2개의 파티션을 소유하고, 재파티셔닝 전에 몇 개의 컨슈머를 더 추가할 수 있습니다. 이는 법칙이 아닌 출발점입니다.
Kafka 클러스터와 컨슈머 지연을 지속적으로 모니터링하세요. 컨슈머 인스턴스를 더 추가해도 해결할 수 없는 높은 컨슈머 지연(파티션 한계에 도달했기 때문에)이 관찰되면 파티션 수를 늘려야 한다는 명확한 신호입니다.
2. 예상 처리량을 기준으로 계산
측정된 처리량에서 필요한 파티션을 추정할 수 있습니다:
공식:
파티션 수 = (총 예상 처리량 / 컨슈머 인스턴스당 처리량) * 버퍼- 총 예상 처리량: 일일 평균이 아닌 최대 생산 속도를 사용하세요.
- 컨슈머 인스턴스당 처리량: 실제 메시지 크기와 다운스트림 호출로 실제 컨슈머를 측정하세요.
- 버퍼: 스파이크와 성장을 위한 여유 공간을 추가하세요. 계산이 정확하다고 가정하지 마세요.
예:
- 최대 예상 처리량: 초당 50,000개 메시지
- 단일 컨슈머 인스턴스 처리량: 초당 5,000개 메시지
- 버퍼: 1.5배
(50,000 / 5,000) * 1.5 = 15
이 경우 16개의 파티션이 합리적인 시작점입니다. 순서, 브로커 용량 또는 키 분포가 이 숫자에 반대된다면 조정하세요.
3. 브로커 기능 및 한계 고려
클러스터 전체의 총 파티션 수를 염두에 두세요. 모든 곳에 적용되는 안전한 브로커당 파티션 수는 없습니다. 하드웨어, Kafka 버전, 복제 계수, 보존, 메시지 크기, 컨트롤러 부하, 장애 복구 목표가 모두 중요합니다.
"브로커당 100개 파티션" 또는 "브로커당 1,000개 파티션"을 보편적인 진리로 취급하는 대신 브로커 메트릭(요청 지연 시간, 디스크 I/O, 컨트롤러 상태, 미달 복제 파티션, 페이지 캐시 압력, 리밸런스 기간)을 추적하세요. 조직에 테스트된 한계가 있다면 해당 한계를 사용하세요.
4. 키 분포 및 핫 파티션
메시지 키를 사용하는 경우, "더 많은 파티션"이 처리량을 해결할 것이라고 결정하기 전에 키 분포를 분석하세요. 몇 개의 지배적인 키가 핫 파티션을 만들 수 있습니다. 리더를 호스팅하는 브로커는 더 열심히 일하고 해당 파티션에 할당된 컨슈머는 뒤처집니다.
- 해결책: 핫 파티션이 예상된다면 다음과 같은 전략을 고려하세요:
- 비즈니스 순서가 허용할 때 덜 치우친 키를 사용하세요.
- 필요한 순서를 유지하는 경우
customer_id:event_type과 같은 복합 키를 사용하세요. - 하나의 핫 워크플로를 별도의 토픽으로 분할하세요.
- 핫 키를 의도적으로 샤딩한 다음 더 좁은 범위에서 순서를 처리하세요.
파티션을 늘리는 것은 광범위한 분산에 도움이 될 수 있습니다. 해당 키의 모든 레코드가 순서를 유지해야 하는 경우 하나의 키를 여러 컨슈머로 분할하지 않습니다.
파티션이 있는 토픽 생성 및 변경
새 토픽을 생성할 때 파티션 수를 지정합니다.
특정 파티션 수로 토픽 생성
kafka-topics.sh 스크립트 사용:
kafka-topics.sh --create --topic my-high-throughput-topic \
--bootstrap-server kafka-broker-1:9092,kafka-broker-2:9092 \
--partitions 16 \
--replication-factor 3
--partitions 16: 토픽을 16개의 파티션으로 설정합니다.--replication-factor 3: 각 파티션은 내결함성을 위해 다른 브로커에 3개의 복제본을 갖습니다.
기존 토픽의 파티션 증가
이는 일반적인 작업이지만 영향이 있습니다. Kafka는 토픽의 파티션 수를 늘릴 수 있습니다. 줄이려면 다른 토픽으로 마이그레이션해야 합니다.
kafka-topics.sh 스크립트 사용:
kafka-topics.sh --alter --topic my-high-throughput-topic \
--bootstrap-server kafka-broker-1:9092 \
--partitions 24
--partitions 24:my-high-throughput-topic의 파티션을 24개로 증가시킵니다.
파티션 변경 시 중요한 고려사항:
- 컨슈머 리밸런스: 파티션 증가는 구독된 컨슈머 그룹의 리밸런스를 트리거할 수 있습니다. 이는 일시적으로 소비를 중단하거나 느리게 할 수 있습니다.
- 새 파티션: 새 파티션은 토픽에 추가됩니다. 기존 메시지는 재파티셔닝되지 않습니다.
- 키 매핑: 키 기반 프로듀서의 경우, 파티션을 추가하면 키에 대한 향후 레코드가 기록되는 위치가 변경될 수 있습니다.
- 브로커 리소스: 브로커가 추가 리더와 복제본을 처리할 수 있는 용량이 있는지 확인하세요.
전체 기록에 걸친 키 순서가 중요한 경우 주의하세요. 기존 레코드는 이전 파티션에 남아 있지만, 새 레코드는 파티션 수 변경 후 다르게 매핑될 수 있습니다.
파티션 수가 잘못되었음을 알려주는 메트릭
컨슈머 지연은 명백한 신호이지만 그 자체로 충분하지 않습니다. 지연은 느린 다운스트림 데이터베이스, 잘못된 컨슈머 코드, 작은 페치 설정, 브로커 과부하 또는 너무 적은 파티션에서 발생할 수 있습니다.
다음 패턴을 찾으세요:
- 컨슈머는 정상이지만 파티션보다 컨슈머가 적어 일부 인스턴스가 유휴 상태입니다.
- 하나의 파티션이 다른 파티션보다 훨씬 높은 지연을 보입니다.
- 하나의 브로커가 많은 핫 파티션 리더를 보유하고 있습니다.
- 클러스터에 여유 브로커가 있음에도 피크 트래픽 중 프로듀서 지연 시간이 증가합니다.
- 리밸런스가 서비스 수준 목표에 영향을 미칠 만큼 오래 걸립니다.
컨슈머 그룹의 경우:
kafka-consumer-groups.sh --bootstrap-server kafka-broker-1:9092 \
--describe --group my-consumer-group
토픽 레이아웃의 경우:
kafka-topics.sh --bootstrap-server kafka-broker-1:9092 \
--describe --topic my-high-throughput-topic
하나의 파티션만 뒤처진 경우, 작업을 더 많은 파티션에 분산할 수 없으면 컨슈머를 추가해도 도움이 되지 않습니다.
모범 사례 및 함정
해야 할 일:
- 측정된 요구사항으로 시작: 예상 컨슈머 수, 처리량 테스트, 브로커 용량을 사용하세요.
- 컨슈머 병렬 처리와 일치: 컨슈머 인스턴스를 효과적으로 확장할 수 있는 충분한 파티션이 있는지 확인하세요.
- 성장 여유 확보: 나중에 파티션을 추가하는 것은 가능하지만 결과가 없는 것은 아닙니다.
- 키 분포 이해: 키를 사용하는 경우 핫 파티션을 피하기 위해 분포를 분석하세요.
- Kafka 모니터링 도구 활용: 도구를 사용하여 토픽/파티션 메트릭, 컨슈머 지연, 브로커 부하를 추적하세요.
하지 말아야 할 일:
- 과도한 파티셔닝: 너무 많은 파티션은 오버헤드를 증가시키고 리밸런스를 느리게 하며 장애 복구를 더 시끄럽게 만들 수 있습니다.
- 부족한 파티셔닝: 확장성과 처리량을 제한하여 컨슈머 지연을 초래합니다.
- 임의의 숫자를 맹목적으로 따르기: 경험 법칙은 출발점으로만 사용하세요.
- 브로커 용량 잊기: 브로커가 모든 토픽의 총 파티션 수를 처리할 수 있는지 확인하세요.
- 파티션 간 완벽한 순서 기대: 순서는 파티션 내에서만 보장된다는 점을 기억하세요.
합리적인 결정 프로세스
새 토픽의 경우 일반적으로 다음 순서로 작업합니다:
- 순서 요구사항을 정의합니다. 고객별? 계정별? 엄격한 순서 없음?
- 최대 프로듀서 처리량과 메시지 크기를 측정하거나 추정합니다.
- 현실적인 다운스트림 종속성을 가진 하나의 컨슈머 인스턴스를 벤치마킹합니다.
- 필요한 컨슈머 병렬 처리와 성장 여유를 기반으로 파티션을 선택합니다.
- 복제 계수를 포함한 후 총 클러스터 영향을 확인합니다.
- 출시 후 파티션별 지연과 브로커 부하를 모니터링합니다.
파티션 수는 미적 경쟁이 아닙니다. 잘 사용되는 8개의 파티션을 가진 지루한 토픽이 모든 리밸런스를 느리게 하는 96개의 대부분 유휴 파티션을 가진 토픽보다 낫습니다. 실제로 필요한 병렬 처리와 성장 여유를 제공하는 가장 작은 수를 선택하세요.