Programming/프로그래밍 내용 정리
Apache Kafka 톺아보기
domean
2025. 5. 30. 08:33
🔵 Apache Kafka란?
- 오픈소스 분산 데이터 스트리밍 플랫폼
- 링크드인에서 개발, 현재는 Apache 재단에서 관리
- 실시간 데이터 스트림의 게시(Publish), 구독(Subscribe), 저장(Storage), 처리(Process) 기능 제공
- 대규모 데이터 이동에 적합 (A → B뿐 아니라 A → 여러 지점(Z) 동시에 가능)
- 전통적 메시징 시스템의 대안
- 높은 처리량(Throughput) 과 내결함성(Fault Tolerance)
- 지속성(Persistence) 기반 저장 구조 (디스크에 로그 형태로 저장)
- 소비자가 개별 오프셋을 관리하며, 재처리나 리플레이가 용이
🔵 Apache Kafka 구성 요소 요약
Kafka는 메시지를 효율적으로 전달하고 저장하기 위한 분산형 스트리밍 플랫폼입니다.
아래는 Kafka의 핵심 구성 요소입니다.
구성 요소 | 설명 요약 |
브로커 | 메시지를 저장하고 컨슈머에게 전달하는 Kafka 서버 인스턴스 |
메시지 | Kafka에서 주고받는 데이터의 기본 단위, 바이트 배열 형태로 저장됨 |
토픽 | 메시지를 논리적으로 분류하는 단위, 데이터의 주제 또는 카테고리 역할 |
파티션 | 토픽을 나눈 물리적 단위로, 순서를 보장하고 병렬 처리 및 분산 저장을 가능하게 함 |
클러스터 | 여러 브로커의 집합으로 고가용성과 확장성 제공 |
프로듀서 | Kafka에 메시지를 발행하는 클라이언트 |
컨슈머 | Kafka로부터 메시지를 읽는 클라이언트 |
컨슈머 그룹 | 하나의 메시지를 중복 없이 병렬로 처리하기 위한 단위 |
리밸런싱 | 컨슈머 그룹 내에서 파티션 소유권을 재조정하는 과정 |
리플리케이션 | 장애 복구와 가용성을 위한 파티션 복제 구조 |
🔵 Apache Kafka 구성 요소 상세
1. 브로커 (Broker)
📌 Kafka에서 메시지를 저장하고 전달하는 서버 인스턴스
✅ 핵심 기능
- Kafka 클러스터의 기본 구성 단위
- 메시지를 디스크에 저장 (토픽/파티션 기반)
- 컨슈머 요청에 따라 메시지 전송
- 리더/팔로워 파티션 관리 및 복제 수행
📘 상세 설명
- 브로커는 Kafka 서버 인스턴스로, 클러스터를 구성하는 노드 단위입니다.
- 프로듀서로부터 메시지를 받아 지정된 토픽/파티션에 저장합니다.
- 컨슈머가 특정 오프셋을 요청하면 해당 메시지를 디스크에서 읽어 전송합니다.
- 리더 파티션이 메시지 처리의 중심이 되고, 팔로워는 이를 복제하여 고가용성을 보장합니다.
- 메타데이터 관리 역할은 ZooKeeper 또는 KRaft 컨트롤러가 수행합니다.
2. 메시지 (Message)
📌 Kafka에서 주고받는 가장 작은 데이터 단위
✅ 핵심 특징
- 바이트 배열 형태로 저장됨
- 키/값 구조를 가질 수 있음
- 오프셋을 통해 순서를 추적 가능
📘 상세 설명
- Kafka의 메시지는 실제로 전송되는 데이터 조각으로, JSON, Avro, 문자열 등 다양한 포맷이 사용될 수 있습니다.
- 각 메시지는 토픽의 특정 파티션에 기록되고, 고유한 오프셋(offset)을 부여받습니다.
- 메시지 키가 지정되면 동일 키 메시지는 항상 동일 파티션에 저장되어 순서 보장이 가능합니다.
3. 토픽 (Topic)
📌 메시지를 논리적으로 분류하는 단위 (주제별 구분)
✅ 핵심 특징
- 메시지를 분류하는 이름 공간
- 다수의 파티션으로 구성됨
- 여러 컨슈머 그룹이 독립적으로 구독 가능
📘 상세 설명
- 토픽은 데이터 스트림을 구분하는 단위입니다. 예: 주문, 로그인, 알림 등
- 토픽은 내부적으로 여러 개의 파티션으로 분산되어 저장됩니다.
- 컨슈머 그룹마다 고유한 오프셋을 유지하므로, 동일 토픽을 다수 애플리케이션이 독립적으로 처리 가능
4. 파티션 (Partition)
📌 병렬성과 순서를 보장하는 토픽의 물리적 저장 단위
✅ 핵심 특징
- 각 파티션은 순차적인 오프셋을 가짐
- 파티션 단위로 메시지가 저장되고 읽힘
- 다른 브로커에 분산 저장되어 확장성 확보
📘 상세 설명
- 하나의 토픽은 여러 개의 파티션으로 구성됩니다.
- 파티션은 로그 파일로 구성되어, 메시지는 append-only 형식으로 저장됩니다.
- 동일 키의 메시지는 같은 파티션에 저장되어 순서가 유지됩니다.
5. 클러스터 (Cluster)
📌 여러 브로커를 묶어 고가용성과 확장성을 제공하는 Kafka의 논리적 단위
✅ 핵심 특징
- 하나의 Kafka 클러스터는 여러 브로커로 구성
- 노드 추가/제거 가능
- 장애 발생 시 브로커 간 데이터 복제 및 처리 지속 가능
📘 상세 설명
- Kafka 클러스터는 여러 브로커가 네트워크로 연결되어 하나의 단일 서비스처럼 동작합니다.
- 각 브로커는 특정 파티션을 담당하며, 리더/팔로워 역할을 나눠 가집니다.
- 클러스터 구성 시 브로커 수, 파티션 수, 리플리카 수를 적절히 설정하여 성능과 안정성 균형을 맞춥니다.
6. 프로듀서 (Producer)
📌 Kafka에 메시지를 발행하는 클라이언트
✅ 핵심 특징
- 특정 토픽으로 메시지를 전송
- 키에 따라 파티션 자동 선택 가능
- 배치 처리 및 재시도 설정 가능
📘 상세 설명
- 프로듀서는 Kafka 클러스터로 메시지를 보내는 데이터 발신자 역할입니다.
- 메시지를 전송할 때 토픽만 지정하면 Kafka가 자동으로 파티션을 선택하거나 키 기반 분배를 수행합니다.
- acks, retries, batch.size, linger.ms 등의 설정으로 신뢰성과 성능 조절 가능
7. 컨슈머 (Consumer)
📌 Kafka로부터 메시지를 읽는 클라이언트
✅ 핵심 특징
- 지정된 토픽을 구독
- 각 파티션에 대해 오프셋 기반 메시지 읽기
- poll() 호출 주기와 heartbeat 관리 중요
📘 상세 설명
- 컨슈머는 메시지를 가져올 때 poll() 메서드를 주기적으로 호출해야 합니다.
- 메시지 처리가 끝난 지점까지 오프셋을 커밋(commit)하여 다음 소비 위치를 관리합니다.
- 자동 커밋 vs 수동 커밋 설정에 따라 정확성 보장이 달라집니다.
8. 컨슈머 그룹 (Consumer Group)
📌 하나의 메시지를 중복 없이 병렬로 처리하기 위한 단위
✅ 핵심 특징
- 그룹 내에서 파티션을 나눠 처리
- 각 파티션은 하나의 컨슈머만 소비 가능
- 그룹 단위로 오프셋 관리
📘 상세 설명
- 동일한 Group ID를 갖는 컨슈머들은 하나의 컨슈머 그룹으로 묶입니다.
- 파티션 수보다 많은 컨슈머는 유휴 상태가 되며, 적절한 컨슈머 수 조정이 중요합니다.
- 서로 다른 그룹은 동일 메시지를 독립적으로 소비 가능
9. 리밸런싱 (Rebalancing)
📌 컨슈머 그룹 내에서 파티션 소유권을 재조정하는 과정
✅ 발생 조건
- 컨슈머 추가/제거, 장애 발생, 파티션 수 변경 시 자동 발생
📘 상세 설명
- 리밸런싱은 모든 컨슈머가 잠시 메시지 소비를 멈춘 후 파티션을 재할당 받는 과정입니다.
- 짧게는 수 초, 길게는 수십 초까지 메시지 지연이 발생할 수 있습니다.
- 너무 잦은 리밸런싱은 처리 중단, 중복 소비 등 문제를 야기할 수 있으므로 적절한 설정이 필요합니다.
10. 리플리케이션 (Replication)
📌 장애 복구와 가용성을 위한 파티션 복제 구조
✅ 핵심 개념
- 리더(Leader)와 팔로워(Follower) 리플리카로 구성
- In-Sync Replica(ISR)만 새 리더 후보 가능
📘 상세 설명
- Kafka는 각 파티션 데이터를 여러 브로커에 복제하여 내결함성을 확보합니다.
- 리더 리플리카는 모든 읽기/쓰기 요청을 처리하고, 팔로워 리플리카는 이를 따라 복제합니다.
- 리더가 장애나면 ISR 중 하나가 자동 승격되어 데이터 유실 없이 처리를 이어갈 수 있습니다.
✅ Kafka 실전 Q&A
1️⃣ 파티션 수 < 컨슈머 수가 많은 경우, 어떻게 동작하나요?
- Kafka 규칙: 하나의 파티션은 하나의 컨슈머에게만 할당됨
- 파티션보다 컨슈머가 많으면, 남는 컨슈머는 유휴(idle) 상태
- 리소스 낭비 발생 → 컨슈머 수 ≤ 파티션 수가 권장됨
📌 예시: 3개 파티션 + 5개 컨슈머
→ 2개 컨슈머는 할당받지 못하고 대기 상태
2️⃣ 파티션 수 > 컨슈머 수가 적은 경우, 어떻게 동작하나요?
- Kafka는 여러 파티션을 하나의 컨슈머에 할당 가능
- 각 컨슈머는 할당된 파티션을 순차 처리함
- 병렬 처리 성능 확보 가능
📌 예시: 6개 파티션 + 3개 컨슈머
→ 각 컨슈머가 2개씩 파티션을 담당
3️⃣ 파티션 수를 늘리려면 어떻게 하나요?
- 증가만 가능 (감소 불가)
- 기존 메시지는 기존 파티션 유지 → 순서 보장 영향 없음
- 컨슈머 그룹에는 리밸런싱 발생
- 파티션이 지나치게 많으면 메타데이터/GC 오버헤드 주의
4️⃣ 오프셋은 어떻게 관리되나요?
- 각 컨슈머 그룹이 오프셋을 개별적으로 관리
- Kafka 내부 토픽 __consumer_offsets에 저장
- 메시지 재처리를 위해 수동 커밋이 권장됨
📌 커밋 방식:
- enable.auto.commit=true → 자동 커밋 (간편하지만 위험)
- 수동 커밋 → 메시지 처리 완료 시점 명확히 조절 가능
5️⃣ 컨슈머 수를 늘리려면?
- 동일한 Group ID를 가진 컨슈머 인스턴스를 추가
- Kafka가 자동으로 리밸런싱 → 파티션 재할당
- 병렬 처리량 증가 가능
⚠️ 단, 파티션 수보다 많으면 초과 컨슈머는 유휴 상태
→ 토픽 확장 → 컨슈머 확장 순서 권장
6️⃣ 컨슈머 폴링 주기는 어떻게 설정하나요?
- poll() 호출 간격이 max.poll.interval.ms 내에 있어야 함
- 초과 시 → 장애로 간주 → 리밸런싱 발생
📌 주요 설정:
- max.poll.interval.ms: 기본 5분, 메시지 처리시간 고려해 설정
- heartbeat.interval.ms: 기본 3초, 생존 신호 주기
- session.timeout.ms: 기본 30초, 이 시간 내 HeartBeat 없으면 제거
7️⃣ 리밸런싱이 일어나는 상황은?
- 컨슈머 그룹에 새 컨슈머 참여
- 컨슈머가 죽거나 종료됨
- 토픽에 새로운 파티션 추가
- 그룹 코디네이터 변경
💡 이때 파티션 재할당을 위해 전체 컨슈머가 잠깐 정지됨
8️⃣ 리밸런싱 시 발생 가능한 문제는?
- 메시지 처리 중단: 실시간 시스템에 지연 발생
- 중복 처리 가능성: 커밋 전에 리밸런싱 → 같은 메시지 다시 처리
- 과도한 리밸런싱 → 성능 저하 + 리소스 소모
💡 해결 팁:
- 메시지 처리 시간에 맞춰 max.poll.interval.ms 적절히 조정
- 컨슈머는 멱등 처리 고려 (idempotent)
9️⃣ Kafka가 빠른 이유는?
- 순차 쓰기 기반 로그 구조 → 디스크 효율 극대화
- Zero-copy 전송 → 디스크 → 네트워크 직접 전송
- 페이지 캐시 활용 → 메모리 속도에 가까운 읽기
- 불변 메시지 구조 → 락/변경 없음 → 단순, 빠름
- 파티션 기반 병렬 처리 → 수평 확장 가능
- 배치 처리 + 압축 + 간결한 프로토콜
결과: 수백만 건/sec 처리 가능한 초고성능 스트리밍 플랫폼