| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 프로덕션 운영
- RabbitMQ Exchange
- 클라우드
- 마이크로서비스
- Kafka 클러스터
- 분산 시스템
- kubernetes
- 메시징 패턴
- 분산 모니터링
- infrastructureascode
- rabbitmq
- Python
- 이벤트 스트리밍
- devops
- 서비스 설계
- ApacheBench
- docker
- 모노리스 분해
- 보안
- 클러스터
- 마이크로서비스 통신
- 메시지 브로커
- 모니터링
- 서비스 메시
- CI/CD
- 컨테이너오케스트레이션
- 세션저장소
- 마이크로서비스 운영
- 고가용성
- 인메모리데이터베이스
- Today
- Total
hobokai 님의 블로그
Apache Kafka 기초 가이드 - 분산 스트리밍 플랫폼 개념과 설치 본문
Apache Kafka 완벽 가이드 1편: 기초 개념과 설치
목차
Apache Kafka란?
Apache Kafka는 LinkedIn에서 개발한 분산 이벤트 스트리밍 플랫폼입니다. 실시간으로 수백만 개의 메시지를 처리할 수 있는 고성능 메시지 브로커로, 현대적인 데이터 아키텍처의 핵심 구성 요소가 되었습니다.
왜 Kafka를 선택해야 할까요?
고성능과 확장성
- 초당 수백만 개의 메시지 처리 가능
- 수평적 확장을 통한 무제한 처리량 증대
내구성과 신뢰성
- 데이터 복제를 통한 장애 허용성
- 디스크 기반 영구 저장으로 데이터 보존
실시간 처리
- 밀리초 단위의 낮은 지연시간
- 스트림 처리를 통한 실시간 분석
풍부한 생태계
- Kafka Connect, Kafka Streams 등 통합 도구
- 다양한 언어와 프레임워크 지원
주요 사용 사례
📊 실시간 데이터 파이프라인
📝 이벤트 소싱 아키텍처
🔄 마이크로서비스 간 메시징
📈 로그 수집 및 분석
🎯 실시간 추천 시스템
💰 금융 거래 데이터 처리
RabbitMQ vs Kafka 비교
| 특징 | RabbitMQ | Kafka |
|---|---|---|
| 아키텍처 | 메시지 브로커 | 분산 스트리밍 플랫폼 |
| 메시지 모델 | Push 기반 | Pull 기반 |
| 처리량 | 중간 | 매우 높음 |
| 지연시간 | 낮음 | 매우 낮음 |
| 메시지 순서 | 큐 단위 | 파티션 단위 |
| 사용 사례 | 마이크로서비스, RPC | 스트리밍, 로그 집계 |
핵심 아키텍처
주요 구성 요소
1. Broker (브로커)
데이터를 저장하고 서비스하는 Kafka 서버입니다. 클러스터는 여러 브로커로 구성됩니다.
2. Topic (토픽)
메시지가 발행되는 카테고리 또는 피드명입니다. 데이터베이스의 테이블과 유사합니다.
3. Partition (파티션)
토픽 내에서 메시지가 저장되는 순서가 보장되는 불변 시퀀스입니다.
4. Producer (프로듀서)
토픽에 메시지를 발행하는 클라이언트 애플리케이션입니다.
5. Consumer (컨슈머)
토픽을 구독하고 메시지를 처리하는 클라이언트 애플리케이션입니다.
6. Consumer Group (컨슈머 그룹)
동일한 토픽을 소비하는 컨슈머들의 논리적 그룹입니다.
데이터 흐름
Producer → Topic (Partitions) → Consumer Groups → Consumers
상세 과정:
- Producer가 Topic의 특정 Partition에 메시지 작성
- Kafka가 메시지를 디스크에 영구 저장
- Consumer Group의 Consumer들이 메시지를 Pull 방식으로 소비
- 각 Partition은 Consumer Group 내 하나의 Consumer만 할당
- Offset 관리를 통한 메시지 처리 추적
복제와 리더십
- Leader: 특정 파티션의 읽기/쓰기를 담당하는 브로커
- Follower: Leader의 데이터를 복제하는 브로커들
- ISR (In-Sync Replicas): Leader와 동기화된 복제본들
설치 방법
Docker Compose 설치 (권장)
가장 빠르고 간편한 개발 환경 구성 방법입니다.
# docker-compose.yml
version: '3.8'
services:
zookeeper:
image: confluentinc/cp-zookeeper:7.4.0
hostname: zookeeper
container_name: zookeeper
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
volumes:
- zookeeper-data:/var/lib/zookeeper/data
- zookeeper-logs:/var/lib/zookeeper/log
kafka:
image: confluentinc/cp-kafka:7.4.0
hostname: kafka
container_name: kafka
depends_on:
- zookeeper
ports:
- "9092:9092"
- "9997:9997"
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
KAFKA_JMX_PORT: 9997
KAFKA_JMX_HOSTNAME: localhost
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
volumes:
- kafka-data:/var/lib/kafka/data
kafka-ui:
image: provectuslabs/kafka-ui:latest
container_name: kafka-ui
depends_on:
- kafka
ports:
- "8080:8080"
environment:
KAFKA_CLUSTERS_0_NAME: local
KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092
KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper:2181
volumes:
zookeeper-data:
zookeeper-logs:
kafka-data:
# Kafka 클러스터 시작
docker-compose up -d
# 서비스 상태 확인
docker-compose ps
# Kafka UI 접속: http://localhost:8080
Ubuntu 네이티브 설치
# Java 설치 (Kafka 요구사항)
sudo apt update
sudo apt install default-jdk
# Java 버전 확인
java -version
# Kafka 다운로드
wget https://downloads.apache.org/kafka/2.13-3.5.0/kafka_2.13-3.5.0.tgz
tar -xzf kafka_2.13-3.5.0.tgz
cd kafka_2.13-3.5.0
# ZooKeeper 시작 (첫 번째 터미널)
bin/zookeeper-server-start.sh config/zookeeper.properties
# Kafka 서버 시작 (두 번째 터미널)
bin/kafka-server-start.sh config/server.properties
KRaft 모드 (ZooKeeper 없는 Kafka)
최신 Kafka는 ZooKeeper 없이도 동작할 수 있습니다.
# 클러스터 ID 생성
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
# 스토리지 포맷
bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties
# KRaft 모드로 Kafka 시작
bin/kafka-server-start.sh config/kraft/server.properties
기본 개념 이해
토픽과 파티션
토픽 생성
# 토픽 생성
kafka-topics.sh --create \
--topic user-events \
--bootstrap-server localhost:9092 \
--partitions 3 \
--replication-factor 1
# 토픽 목록 확인
kafka-topics.sh --list --bootstrap-server localhost:9092
# 토픽 상세 정보
kafka-topics.sh --describe \
--topic user-events \
--bootstrap-server localhost:9092
파티션 전략
- 더 많은 파티션 = 더 높은 병렬성
- 파티션 수는 늘릴 수만 있음 (줄일 수 없음)
- 키 기반 파티셔닝으로 순서 보장
오프셋과 컨슈머 그룹
오프셋 (Offset)
- 파티션 내에서 각 메시지의 고유 식별자
- 순차적으로 증가하는 숫자
- 컨슈머의 읽기 위치 추적
컨슈머 그룹
# 컨슈머 그룹 목록
kafka-consumer-groups.sh --list --bootstrap-server localhost:9092
# 컨슈머 그룹 상세 정보
kafka-consumer-groups.sh --describe \
--group my-group \
--bootstrap-server localhost:9092
# 오프셋 리셋
kafka-consumer-groups.sh --reset-offsets \
--group my-group \
--topic user-events \
--to-earliest \
--bootstrap-server localhost:9092 \
--execute
메시지 전달 보장
1. At most once (최대 한 번)
- 메시지 손실 가능, 중복 없음
acks=0설정
2. At least once (최소 한 번)
- 메시지 중복 가능, 손실 없음
acks=1설정
3. Exactly once (정확히 한 번)
- 메시지 손실과 중복 모두 방지
acks=all,enable.idempotence=true설정
첫 번째 메시지 전송
Python으로 Producer/Consumer 구현
producer.py
from kafka import KafkaProducer
import json
import time
# Producer 설정
producer = KafkaProducer(
bootstrap_servers=['localhost:9092'],
value_serializer=lambda v: json.dumps(v, ensure_ascii=False).encode('utf-8'),
key_serializer=lambda k: k.encode('utf-8') if k else None
)
def send_user_event(user_id, action):
event = {
'user_id': user_id,
'action': action,
'timestamp': int(time.time() * 1000),
'message': f'사용자 {user_id}가 {action} 액션을 수행했습니다'
}
# 메시지 전송
future = producer.send(
'user-events', # 토픽명
key=user_id, # 파티션 키
value=event # 메시지 내용
)
# 전송 결과 확인
try:
record_metadata = future.get(timeout=10)
print(f"✓ 메시지 전송 성공:")
print(f" 토픽: {record_metadata.topic}")
print(f" 파티션: {record_metadata.partition}")
print(f" 오프셋: {record_metadata.offset}")
print(f" 사용자: {user_id}, 액션: {action}")
print("-" * 40)
except Exception as e:
print(f"✗ 메시지 전송 실패: {e}")
# 테스트 메시지 전송
if __name__ == "__main__":
print("📤 Kafka Producer 시작")
# 여러 사용자 이벤트 전송
events = [
('user001', '로그인'),
('user002', '상품조회'),
('user001', '장바구니추가'),
('user003', '로그인'),
('user002', '주문완료'),
('user001', '로그아웃')
]
for user_id, action in events:
send_user_event(user_id, action)
time.sleep(1) # 1초 간격
producer.close()
print("📤 Producer 종료")
consumer.py
from kafka import KafkaConsumer
import json
# Consumer 설정
consumer = KafkaConsumer(
'user-events', # 구독할 토픽
bootstrap_servers=['localhost:9092'],
group_id='user-events-processor', # 컨슈머 그룹
value_deserializer=lambda m: json.loads(m.decode('utf-8')),
key_deserializer=lambda k: k.decode('utf-8') if k else None,
auto_offset_reset='earliest', # 처음부터 읽기
enable_auto_commit=True, # 자동 오프셋 커밋
auto_commit_interval_ms=1000 # 커밋 간격
)
def process_user_event(event, metadata):
"""사용자 이벤트 처리 로직"""
user_id = event['user_id']
action = event['action']
timestamp = event['timestamp']
print(f"📥 이벤트 수신:")
print(f" 파티션: {metadata.partition}")
print(f" 오프셋: {metadata.offset}")
print(f" 키: {metadata.key}")
print(f" 사용자: {user_id}")
print(f" 액션: {action}")
print(f" 시간: {timestamp}")
# 비즈니스 로직 수행
if action == '로그인':
print(" → 로그인 통계 업데이트")
elif action == '주문완료':
print(" → 주문 확인 이메일 발송")
elif action == '장바구니추가':
print(" → 추천 상품 업데이트")
print("-" * 40)
# 메시지 소비 시작
if __name__ == "__main__":
print("📥 Kafka Consumer 시작")
print("💡 메시지를 기다리는 중... (Ctrl+C로 종료)")
try:
for message in consumer:
process_user_event(message.value, message)
except KeyboardInterrupt:
print("\n📥 Consumer 종료")
finally:
consumer.close()
실행 및 테스트
# 1단계: 토픽 생성 (Docker 환경에서)
docker exec -it kafka kafka-topics \
--create --topic user-events \
--bootstrap-server localhost:9092 \
--partitions 3 --replication-factor 1
# 2단계: Consumer 실행 (첫 번째 터미널)
python consumer.py
# 3단계: Producer 실행 (두 번째 터미널)
python producer.py
실행 결과 예시
Producer 출력:
📤 Kafka Producer 시작
✓ 메시지 전송 성공:
토픽: user-events
파티션: 0
오프셋: 0
사용자: user001, 액션: 로그인
----------------------------------------
Consumer 출력:
📥 Kafka Consumer 시작
💡 메시지를 기다리는 중... (Ctrl+C로 종료)
📥 이벤트 수신:
파티션: 0
오프셋: 0
키: user001
사용자: user001
액션: 로그인
시간: 1703845200000
→ 로그인 통계 업데이트
----------------------------------------
Kafka UI로 확인
웹 브라우저에서 http://localhost:8080에 접속하면:
- Topics 탭: 생성된 토픽과 파티션 정보
- Messages 탭: 실제 메시지 내용 확인
- Consumers 탭: 컨슈머 그룹과 지연(lag) 상태
- Brokers 탭: 브로커 상태와 성능 지표
다음 편 미리보기
2편: Producer/Consumer 고급 기능과 Kafka Streams에서는:
🔧 Producer 고급 설정
- 파티셔닝 전략과 커스텀 파티셔너
- 배치 처리와 압축 최적화
- 오류 처리와 재시도 로직
📊 Consumer 고급 패턴
- 수동 오프셋 관리
- 다중 스레드 소비 패턴
- 컨슈머 리밸런싱 제어
🌊 Kafka Streams 입문
- 실시간 스트림 처리
- 상태 저장 연산 (집계, 조인)
- 윈도우 기반 분석
💻 실전 프로젝트
- 실시간 사용자 활동 분석 시스템
- 주문 처리 파이프라인
- 로그 수집 및 모니터링
Kafka의 기본기를 탄탄히 다졌다면, 이제 실제 프로덕션 환경에서 활용할 수 있는 고급 기능들을 살펴볼 차례입니다. 2편에서는 더욱 실용적이고 성능 최적화된 Kafka 활용법을 다루겠습니다.
'Data Platform' 카테고리의 다른 글
| RabbitMQ 완벽 가이드 3편: 프로덕션 운영과 고급 기능 (3) | 2025.07.23 |
|---|---|
| RabbitMQ 완벽 가이드 2편: Exchange와 라우팅 패턴 (0) | 2025.07.23 |
| RabbitMQ 완벽 가이드 1편: 기초 개념과 설치 (0) | 2025.07.23 |
| Kafka 프로덕션 가이드 - 클러스터링, 모니터링, 보안, 운영 자동화 (1) | 2025.07.23 |
| Kafka Producer/Consumer 고급 가이드 - 파티셔닝, 스트림 처리, 성능 최적화 (3) | 2025.07.23 |