Apache Kafka 빠른 시작 - CLI로 Kafka 4.2 설치 및 로컬 예제 실행

Kafka 4.2를 설치하고 몇 분 만에 이벤트를 스트리밍하세요.

Page content

Apache Kafka 4.2.0가 현재 지원되는 릴리스 라인이며, Kafka 4.x는 기본적으로 완전히 ZooKeeper를 필요로 하지 않고 KRaft를 기반으로 구축되어 있어 현대적인 빠른 시작(Quickstart)에 가장 적합한 기준점입니다.

이 가이드는 실용적이고 명령줄 중심의 빠른 시작 가이드입니다. Kafka 설치, 로컬 브로커 시작, 필수 Kafka CLI 도구 학습, 그리고 터미널에 바로 붙여넣을 수 있는 두 가지 종단 간(end-to-end) 예제로 마무리합니다.

distributed message processing infographic apache kafka

Apache Kafka란 무엇이며 어디에 사용됩니까

Apache Kafka는 **이벤트 스트리밍 플랫폼(event streaming platform)**입니다. 실용적인 관점에서 이벤트 스트리밍이란 소스(데이터베이스, 센서, 애플리케이션)에서 실시간으로 이벤트 데이터를 캡처하고, 생성된 스트림을 내구성 있게 저장하며, 실시간(또는 나중에)으로 처리하거나 라우팅하는 것을 의미합니다.

Kafka는 하나의 플랫폼에 세 가지 핵심 기능을 제공합니다. 이벤트 스트림에 대한 발행 및 구독(publish and subscribe), 필요에 따라 스트림의 내구성 있는 저장(store), 그리고 발생 시점 또는 사후적으로 스트림 **처리(process)**입니다. 이러한 조합 때문에 Kafka는 실시간 데이터 파이프라인, 통합, 메시징, 스트리밍 분석에 사용됩니다.

Kafka가 더 넓은 데이터 인프라에서 어떤 위치에 있는지 문맥을 이해하려면 S3 호환 객체 저장소, PostgreSQL 아키텍처, Elasticsearch 최적화, AI 네이티브 데이터 레이어를 다루는 AI 시스템용 데이터 인프라: 객체 저장소, 데이터베이스, 검색 및 AI 데이터 아키텍처 pillar를 참조하십시오.

AWS에서 구축 중이며 관리형 대안이 필요한 경우, Kinesis Data Streams를 사용하여 이벤트 중심 마이크로서비스를 구현하는 방법을 다루는 AWS Kinesis를 사용한 이벤트 중심 마이크로서비스 구축을 참조하십시오.

Kafka를 사용한 상태ful 스트림 처리에 대해서는 Apache Flink on K8s and Kafka: PyFlink, Go, ops, and managed pricing을 참조하십시오.

Kafka로 발행하기 전에 데이터베이스에 쓰는 서비스에 대해서는 트랜잭션 아웃박스 패턴이 데이터베이스 커밋과 Kafka produce 호출 사이에서 이벤트가 손실되지 않도록 보장합니다.

운영 측면에서 Kafka는 고성능 TCP 프로토콜을 통해 통신하는 서버 및 클라이언트의 분산 시스템입니다. 브로커는 데이터를 저장하고 제공하며, 클라이언트(프로듀서 및 컨슈머)는 대규모로 그리고 고장 허용 방식으로 이벤트를 읽고 씁니다.

CLI에서 반복적으로 보게 될 몇 가지 개념:

  • **토픽(Topics)**은 이벤트를 조직합니다. 토픽은 다중 프로듀서 및 다중 구독자이며, 보존(retention) 컨트롤이 오래된 데이터를 언제 버릴지 결정하므로 이벤트를 여러 번 읽을 수 있습니다.
  • **파티션(Partitions)**은 확장성을 위해 브로커 간에 토픽을 샤딩하며, 파티션별 순서가 보장됩니다.
  • **복제 팩터(Replication factor)**는 고장 허용을 제어합니다. 문서 예시에서는 프로덕션 환경에서 일반적으로 복제 팩터 2 또는 3을 권장합니다(단일 노드 개발용 빠른 시작에서는 일반적으로 1을 사용함).

Apache Kafka 설치

Kafka의 공식 빠른 시작은 바이너리 릴리스(tarball) 또는 공식 Docker 이미지를 사용합니다. 둘 다 로컬 개발에 적합합니다.

생략하면 안 되는 사전 요구 사항

Kafka 4.x는 최신 Java가 필요합니다. 서버 및 도구의 경우 **Java 17+**가 로컬 실행의 기준이며, Kafka 4.0은 Java 8 지원을 제거했습니다.

Kafka를 학습하기 위해 설치하는 경우 Java 17 또는 21과 같은 지원되는 JDK를 목표로 하십시오. Kafka의 Java 지원 페이지에서 Java 17, 21, 25를 완전히 지원한다고 명시하고 있으며, Java 11은 일부 모듈(클라이언트 및 스트림)에서만 지원됩니다.

공식 바이너리 릴리스에서 설치

Kafka 4.2.0의 공식 빠른 시작은 바이너리 배포판을 다운로드하고 추출하는 것으로 시작합니다:

tar -xzf kafka_2.13-4.2.0.tgz
cd kafka_2.13-4.2.0

고급 독자를 위한 참고 사항:

  • 파일명의 “2.13"은 Scala 빌드 라인을 반영합니다. Kafka 4.x 바이너리의 경우 Scala 2.13이 주요 배포 라인이며, Kafka 4.0은 Scala 2.12 지원을 제거했습니다.
  • 공급망 무결성에 관심이 있다면, 다운로드 페이지에서 Apache의 게시된 절차 및 KEYS를 사용하여 다운로드를 검증할 수 있다고 명시적으로 문서화되어 있습니다.

Docker로 설치

Kafka는 Docker Hub에서 공식 Docker 이미지를 제공합니다. 빠른 시작에서는 다음과 같이 Kafka 4.2.0을 풀(pull)하고 실행할 수 있음을 보여줍니다:

docker pull apache/kafka:4.2.0
docker run -p 9092:9092 apache/kafka:4.2.0

또한 “네이티브” 이미지 라인(GraalVM 네이티브 이미지 기반)도 있습니다. Kafka 문서 및 이 이미지 라인에 대한 Kafka 개선 제안서(KIP)는 이를 **실험적(experimental)**으로 간주하며 로컬 개발 및 테스트용으로 의도되어 있고 프로덕션용이 아님을 설명합니다.

Windows 사용자를 위한 플랫폼 참고 사항

Kafka 배포판에는 Windows 스크립트(배치 파일)가 포함되어 있습니다. Kafka 문서에서는 역사적으로 Windows에서는 Unix bin/ .sh 스크립트 대신 bin\windows\.bat 스크립트를 사용한다고 명시했습니다.

KRaft로 로컬에서 Kafka 시작

“Apache Kafka를 실행하려면 ZooKeeper가 필요한가요?“라고 질문하신다면, 현대적인 답변은 아니오입니다. Kafka 4.0은 완전히 ZooKeeper 없이 운영되도록 설계된 최초의 주요 릴리스이며, 로컬 및 프로덕션 사용의 운영 오버헤드를 줄이는 KRaft 모드로 기본적으로 실행됩니다.

추출된 tarball에서 단일 노드 로컬 브로커 시작

Kafka 4.2 빠른 시작은 세 가지 명령을 사용합니다:

  1. 클러스터 UUID 생성
  2. 로그 디렉토리 포맷
  3. 서버 시작
# Generate a Cluster UUID
KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"

# Format Log Directories (standalone local format)
bin/kafka-storage.sh format --standalone -t "$KAFKA_CLUSTER_ID" -c config/server.properties

# Start the Kafka broker
bin/kafka-server-start.sh config/server.properties

KRaft에서 “포맷” 단계가 중요한 이유: Kafka의 KRaft 운영 문서는 kafka-storage.sh random-uuid가 클러스터 ID를 생성하고 각 서버가 kafka-storage.sh format로 포맷되어야 한다고 설명합니다. 제시된 논리 중 하나는 자동 포맷팅이 오류를 숨길 수 있으며, 특히 메타데이터 로그 주변에서 문제가 발생할 수 있으므로 명시적 포맷팅이 선호된다는 것입니다.

이 빠른 시작에서 실행 중인 내용

로컬 개발을 위해 Kafka는 단순화된 “결합형(combined)” 설정(컨트롤러와 브로커가 함께)으로 실행할 수 있습니다. Kafka의 KRaft 문서는 결합형 서버를 개발에는 더 간단하지만, 컨트롤러가 독립적으로 격리되고 확장되어야 하는 중요한 배포 환경에는 권장되지 않는다고 명시합니다.

“실제” 클러스터의 경우, KRaft 컨트롤러와 브로커는 별도의 역할(process.roles)이며, 컨트롤러는 일반적으로 3 또는 5개의 노드 쿼럼(quorum)으로 배포됩니다(가용성은 다수가 살아있어야 함에 따라 달라짐).

Kafka CLI 필수 사항 및 주요 명령줄 매개변수

Kafka는 bin/ 아래에 많은 CLI 도구를 제공합니다. 공식 운영 문서에서는 두 가지 유용한 속성을 강조합니다:

  • 공통 도구는 배포판의 bin/ 디렉토리에 있습니다.
  • 각 도구는 인자 없이 실행하면 전체 명령줄 사용법을 출력합니다.

Kafka 4.x에서 또한 중요합니다: AdminClient 명령은 더 이상 --zookeeper를 수락하지 않습니다. Kafka의 호환성 문서는 Kafka 4.0부터 클러스터와 상호 작용하려면 --bootstrap-server를 사용해야 한다고 명시합니다.

지속적으로 사용할 Kafka 연결 플래그

대부분의 도구에는 클러스터 진입점이 필요합니다:

  • --bootstrap-server host:port
    토픽 작업, 컨슈머 그룹, 그리고 대부분의 브로커 대상 명령에 사용하십시오. 이는 Kafka 4.x에서 ZooKeeper 기반 관리 워크플로우의 정표(canonical) 대체 수단입니다.

KRaft는 일부 도구에서 브로커와 컨트롤러 엔드포인트를 도입합니다. 예를 들어, kafka-features.sh 및 메타데이터 도구 일부는 컨트롤러 엔드포인트를 사용할 수 있는 반면, 많은 관리 작업은 브로커 엔드포인트를 사용합니다. KRaft 운영 페이지에는 두 가지 스타일이 모두 예시로 표시됩니다.

kafka-topics.sh를 사용한 토픽 관리

핵심 라이프사이클을 위해 kafka-topics.sh를 사용하게 됩니다:

  • 토픽 생성, 설명, 목록 조회 (빠른 시작에서는 --create, --describe, --topic를 보여줍니다).
  • 파티션 및 복제 팩터를 통해 규모와 내구성 지정. 운영 가이드는 --partitions--replication-factor를 보여주며 이들이 확장성과 고장 허용에 어떻게 영향을 미치는지 설명합니다.
  • 생성 시 --config key=value로 토픽별 오버라이드 추가 (토픽 구성 문서에 구체적인 예시 있음).

“프로덕션 중심"의 생성 명령은 다음과 같이 생겼습니다(이 정확한 형태는 공식 운영 문서에서 사용됩니다):

bin/kafka-topics.sh --bootstrap-server localhost:9092 \
  --create --topic my_topic_name \
  --partitions 20 --replication-factor 3 \
  --config x=y

콘솔 클라이언트를 사용한 프로듀싱 및 컨슈밍

빠른 시작은 검증 및 스모크 테스트에 빠르기 때문에 콘솔 프로듀서와 컨슈머를 사용합니다:

  • kafka-console-producer.sh --topic ... --bootstrap-server ...
  • kafka-console-consumer.sh --topic ... --from-beginning --bootstrap-server ...

Kafka 4.2에는 CLI 일관성 개선도 포함되어 있습니다. 업그레이드 노트에서:

  • kafka-console-producer--max-partition-memory-bytes를 비추적(deprecate)하고 대신 --batch-size를 권장합니다.
  • kafka-console-consumer는 포맷터 속성에 대해 --property를 비추적하고 대신 --formatter-property를 사용합니다.
  • kafka-console-producer는 메시지 리더 속성에 대해 --property를 비추적하고 대신 --reader-property를 사용합니다.

내부 실행부(runbooks)를 유지 관리 중이라면, Kafka 5.0이 비추적 플래그를 제거하기 전에 지금 이 노트를 업데이트하는 것이 좋습니다.

kafka-consumer-groups.sh를 사용한 컨슈머 지연(Lag) 검사

실제 시스템에서 “내 컨슈머가 따라가고 있는가?“는 일상적인 질문입니다. 운영 가이드는 다음을 시연합니다:

  • 그룹 목록: --list
  • 오프셋 및 지연과 함께 그룹 설명: --describe --group ...
  • 멤버 및 할당 설명: --members--verbose
  • 그룹 삭제: --delete
  • 오프셋 안전하게 리셋: --reset-offsets

예시:

bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group my-group

로컬 Docker 및 원격 클라이언트를 위한 한 가지 구성 주의 사항

컨테이너에서 Kafka를 실행하거나 로드 밸런서 뒤에 배치하면 결국 리스너를 올바르게 설정해야 할 필요가 발생합니다. Kafka의 브로커 구성 문서에서는 클라이언트가 사용해야 하는 주소와 바인딩 주소가 다를 때, 특히 브로커가 클라이언트 및 기타 브로커에 광고하는 주소로 advertised.listeners를 설명합니다.

지금 실행할 수 있는 빠른 시작 예시

아래 예시는 의도적으로 CLI 기반으로 되어 있어 애플리케이션 코드를 작성하기 전에 로컬 Kafka 설정을 검증할 수 있습니다.

예시: 토픽 실행 및 메시지 종단 간 스트리밍

이는 Kafka 4.2 빠른 시작의 정표적인 “생성, 프로듀스, 컨슈م” 흐름입니다.

터미널 A를 열고 토픽을 생성합니다:

bin/kafka-topics.sh --create --topic quickstart-events --bootstrap-server localhost:9092

이제 설명합니다(선택 사항이지만 파티션과 복제 팩터를 학습할 때 유용함):

bin/kafka-topics.sh --describe --topic quickstart-events --bootstrap-server localhost:9092

터미널 B를 열고 프로듀서를 시작합니다:

bin/kafka-console-producer.sh --topic quickstart-events --bootstrap-server localhost:9092

몇 줄을 입력합니다(각 줄이 이벤트가 됨), 그리고 프로듀서를 실행 상태로 둡니다:

This is my first event
This is my second event

터미널 C를 열고 처음부터 컨슈머를 시작합니다:

bin/kafka-console-consumer.sh --topic quickstart-events --from-beginning --bootstrap-server localhost:9092

동일한 줄이 출력되는 것을 볼 수 있습니다.

이것이 “동작한다"보다 더 많은 것을 검증하는 이유: Kafka의 빠른 시작은 브로커가 이벤트를 내구성 있게 저장하고, 이벤트를 여러 번 읽을 수 있으며 여러 컨슈머가 읽을 수 있다고 설명합니다. 이 내구성 때문에 이 빠른 시작 패턴은 설치 또는 업그레이드 후 가장 먼저 수행해야 할 것입니다.

예시: 파일에서 토픽으로, 파일로의 간단한 Kafka Connect 파이프라인 실행

Kafka Connect는 “모든 것에 대해 커스텀 프로듀서와 컨슈머를 작성하지 않고 어떻게 데이터를 Kafka로 이동하고 외부로 내보낼 수 있는가?“라는 반복되는 질문에 답합니다. Kafka Connect 개요는 이를 커넥터를 통해 Kafka와 다른 시스템 간의 확장 가능하고 신뢰할 수 있는 스트리밍을 위한 도구로 설명합니다.

Kafka 4.2 빠른 시작에는 파일 소스 및 싱크 커넥터를 사용한 최소한의 로컬 Connect 데모가 포함되어 있습니다.

Kafka 디렉토리에서 먼저 작업자 플러그인 경로를 제공된 파일 커넥터 jar를 포함하도록 설정합니다:

echo "plugin.path=libs/connect-file-4.2.0.jar" >> config/connect-standalone.properties

작은 입력 파일을 생성합니다:

echo -e "foo\nbar" > test.txt

소스 및 싱크 커넥터 구성 모두와 함께 스탠드alone 모드로 Connect 작업자를 시작합니다:

bin/connect-standalone.sh \
  config/connect-standalone.properties \
  config/connect-file-source.properties \
  config/connect-file-sink.properties

무엇이 일어나야 하는지 (그리고 왜 유용한지):

  • 소스 커넥터는 test.txt에서 줄을 읽고 connect-test 토픽으로 프로듀스합니다.
  • 싱크 커넥터는 connect-test에서 읽고 test.sink.txt로 씁니다.

싱크 파일을 검증합니다:

more test.sink.txt

다음과 같이 보일 것입니다:

foo
bar

토픽을 직접 검증할 수도 있습니다:

bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning

이 두 번째 예시는 Connect 구성이 어디에 있는지(작업자 구성 및 커넥터 구성)를 알려주고 최소한의 “수집, 저장, 내보내기” 루프를 보여주기 때문에 훌륭한 근육 기억(muscle-memory) 빌더입니다.

문제 해결 및 다음 단계

대부분의 “Kafka 빠른 시작이 시작되지 않음” 문제는 소수의 근본 원인으로 귀결됩니다.

브로커 시작 실패

공식 요구 사항부터 시작하십시오:

  • Kafka 4.2 빠른 시작은 명시적으로 **Java 17+**를 요구합니다. 더 오래된 JDK를 사용 중이라면 먼저 이를 해결하십시오.
  • KRaft 모드에서 스토리지 포맷팅은 필수적인 명시적 단계입니다. kafka-storage.sh format을 건너뛰면 시작 실패 또는 메타데이터 오류가 발생할 가능성이 높습니다.

실험을 해보고 이제 깨끗한 상태로重新开始하고 싶다면, Kafka의 빠른 시작은 데모에서 사용한 로컬 데이터 디렉토리를 삭제하는 방법을 보여줍니다:

rm -rf /tmp/kafka-logs /tmp/kraft-combined-logs

브로커가 실행 중임에도 CLI 명령 실패

Kafka 4.x에서 --zookeeper가 아닌 --bootstrap-server를 사용하고 있는지 검증하십시오. Kafka의 호환성 문서는 Kafka 4.0부터 AdminClient 명령에서 --zookeeper가 제거되었음을 명시적으로 지적합니다.

Docker 네트워킹 예상치 못한 상황

Kafka가 Docker에 있고 클라이언트 도구가 Docker 외부(또는 다른 머신)에 있다면, 올바른 리스너 광고가 필요할 수 있습니다. 브로커 구성 문서에서는 클라이언트가 연결해야 하는 주소가 바인딩 주소(listeners)와 다를 때 advertised.listeners가 사용된다고 설명합니다.

빠른 시작 후 갈 곳

이 게시물의 예시를 완료했다면, 이미 가장 일반적인 첫 검색 질문에 답했습니다:

  • Kafka의 용도 (종단 간 이벤트 스트리밍)
  • 로컬 Kafka 설치 방법 (tarball 또는 Docker)
  • ZooKeeper가 사라진 이유 및 4.x에서 KRaft가 기본값인 이유
  • 일상적으로 중요한 CLI 도구 (토픽, 프로듀서, 컨슈머, 그룹)

여기서부터, 가장 가치 있는 다음 단계는 일반적으로 다음과 같습니다:

  • 토픽, 파티션, 복제에 대한 더 깊은 정신 모델(mental models)을 위해 Kafka의 “소개(Introduction)” 읽기.
  • 첫 번째 처리 애플리케이션을 원한다면 Kafka Streams 빠른 시작 탐색 (Streams 빠른 시작은 WordCount 데모 실행 및 콘솔 컨슈머로 결과 검사를 시연함).

구독하기

시스템, 인프라, AI 엔지니어링에 관한 새 글을 받아보세요.