확장성과 처리량을 위한 Kafka 파티션 최적화
Kafka의 분산형 특성과 파티션 의존성은 높은 처리량과 내결함성을 갖춘 이벤트 스트리밍을 처리하는 능력의 근간이 됩니다. 토픽에 할당된 파티션 수는 확장성, 성능 및 컨슈머 효율성에 직접적인 영향을 미칩니다. 최적의 파티션 수를 선택하는 것은 모든 경우에 적용되는 결정이 아니며, 특정 사용 사례, 예상 데이터 볼륨 및 소비 패턴에 대한 신중한 고려가 필요합니다. 이 문서는 이벤트 스트림의 확장성을 극대화하고 높은 처리량을 달성하기 위해 올바른 Kafka 파티션 수를 결정하는 모범 사례를 안내합니다.
Kafka 파티션 이해하기
기본적으로 Kafka 토픽은 하나 이상의 파티션으로 나뉩니다. 각 파티션은 지속적으로 추가되는 레코드의 순서가 지정되고 변경 불가능한 시퀀스입니다. 파티션은 Kafka에서 병렬 처리의 단위입니다. 이는 다음을 의미합니다.
- 프로듀서가 파티션에 쓰기: 프로듀서는 메시지를 보낼 파티션을 선택할 수 있습니다 (예: 키 또는 라운드 로빈 기반).
- 컨슈머가 파티션에서 읽기: 컨슈머 그룹의 각 컨슈머는 할당된 하나 이상의 파티션에서 독점적으로 읽습니다. 이는 그룹 내 단일 컨슈머 인스턴스에 의해 파티션 내 메시지가 순서대로 처리되도록 보장합니다.
- 브로커가 파티션을 호스팅: Kafka 브로커는 파티션을 저장합니다. 많은 파티션을 가진 토픽은 여러 브로커에 분산될 수 있어 스토리지 및 처리의 수평적 확장이 가능합니다.
파티션의 주요 특징:
- 파티션 내 순서: 단일 파티션 내의 메시지는 항상 순서가 유지됩니다. 그룹 내 컨슈머는 이 순서를 유지합니다.
- 파티션 간 순서 없음: 동일한 토픽의 서로 다른 파티션 간 메시지 순서는 보장되지 않습니다.
- 병렬성: 파티션 수는 프로듀서와 컨슈머 모두에 대한 최대 병렬 처수를 결정합니다. 주제에서 병렬로 소비하는 컨슈머는 파티션 수만큼만 가질 수 있습니다.
파티션 수에 영향을 미치는 요소
Kafka 토픽의 파티션 수를 결정할 때 평가해야 할 몇 가지 중요한 요소가 있습니다.
1. 처리량 요구 사항 (프로듀서 및 컨슈머)
- 프로듀서 처리량: 프로듀서가 높은 속도로 메시지를 생성할 수 있는 경우, 사용 가능한 브로커에 부하를 분산하고 프로듀서 인스턴스의 잠재적 확장을 허용하기에 충분한 파티션이 필요합니다. 더 많은 파티션은 더 높은 총 쓰기 처리량으로 이어질 수 있습니다.
- 컨슈머 처리량: 컨슈머의 총 처리량은 읽을 수 있는 파티션 수에 의해 제한됩니다. N개의 파티션이 있는 경우, 단일 컨슈머 그룹에서 병렬로 메시지를 처리하는 컨슈머는 최대 N개까지 가질 수 있습니다. 소비 속도를 높여야 한다면 컨슈머 인스턴스를 확장하기 위해 더 많은 파티션이 필요합니다.
2. 확장성 목표
- 향후 성장: 파티션을 줄이는 것보다 토픽에 파티션을 추가하는 것이 더 쉬운 경우가 많습니다 (파티션 증가에도 영향이 있음). 시간이 지남에 따라 예상되는 데이터 볼륨 증가 및 처리 요구 사항을 고려하십시오.
- 리밸런싱: 기존 토픽에 파티션을 추가하면 컨슈머 그룹에 대한 파티션 리밸런스가 트리거됩니다. 이는 Kafka 작업의 정상적인 부분이기는 하지만, 과도한 파티션 추가로 인한 빈번한 리밸런싱은 가용성에 영향을 줄 수 있습니다. 합리적인 초기 파티션 수를 설정하고 필요할 때만 늘리는 것이 좋습니다.
3. 브로커 리소스
- 디스크 공간: 각 파티션은 이를 호스팅하는 브로커에서 디스크 공간을 차지합니다. 파티션이 많을수록 리더/팔로워 복제본에 대한 오버헤드가 증가하고 잠재적으로 디스크 I/O가 높아집니다.
- 네트워크 대역폭: 파티션은 프로듀서, 브로커 및 컨슈머 간의 데이터 전송을 수반합니다. 많은 수의 파티션은 네트워크 트래픽 및 관리 오버헤드를 증가시킬 수 있습니다.
- CPU 및 메모리: 각 파티션은 리더십, 복제 및 요청 처리를 관리하기 위해 브로커 리소스를 필요로 합니다. 파티션이 너무 많으면 브로커 리소스를 압도할 수 있습니다.
4. 메시지 순서 요구 사항
- 키 기반 순서: 메시지 순서가 중요하고 메시지 키를 사용하는 경우, 동일한 키를 가진 모든 메시지는 동일한 파티션으로 이동합니다. 이 시나리오에서는 파티션 수가 동일한 키를 가진 메시지 처리의 원하는 병렬 처리와 일치해야 합니다. 핫 키(hot key)가 있으면 항상 동일한 파티션에 위치하게 되어 해당 파티션에 할당된 컨슈머의 병렬 처리 잠재력이 제한됩니다.
- 엄격한 순서 없음: 엄격한 메시지 순서가 요구 사항이 아닌 경우, 처리량과 병렬성을 우선시하여 파티션 전반에 메시지를 더 자유롭게 분산할 수 있습니다.
5. 컨슈머 그룹 확장성
언급했듯이, 파티션 수는 컨슈머 그룹 내에서 토픽에서 동시에 읽을 수 있는 최대 컨슈머 수를 결정합니다. 더 많은 컨슈머 인스턴스를 추가하여 소비를 확장해야 하는 경우, 원하는 컨슈머 인스턴스 수만큼 적어도 파티션을 가져야 합니다.
파티션 수 결정을 위한 전략
최적의 파티션 수에 도달하는 데 도움이 되는 실용적인 전략은 다음과 같습니다.
1. 기준점을 설정하고 모니터링
일반적인 시작점은 초기 예상 컨슈머 인스턴스 수와 성장을 위한 버퍼를 기반으로 파티션 수를 설정하는 것입니다.
- 예시: 토픽에 대해 4개의 컨슈머 인스턴스를 실행할 것으로 예상되는 경우, 6~10개의 파티션으로 시작합니다. 이렇게 하면 즉시 파티션 수를 늘릴 필요 없이 몇 개의 컨슈머 인스턴스를 더 추가할 수 있으며 쓰기 병렬 처리도 일부 제공됩니다.
지속적으로 Kafka 클러스터와 컨슈머 지연(lag)을 모니터링하십시오. 컨슈머 지연이 높고 이를 더 많은 컨슈머 인스턴스를 추가하여 해결할 수 없는 경우(파티션 한도에 도달했기 때문에), 파티션 수를 늘려야 한다는 명확한 신호입니다.
2. 예상 처리량을 기반으로 계산
예상 최대 처리량과 단일 컨슈머 인스턴스의 처리량 기능을 고려하여 필요한 파티션을 추정할 수 있습니다.
-
공식:
파티션 수 = (총 예상 처리량 / 컨슈머 인스턴스당 처리량) * 버퍼- 총 예상 처리량: 토픽이 처리해야 하는 초당 최대 메시지 수 (예: 초당 100,000개 메시지).
- 컨슈머 인스턴스당 처리량: 단일 컨슈머 인스턴스가 초당 처리할 수 있는 최대 메시지 수. 이는 특정 애플리케이션 및 인프라에 대해 측정하고 이해해야 합니다.
- 버퍼: 급증, 향후 성장 및 즉시 한도에 도달하는 것을 방지하기 위한 승수 (예: 1.5배 ~ 2배).
-
예시:
- 최대 예상 처리량: 초당 50,000개 메시지
- 단일 컨슈머 인스턴스 처리량: 초당 5,000개 메시지
- 버퍼: 1.5배
파티션 수 = (50,000 / 5,000) * 1.5 = 10 * 1.5 = 15
이 경우 16개의 파티션으로 시작할 수 있습니다.
3. 브로커 기능 및 한도 고려
Kafka 클러스터가 효과적으로 처리할 수 있는 총 파티션 수를 염두에 두십시오. 단일 고정된 제한은 없지만, 브로커당 파티션 수가 증가함에 따라 성능이 저하됩니다. 일반적으로 브로커당 100~200개를 초과하지 않도록 목표하는 것이 좋지만, 이는 브로커 하드웨어 및 작업량에 따라 크게 달라질 수 있습니다.
- 총 파티션: 브로커가 5개이고 브로커당 파티션을 100개 미만으로 유지하려면 모든 토픽의 총 파티션 수는 이상적으로 500개 미만이어야 합니다.
4. 키 분포 및 핫 파티션
메시지 키를 사용하는 경우 키 분포를 분석하십시오. 소수의 키가 압도적으로 우세하면 모두 동일한 파티션으로 이동하여 "핫 파티션"을 생성합니다. 이는 파티션을 호스팅하는 브로커가 과부하되거나 해당 파티션에 할당된 단일 컨슈머 인스턴스가 따라잡지 못할 때 프로듀서 모두에게 병목 현상이 될 수 있습니다.
- 해결책: 핫 파티션이 예상되는 경우 다음과 같은 전략을 고려하십시오.
- 로드 분산을 위해 복합 키를 사용하거나 키를 해시 처리합니다.
- 심지어 일반적인 키도 분산시켜 더 많은 컨슈머 병렬 처리를 허용하도록 파티션 수를 늘립니다.
파티션을 사용한 토픽 생성 및 수정
새 토픽을 생성할 때 파티션 수를 지정합니다.
특정 수의 파티션으로 토픽 생성
kafka-topics.sh 스크립트 사용:
kafka-topics.sh --create --topic my-high-throughput-topic \n --bootstrap-server kafka-broker-1:9092,kafka-broker-2:9092 \n --partitions 16 \n --replication-factor 3
--partitions 16: 토픽을 16개의 파티션으로 설정합니다.--replication-factor 3: 내결함성을 위해 각 파티션은 서로 다른 브로커에 3개의 복제본을 갖게 됩니다.
기존 토픽의 파티션 수 늘리기
이것은 일반적인 작업이지만 영향이 있습니다. 파티션을 늘릴 수는 있지만 줄일 수는 없습니다.
kafka-topics.sh 스크립트 사용:
kafka-topics.sh --alter --topic my-high-throughput-topic \n --bootstrap-server kafka-broker-1:9092 \n --partitions 24
--partitions 24:my-high-throughput-topic의 파티션을 24개로 늘립니다.
파티션 수정 시 중요 고려 사항:
- 컨슈머 리밸런스: 파티션을 늘리면 해당 토픽을 구독하는 모든 컨슈머 그룹에 대해 컨슈머 리밸런스가 트리거됩니다. 이는 일시적으로 소비를 중단시킬 수 있습니다.
- 새 파티션: 새 파티션은 토픽에 추가됩니다. 기존 메시지는 다시 파티션 처리되지 않습니다.
- 브로커 리소스: 브로커가 증가된 파티션 수를 처리할 수 있는 충분한 용량을 가지고 있는지 확인하십시오.
모범 사례 및 함정
해야 할 일:
- 보수적으로 시작하고 모니터링: 합리적인 수로 시작하여 관찰된 메트릭(컨슈머 지연, 처리량)을 기반으로 필요에 따라 확장하십시오.
- 컨슈머 병렬 처리와 일치: 컨슈머 인스턴스를 효과적으로 확장하기에 충분한 파티션이 있는지 확인하십시오.
- 향후 성장을 고려: 데이터 볼륨 및 처리 요구 사항의 예상 증가를 고려하십시오.
- 키 분포 이해: 키를 사용하는 경우 핫 파티션을 피하기 위해 분포를 분석하십시오.
- Kafka 모니터링 도구 활용: 토픽/파티션 메트릭, 컨슈머 지연 및 브로커 부하를 추적하기 위해 도구를 사용하십시오.
하지 말아야 할 일:
- 과도한 파티션 할당: 파티션이 너무 많으면 오버헤드가 증가하고, 리밸런스가 느려지며, 브로커 리소스 고갈 가능성이 높아집니다.
- 파티션 부족: 확장성과 처리량을 제한하여 컨슈머 지연을 유발합니다.
- 임의의 숫자를 맹목적으로 따르기: 특정 사용 사례와 예상 부하를 기반으로 파티션을 결정하십시오.
- 브로커 용량 간과: 브로커가 모든 토픽의 총 파티션 수를 처리할 수 있는지 확인하십시오.
- 파티션 간 완벽한 순서를 기대: 순서는 단일 파티션 내에서만 보장된다는 점을 기억하십시오.
결론
Kafka 파티션 최적화는 확장 가능하고 높은 처리량을 갖춘 이벤트 스트리밍 아키텍처를 구축하는 데 중요한 단계입니다. 처리량 요구 사항, 확장성 목표, 컨슈머 병렬 처리 및 브로커 리소스를 신중하게 고려함으로써 각 토픽에 대한 최적의 파티션 수를 정보에 입각하여 결정할 수 있습니다. 파티션 수는 정적이 아니며 애플리케이션이 발전함에 따라 조정이 필요할 수 있는 구성이라는 점을 기억하십시오. 지속적인 모니터링과 용량 계획에 대한 사전 예방적 접근 방식은 Kafka 토픽이 계속해서 성능과 확장성을 유지하도록 보장할 것입니다.