아파치 카프카는 대량 이벤트를 실시간으로 처리하는 능력으로 유명합니다. 그러나 수백만 개의 이벤트를 처리하기 위해서는 Kafka 프로듀서 서비스와 컨슈머 서비스를 구현할 때 특정한 모범 사례를 따를 필요가 있습니다.
시작하기 전에Kafka를 사용하기전에, 언제 Kafka를 사용해야 하는지 이해해봅시다:
- 대량 이벤트 스트림. 애플리케이션/서비스가 사용자 활동 이벤트, 웹사이트 클릭 이벤트, 센서 데이터 이벤트, 로깅 이벤트 또는 주식 시장 업데이트와 같이 지속적인 이벤트 스트림을 생성할 때, Kafka의 대량 처리 및 낮은 대기 시간 능력이 매우 유용합니다.
- 실시간 분석. Kafka는 특히 실시간 데이터 처리 파이프라인을 구축하는 데 매우 유용하며, 데이터가 도착하는 즉시 처리해야 하는 경우에 사용합니다. Kafka를 사용하면 Kafka streams, Apache Spark 또는 Flink와 같은 분석 엔진으로 데이터를 스트리밍하여 즉각적인 분석/인사이트 및 스트림 또는 배치 처리를 할 수 있습니다.
- 애플리케이션의 분리. 중앙 메시지 허브 역할을 하면서 애플리케이션의 다른 부분을 분리함으로써 서비스의 독립적인 개발 및 확장을 가능하게 하며, 책임 있는 분리 원칙을 촉진합니다.
- 시스템 간 데이터 통합.분산 시스템을 통합할 때, Kafka는 팀/프로젝트 간의 다양한 애플리케이션 간에 데이터를 효율적으로 전송할 수 있으며 신뢰할 수 있는 데이터 브로커 역할을 합니다.
다른 큐잉 시스템과의 주요 차이점
아래는 Apache Kafka가 ActiveMQ, ZeroMQ, VerneMQ와 같은 시스템과의 차이점입니다:
지속적인 저장
Kafka는 이벤트를 분산 로그에 저장하여 데이터를 언제든지 재생할 수 있는 기능과 시스템/노드 장애 시에도 데이터 지속성을 제공하며, 이는 일부 전통적인 메시지 큐가 Redis와 같은 인메모리 저장소에 의존하는 것과 다릅니다.
파티셔닝
데이터는 브로커/주제 간에 파티셔닝되어 대규모 데이터 스트림의 병렬 처리를 가능하게 하고 높은 처리량을 제공합니다. 이는 소비자 스레드가 개별 파티셔닝에 연결되어 수평 확장을 촉진하는 데 도움이 됩니다.
소비자 그룹
여러 소비자가 동일한 주제를 구독하고 파티션 내의 서로 다른 오프셋에서 읽을 수 있어, 다양한 팀이 동일 데이터를 서로 다른 목적으로 소비하고 처리할 수 있는 중복 소비 패턴을 허용합니다. 몇 가지 예는:
- ML 팀이 의심스러운 활동을 탐지하기 위해 소비한 사용자 활동
- 추천 팀은 추천 사항을 구축합니다
- 광고 팀은 관련 광고를 생성합니다
카프카 프로듀서 모범 사례
배치 크기 및 대기 시간
batch.size
와 linger.ms
를 구성하여 카프카 프로듀서의 처리량을 증가시킬 수 있습니다. batch.size
는 바이트 단위의 배치 최대 크기입니다. 카프카는 프로듀서에게 보내기 전에 배치하려고 시도합니다.
linger.ms
는 프로듀서가 처리할 배치에 추가 메시지가 추가될 때까지 대기하는 최대 시간을 밀리초 단위로 결정합니다.
배치 크기
와 linger.ms
설정을 구성하면 처리 시스템에 전송하기 전에 얼마나 많은 데이터가 축적되는지를 제어하여 시스템 성능을 크게 향상시킬 수 있으며, 대량의 데이터를 처리할 때 더 나은 처리량과 감소된 지연 시간을 허용합니다. 선택한 값에 따라 약간의 지연이 발생할 수도 있습니다. 특히, 올바른 linger.ms
와 함께 큰 배치 크기는 데이터 전송 효율성을 최적화할 수 있습니다.
압축
처리량을 증가시키는 또 다른 방법은 compression.type
설정을 통해 압축을 활성화하는 것입니다. 프로듀서는 데이터를 브로커에 전송하기 전에 gzip
, snappy
또는 lz4
로 압축할 수 있습니다. 대량의 데이터 볼륨에 대해 이 설정은 네트워크 효율성과 함께 압축 오버헤드를 도와줍니다. 또한 대역폭을 절약하고 시스템의 처리량을 증가시킵니다. 추가적으로 적절한 직렬 변환기와 키 직렬 변환기를 설정함으로써, 소비자와 호환되는 형식으로 데이터가 직렬화되도록 할 수 있습니다.
재시도 및 아이덴포턴시
카프카 프로듀서의 신뢰성을 보장하기 위해 재시도와 아이덴포턴시를 활성화해야 합니다. retries
를 설정하면, 프로듀서는 특정 시도 횟수 내에 브로커로부터 ack
를 받지 못한 데이터 배치를 자동으로 재전송할 수 있습니다.
확인
이 설정은 메시지가 성공적으로 전송되었다고 간주되기 전에 브로커로부터 요구되는 확인 수준을 제어합니다. 올바른 acks
수준을 선택함으로써 애플리케이션의 신뢰성을 제어할 수 있습니다. 아래는 이 설정에 대한 허용된 값입니다.
- 0 – 가장 빠르지만 메시지 전달 보장이 없습니다.
- 1 – 메시지가 리더 브로커에 기록되면 확인되며, 기본적인 신뢰성을 제공합니다.
- all – 모든 복제본이 확인할 때만 메시지가 전달된 것으로 간주되어 높은 내구성을 보장합니다.
작업 부하 기반 구성 조정
메시지 전송 속도, 일괄 크기 및 오류율과 같은 메트릭을 추적하여 성능 병목 현상을 식별해야 합니다. 피처/데이터 수정 또는 업데이트에 따라 생산자 설정을 정기적으로 확인 및 조정해야 합니다.
Kafka 소비자 최적화 방법
소비자 그룹
모든 Kafka 소비자는 소비자 그룹에 속해야 하며, 소비자 그룹은 한 명 이상의 소비자를 포함할 수 있습니다. 그룹 내에서 더 많은 소비자를 만들면 모든 파티션에서 읽을 수 있어 데이터 양을 처리할 수 있습니다. group.id
구성은 소비자가 속한 소비자 그룹을 식별하여 동일한 주제에서 소비하는 여러 소비자 간의 부하 분산을 허용합니다. 최상의 실천 방법은 동일한 애플리케이션 내에서 쉽게 소비자 그룹을 식별하기 위해 의미 있는 그룹 ID를 사용하는 것입니다.
옵셋 커밋
애플리케이션이 옵셋을 커밋하는 시기를 제어할 수 있으며, 이를 통해 데이터 손실을 피할 수 있습니다. 옵셋을 커밋하는 두 가지 방법이 있습니다: 자동 및 수동. 고처리량 애플리케이션의 경우 더 나은 제어를 위해 수동 커밋을 고려해야 합니다.
- 자동.offset.리셋 – 커밋된 오프셋이 없는 토픽을 소비자가 처음 소비할 때 수행할 작업을 정의합니다(예: 새로운 토픽 또는 그룹에 처음으로 가입하는 소비자). 옵션으로는
earliest
(처음부터 읽기),latest
(끝부터 읽기) 또는none
(에러 발생)이 있습니다. 대부분의 사용 사례에서 새로운 소비자가 그룹에 가입할 때 데이터 손실을 피하기 위해 “earliest”를 선택하십시오.소비자가 다시 시작되거나 그룹에 추가될 때 적절한 동작을 보장하도록 데이터 소비를 시작하는 방법을 제어합니다. - enable.auto.commit – 주기적으로 오프셋을 자동으로 커밋하도록 도와줍니다. 보통 신뢰성이 높이 필요하지 않은 대부분의 프로덕션 시나리오에 대해 값은
false
로 설정하고 응용 프로그램 논리 내에서 오프셋을 수동으로 커밋하여 정확한 처리를 보장합니다.데이터 처리에 대한 더 많은 제어를 제공하여 오프셋 커밋을 관리할 수 있습니다. - auto.commit.interval.ms – i밀리초 단위의 간격으로,
enable.auto.commit
이true
로 설정된 경우 오프셋이 자동으로 커밋됩니다. 예기치 않은 실패로 인한 데이터 손실을 방지하기 위해 애플리케이션의 처리 시간에 따라 수정하세요.
가져오기 크기 및 최대 폴링 레코드
이 구성은 각 요청에서 검색되는 레코드 수를 제어하는 데 도움이 되며, fetch.min.bytes
및 max.poll.records
를 구성합니다. 이 값을 증가시키면 애플리케이션의 처리량을 개선하면서 CPU 사용량을 줄이고 브로커에 대한 호출 수를 줄이는 데 도움이 될 수 있습니다.
- fetch.min.bytes – 브로커에서 단일 폴링 요청으로 가져올 최소 바이트 수입니다. 불필요한 네트워크 호출을 피하기 위해 작은 값을 설정하되, 과도한 폴링을 방지하기 위해 너무 작지 않도록 하세요. 이는 작은 빈번한 요청을 방지하여 네트워크 효율성을 최적화하는 데 도움이 됩니다.
- fetch.max.bytes – 브로커에서 단일 폴링 요청으로 가져올 수 있는 최대 바이트 수입니다. 소비자 작업자가 과부하에 걸리지 않도록 사용 가능한 메모리에 따라 조정하세요. 이는 단일 폴에서 검색되는 데이터 양을 줄여 메모리 문제를 피합니다.
- max.poll.interval.ms – 타임아웃되기 전에 폴 요청이 데이터를 반환할 때까지 기다리는 최대 시간입니다. 데이터가 없을 경우 소비자가 멈추거나 지연되는 것을 피하기 위해 적절한 타임아웃을 설정하세요. 이는 소비자가 메시지를 너무 오래 기다리며 갇히는 것을 방지하는 데 도움이 됩니다. (때때로, liveness probe에 영향을 받을 경우 k8s 포드가 재시작될 수 있습니다).
파티션 할당
이는 그룹 내 소비자에게 파티션(partition.assignment.strategy
)을 할당하는 데 사용되는 전략입니다 (예: range
, roundrobin
). 대부분의 시나리오에서는 range
를 사용하여 소비자 간에 파티션을 고르게 분배하세요. 이는 그룹 내 소비자 간의 균형 잡힌 부하 분배를 가능하게 합니다.
카프카를 사용하기 전에 고려해야 할 몇 가지 중요한 사항이 있습니다:
- 복잡성. 카프카를 구현하려면 파티셔닝 및 오프셋 관리와 같은 분산 시스템 개념에 대한 심층적인 이해가 필요합니다. 이는 카프카의 고급 기능과 구성으로 인한 것입니다.
- 모니터링 및 관리. 모니터링 및 카프카 클러스터 관리를 구현하는 것은 고가용성과 성능을 보장하기 위한 중요한 요소입니다.
- 보안. 카프카 토픽을 통해 흐르는 민감한 데이터를 보호하기 위해 견고한 보안 관행을 구현하는 것도 중요합니다.
이러한 모범 사례를 구현하면 카프카 기반 애플리케이션을 확장하여 수백만/수십억 건의 이벤트를 처리할 수 있습니다. 그러나 최적의 구성은 애플리케이션의 특정 요구 사항에 따라 다를 수 있음을 기억하는 것이 중요합니다.
Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads