Apache Kafka 공부 기록 (Part 1)
Table of Contents
Kafka Theory
- Topics, Partitions, and Offsets
- Producers and Message Keys
- Consumers & Deserialization
- Consumer Groups & Consumer Offsets
- Brokers and Topics
- Topic Replication
- Producer Acknowledgements & Topic Durability
- Zookeeper
- Kafka KRaft - Removing Zookeeper
- Theory Roundup
Starting Kafka
- Kafka 설치
- Kafka 설치 확인
- Zookeeper 실행
- Kafka 실행
Kafka CLI
- Intro to CLI
- Kafka Topics CLI
- Kafka Console Producer CLI
- Kafka Console Consumer CLI
- Kafka Console Consumer Groups CLI
- Kafka Offset 초기화 CLI
Kafka Theory
[Topics, Partitions, and Offsets]
1. Topics
- Kafka에서 Topic은 특정한 데이터 스트림을 의미함
- DB 테이블과 유사하지만, Topic은 제약 조건이 없음
- 원하는 만큼 Topic들을 만들 수 있음
- Topic은 이름을 기준으로 식별됨
- 다양한 형식의 Message를 저장할 수 있음
- Message의 순서가 유지되는 데이터 스트림을 지님
- Query를 지원하지 않으며, Kafka Producer와 Consumer를 통해 데이터를 송수신함
2. Partitions
- Topic은 여러 개의 Partition으로 나뉘며, 각 Partition 내부에서는 메시지의 순서가 보장됨
- 메시지는 Offset이라는 고유한 ID를 가짐
- Kafka의 데이터는 Immutable하며, 한 번 기록된 데이터는 수정 불가능
- 데이터는 일정 기간 동안 유지되며(기본 1주일, 설정 가능), 이후 자동 삭제됨
- Partition 내에서는 순서가 보장되지만, 여러 Partition을 사용할 경우 전역적인 순서 보장은 불가능
- Key를 지정하지 않으면 데이터는 랜덤한 Partition에 저장됨
[Producers and Message Keys]
1. Producers
- Producer는 Kafka에 데이터를 전송하는 역할을 함
- Producer는 특정 Partition에 데이터를 저장하는 방법을 알고 있음
- Kafka Broker에 장애가 발생하면 자동으로 복구 가능
2. Message Keys
- Producer는 메시지에 Key를 지정할 수 있음
- Key가 NULL이면, 메시지는 Roundrobin 방식으로 랜덤한 Partition에 저장됨
- Key가 있으면, 해당 Key의 모든 메시지는 같은 Partition에 저장됨 (with Hashing Algorithm)
- 특정 Key에 대해 순서 보장이 필요한 경우 Key를 설정하는 것이 중요함
3. Kafka Messages Serializer
- Kafka는 byte 단위로 데이터를 저장하며, 따라서 데이터를 byte로 변환하는 과정이 필요함
- Common Serializers: String (JSON 포함), Int, Float, Avro, Protobuf
[Consumers & Deserialization]
1. Consumers
- Consumer는 Kafka에서 데이터를 읽어오는 역할을 함
- Topic 이름을 기준으로 데이터를 읽음 (Pull 방식)
- Broker 장애 발생 시 자동으로 복구 가능
- Partition 내에서는 Offset 순서대로 데이터를 읽음
2. Deserialization
- Consumer는 byte 데이터를 다시 원래 객체로 변환해야 함
- Producer에서 사용한 Serialization 방식과 동일한 방식으로 Deserialization 필요
- Serialization/Deserialization 방식은 Topic 생성 이후 변경 불가능
[Consumer Groups & Consumer Offsets]
1. Consumer Groups
- 여러 개의 Consumers가 하나의 Consumer Group을 이루며, Group 내에서 각 Consumer는 서로 다른 Partition을 읽음
- Consumer의 개수가 Partition 수보다 많아지면 일부 Consumer는 비활성화됨
- Consumer Group ID를 다르게 설정하면, 동일한 Topic에서도 여러 개의 Consumer Group을 운영 가능
2. Consumer Offsets
- Kafka는 Consumer가 어디까지 데이터를 읽었는지 Offset을 저장함
__consumer_offset
: Topic에 Offset을 저장함- Consumer가 종료되더라도 Offset을 기반으로 이어서 읽을 수 있음
3. 전송 보장 방식
- At Least Once (최소 1회 전달, 기본값): 데이터가 중복될 수 있음 (중복 처리를 위한 Idempotent 설계 필요)
- At Most Once (최대 1회 전달): 일부 메시지가 손실될 수 있음
- Exactly Once (정확히 1회 전달): Kafka 내부에서는 가능하지만, 외부 시스템과 연동할 때는 추가적인 설정 필요
[Brokers and Topics]
1. Kafka Brokers
- Kafka Cluster는 여러 개의 Brokers(서버)로 구성됨
- 각 Broker는 고유한 ID를 가짐
- 특정 Broker에 연결하면 전체 Cluster와 통신 가능
- 기본적으로 3개의 Brokers를 추천하지만, 대큐모 Cluster에서는 100개 이상의 Brokers를 운영할 수도 있음
2. Topic과 Broker의 관계
- 하나의 Topic은 여러 개의 Partition을 가짐
- Partition은 여러 Broker에 분산 저장됨
- Kafka Client는 Bootstrap 서버 1개에만 연결해도 Cluster 전체 정보를 얻을 수 있음
[Topic Replication]
1. Replication Factor
- Kafka에서는 데이터를 안전하게 저장하기 위해 Replication Factor를 설정함
- 일반적으로 2–3개의 복제본을 설정
- Broker 장애 발생 시에도 데이터가 손실되지 않도록 보장함
- Leader Partition과 Follower Partition이 존재하며, Leader가 데이터를 관리함
[Producer Acknowledgements & Topic Durability]
1. Producer Acks 설정
- Producer는 메시지가 정상적으로 저장되었는지 확인할 수 있음
acks=0
: 확인 없이 전송 (데이터 손실 가능성 높음)acks=1
: Leader Broker의 확인만 받음 (일부 데이터 손실 가능성 있음)acks=all
: 모든 복제본에서 확인을 받음 (가장 안전하지만 속도 저하 가능)
[Zookeeper]
- Kafka는 Metadata 관리 및 Cluster 상태를 유지하기 위해 Zookeeper를 사용함
- (1) Broker 리스트 관리
- (2) Partition의 Leader 선출
- (3) 새로운 Topic 생성, 삭제 등의 이벤트 감지
Kafka 3.x
이상에서는 Zookeeper 없이 운영 가능 (KRaft 도입)
[Kafka KRaft — Removing Zookeeper]
Kafka 3.x
부터는 Zookeeper 없이 자체적으로 Metadata를 관리하는 KRaft (Kafka Raft)를 도입함- Zookeeper를 제거하면 성능과 확장성이 향상됨
- 10만 개 이상의 Partition을 운영하는 경우 Zookeeper 성능 병목이 될 수 있음
Kafka 4.x
에서는 완전히 Zookeeper가 제거될 예정
[Theory Roundup]
Starting Kafka
[Kafka 설치]
- 설치 가이드: How to install Apache Kafka on Mac with Homebrew (Java JDK로 함께 설치됨)
brew install kafka
- Kafka 설치 경로:
/opt/homebrew/Cellar/kafka
- Binaries & Scripts:
/opt/homebrew/bin
- Kafka Configurations:
/opt/homebrew/etc/kafka
- Zookeeper Configurations:
/opt/homebrew/etc/zookeeper
- The
log.dirs
config (the location for Kafka data) will be set toopt/homebrew/var/lib/kafka-logs
[Kafka 설치 확인]
kafka-topics
[Zookeeper 실행]
/opt/homebrew/bin/zookeeper-server-start /opt/homebrew/etc/zookeeper/zoo.cfg
- Kafka는 Cluster 관리를 Zookeeper에 의존함. 따라서 Kafka 실행 전 Zookeeper가 먼저 실행되어야 함
[Kafka 실행]
/opt/homebrew/bin/kafka-server-start /opt/homebrew/etc/kafka/server.properties
Kafka CLI
[Intro to CLI]
- Kafka CLI 명령어는 Kafka Binaries에 포함되어 제공됨
kafka-topics \
--bootstrap-server localhost:9092
[Kafka Topics CLI]
1. Kafka Topic 생성
- 현재 존재하는 Topic 확인
kafka-topics \
--bootstrap-server localhost:9092 \
--list
first_topic
생성
kafka-topics \
--bootstrap-server localhost:9092 \
--topic first_topic \
--create
second_topic
생성 (파티션 3개 설정)
kafka-topics \
--bootstrap-server localhost:9092 \
--topic second_topic \
--create \
--partition 3
third_topic
생성 (파티션 3개, 복제 1개로 설정)
kafka-topics \
--bootstrap-server localhost:9092 \
--topic third_topic \
--create \
--partition 3 \
--replication-factor 1
2. Kafka Topic 목록 확인
kafka-topics \
--bootstrap-server localhost:9092 \
--topic second_topic \
--list
3. Kafka Topic 상세 정보 확인
kafka-topics \
--bootstrap-server localhost:9092 \
--topic first_topic \
--describe
4. Kafka Topic 삭제
delete.topic.enable=true
설정이 되어 있어야 동작함
kafka-topics \
--bootstrap-server localhost:9092 \
--topic first_topic \
--delete
[Kafka Console Producer CLI]
1. first_topic
생성
kafka-topics \
--bootstrap-server localhost:9092 \
--topic first_topic \
--create \
--partitions 1
2. 메시지 전송
kafka-console-producer \
--bootstrap-server localhost:9092 \
--topic first_topic
> Hello World!
> My name is Joshua
> I root for Liverpool FC
3. 메시지 수신 확인
kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic first_topic \
--from-beginning
4. Key를 사용한 메시지 전송
kafka-console-producer \
--bootstrap-server localhost:9092 \
--topic first_topic \
--property parse.key=true \
--property key.separator=:
> name:Joshua
> country:South Korea
> club:Liverpool
5. Key 포함 메시지 수신 확인
kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic first_topic \
--from-beginning
[Kafka Console Consumer CLI]
1. second_topic
생성 (파티션 3개 설정)
kafka-topics \
--bootstrap-server localhost:9092 \
--topic second_topic \
--create \
--partitions 3
2. 메시지 수신 확인
kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic second_topic
3. 메시지 전송 (Roundrobin Partitioner 사용)
kafka-console-producer \
--bootstrap-server localhost:9092 \
--producer-property partitioner.class=org.apache.kafka.clients.producer.RoundRobinPartitioner \
--topic second_topic
4. 메시지의 Key, Value, Timestamp 포함하여 출력
kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic second_topic \
--formatter kafka.tools.DefaultyMessageFormatter \
--property print.timestamp=true \
--property print.key=true \
--property print.value=true \
--property print.partition=true \
--from-beginning
[Kafka Console Consumer Groups CLI]
1. Consumer Group 목록 조회
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--list
2. 특정 Consumer Group 상세 정보 확인
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--describe \
--group joshua-app
3. Consumer Group 내 Lag 확인 후 Consume 계속
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--topic third_topic \
--group joshua-app \
--from-beginning
[Kafka Offset 초기화 CLI]
1. 특정 Consumer Group 상세 정보 확인
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--describe \
--group joshua-app
2. Offset 초기화 (Dry Run)
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--group joshua-app \
--reset-offsets \
--to-earliest \
--topic third_topic \
--dry-run
3. Offset 초기화 (Execute)
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--group joshua-app \
--reset-offsets \
--to-earliest \
--topic third_topic \
--execute
4. Offset 초기화 후 Consume 계속
kafka-console-consumer \
--bootstrap-server localhost:9092 \
--topic third_topic \
--group joshua-app
5. 최종 Offset 정보 확인
kafka-consumer-groups \
--bootstrap-server localhost:9092 \
--describe \
--group joshua-app