Kafka 아키텍처 설명: 핵심 구성 요소 및 역할
Apache Kafka는 높은 처리량과 내결함성을 갖춘 분산 이벤트 스트리밍 플랫폼입니다. 이 플랫폼의 아키텍처를 이해하는 것은 Kafka가 어떻게 데이터를 안정적으로 처리하고 저장하는지 파악하는 데 필수적입니다. 기본적인 개념 증명(proof-of-concept)을 설정하든, 중요한 애플리케이션을 확장하든, 효과적인 배포 및 관리를 위해서는 브로커(Brokers), 토픽(Topics), 프로듀서(Producers), 컨슈머(Consumers), ZooKeeper와 같은 핵심 구성 요소의 역할을 파악하는 것이 중요합니다.
이 가이드에서는 Kafka의 아키텍처를 체계적으로 분석하여 이러한 구성 요소들이 어떻게 상호 작용하여 실시간 데이터 이동 및 저장에 대한 강력하고 확장 가능한 시스템을 형성하는지 자세히 설명합니다.
Kafka 아키텍처의 핵심 구성 요소
Kafka는 여러 머신(노드)에 기능을 분산하여 확장성과 복원력을 제공하는 분산 시스템으로 작동합니다. 핵심 아키텍처는 다섯 가지 주요 엔티티의 조정된 노력을 기반으로 합니다.
1. Kafka 브로커 (서버)
Kafka 클러스터는 하나 이상의 서버로 구성되며, 이 서버를 브로커(Brokers)라고 합니다. 이러한 브로커는 데이터(로그)를 저장하고 클라이언트 요청(읽기 및 쓰기)을 처리하는 역할을 담당합니다.
- 역할: 브로커는 프로듀서로부터 메시지를 수신하여 토픽 파티션에 커밋하고, 해당 메시지를 컨슈머에게 제공합니다. 이들이 클러스터의 중추 역할을 합니다.
- 내결함성: 브로커에 장애가 발생하면, 복제(replication)가 올바르게 구성된 경우 복제 브로커가 해당 파티션을 처리하여 데이터 가용성을 보장합니다.
- 확장성: 클러스터에 브로커를 추가하면 부하와 저장 용량을 분산하여 시스템을 수평적으로 확장할 수 있습니다.
2. 토픽 (데이터 범주)
토픽은 Kafka에서 데이터 스트림을 분류하는 기본 메커니즘입니다. 데이터베이스의 테이블이나 파일 시스템의 폴더에 비유할 수 있습니다.
- 정의: 토픽은 레코드가 게시되는 피드 이름입니다. 토픽 내의 데이터는 항상 시간 순서대로 정렬됩니다.
- 파티션: 병렬 처리 및 확장성을 달성하기 위해 토픽은 파티션(Partitions)으로 나뉩니다. 각 파티션은 순서가 지정된 변경 불가능한 레코드 시퀀스입니다.
- 파티션 내의 데이터는 엄격하게 순서가 지정되며 오프셋(offset)이라는 증가하는 ID가 할당됩니다.
- 메시지는 키(제공된 경우) 또는 라운드 로빈(round-robin) 방식으로 파티션에 분산됩니다.
- 복제: 내결함성을 위해 파티션은 여러 브로커에 복제됩니다. 활성 주 복사본을 보유한 브로커는 리더(Leader)이며, 나머지는 팔로워(Follower)입니다.
예시: 토픽 구성
토픽을 생성할 때 파티션 수와 복제 계수를 정의합니다. 예를 들어, user_activity라는 이름의 토픽을 3개의 파티션과 3의 복제 계수로 생성하려면 다음 명령을 사용합니다.
kafka-topics.sh --create --topic user_activity --bootstrap-server localhost:9092 --partitions 3 --replication-factor 3
3. 프로듀서 (데이터 작성자)
프로듀서는 Kafka 토픽으로 레코드 스트림을 게시(쓰기)하는 클라이언트 애플리케이션입니다.
- 기능: 프로듀서는 레코드를 키-값 쌍(선택적 타임스탬프 및 헤더 포함)으로 형식화하여 Kafka 클러스터로 보냅니다.
- 파티션 할당: 프로듀서는 메시지가 어떤 파티션으로 갈지 결정합니다. 메시지에 키가 있으면 Kafka는 키에 대한 해싱 메커니즘을 사용하여 일관되게 동일한 파티션에 매핑합니다. 키가 제공되지 않으면 메시지는 라운드 로빈 방식으로 분산됩니다.
- 승인 (Acks): 프로듀서는
acks설정을 사용하여 필요한 내구성 수준을 구성합니다. 이 설정은 쓰기가 성공한 것으로 간주되기 전에 몇 개의 브로커가 수신을 확인해야 하는지를 결정합니다(예:acks=all은 최대 내구성을 보장합니다).
4. 컨슈머 (데이터 판독기)
컨슈머는 하나 이상의 토픽을 구독하고 해당 토픽에 게시된 레코드 스트림을 처리하는 클라이언트 애플리케이션입니다.
- 소비 메커니즘: 컨슈머는 파티션 내의 오프셋을 기준으로 순차적으로 데이터를 읽습니다. 컨슈머는 성공적으로 처리한 오프셋을 추적하는 책임이 있습니다.
- 컨슈머 그룹: 컨슈머는 일반적으로 컨슈머 그룹(Consumer Group) 내에서 작동합니다. Kafka는 특정 컨슈머 그룹 내에서 각 파티션이 하나의 컨슈머 인스턴스에 의해서만 소비되도록 보장합니다. 이를 통해 파티션 수만큼 컨슈머 인스턴스를 추가하여 읽기를 수평적으로 확장할 수 있습니다.
예시: 컨슈머 오프셋
컨슈머가 메시지를 처리할 때, 마지막으로 처리된 오프셋을 주기적으로 Kafka에 커밋합니다(일반적으로 내부 토픽인 __consumer_offsets에 저장됨). 컨슈머가 충돌하면, 동일한 그룹 내에서 다시 시작될 때 마지막으로 커밋된 오프셋부터 읽기를 재개하여 데이터 손실이나 이중 처리를 방지합니다(커밋 전략에 따라 다름).
5. Apache ZooKeeper (조정 서비스)
역사적으로 Apache ZooKeeper는 Kafka 클러스터의 메타데이터와 상태를 관리하는 데 필수적이었습니다. Kafka는 자체 관리 메타데이터 아키텍처(Kafka Raft Metadata Mode, 또는 KRaft)로 전환 중이지만, ZooKeeper는 많은 기존의 널리 배포된 클러스터에서 여전히 중요한 구성 요소입니다.
- 메타데이터 저장: ZooKeeper는 활성 브로커 목록, 브로커에 대한 파티션 할당, 토픽의 구성 세부 정보를 포함한 클러스터 구성을 저장합니다.
- 컨트롤러 선출: ZooKeeper는 Kafka 컨트롤러(Kafka Controller)의 선출을 관리합니다. 컨트롤러는 파티션 리더십 변경, 복제본 동기화 및 전반적인 클러스터 상태 변경을 관리하기 위해 선출된 브로커입니다.
| 구성 요소 | 주요 책임 | 비유 |
|---|---|---|
| 브로커 | 데이터 로그 저장 및 제공 | 데이터베이스 서버 |
| 토픽 | 데이터 스트림 분류 | 테이블/범주 |
| 파티션 | 토픽 내 순서 지정 및 병렬 처리 | 샤드/로그 파일 |
| 프로듀서 | 토픽으로 데이터 쓰기 | 데이터 수집 도구 |
| 컨슈머 | 토픽에서 데이터 읽기 | 데이터 처리기 |
| ZooKeeper | 클러스터 조정 및 메타데이터 관리 | 클러스터 관리자 |
데이터 흐름 및 상호 의존성
아키텍처는 책임의 명확한 흐름을 설정하여 작동합니다.
- 프로듀서 초기화: 프로듀서는 클러스터의 모든 브로커(게이트웨이 역할)에 연결하여 대상 토픽에 대한 메타데이터를 요청합니다.
- 리더 리디렉션: 브로커는 프로듀서를 대상 파티션의 현재 리더 복제본으로 리디렉션합니다.
- 데이터 쓰기: 프로듀서는 레코드를 리더 브로커로 보냅니다.
- 복제: 리더 브로커는 레코드를 로컬 로그에 쓰고, 오프셋을 할당한 다음, 지정된 모든 팔로워 복제본으로 레코드를 복제합니다.
- 승인: 구성된 복제본 수(
acks수준)가 수신을 확인하면, 리더는 성공 사실을 프로듀서에게 다시 알립니다. - 소비: 컨슈머는 관심 있는 파티션의 리더 브로커에게 폴링(poll)하고, 지정된 오프셋부터 시작하여 레코드를 요청합니다.
중요 고려 사항: 데이터 보존
기존 메시지 큐와 달리 Kafka는 근본적으로 분산 커밋 로그입니다. 데이터는 컨슈머가 읽었는지 여부에 관계없이 구성된 기간(기본값은 종종 7일) 동안 또는 크기 임계값에 도달할 때까지 브로커 디스크에 보존됩니다. 이러한 영속성 덕분에 새 컨슈머나 지연된 컨슈머도 이전 데이터를 읽을 수 있습니다.
모범 사례: 애플리케이션의 복구 요구 사항에 따라 디스크 공간을 효율적으로 관리하기 위해 토픽에서 log.retention.hours 또는 log.retention.bytes를 신중하게 구성하십시오.
확장 및 복원력
Kafka의 아키텍처는 본질적으로 수평 확장 및 복원력을 위해 설계되었습니다.
- 쓰기/읽기 확장: 더 많은 브로커를 추가하고 트래픽이 많은 토픽의 파티션 수를 늘려 달성합니다.
- 내결함성: 복제를 통해 달성됩니다. 파티션의 리더 브로커가 실패하면 ZooKeeper(또는 KRaft 메커니즘)가 실패를 감지하고, 나머지 팔로워들은 새로운 리더를 선출하기 위해 협력하여 프로듀서 및 컨슈머의 최소 다운타임으로 지속적인 가용성을 보장합니다.
브로커가 파티션을 저장하는 방법, 프로듀서가 키를 통해 메시지를 라우팅하는 방법, 컨슈머 그룹이 오프셋을 관리하는 방법을 포함한 이러한 핵심 아키텍처 구성 요소를 마스터하면 고성능 이벤트 스트리밍을 위해 Kafka를 배포하고 조정하는 데 필요한 기반을 얻게 됩니다.