들어가면서
대규모 트래픽 상황에서도 안정적이고 높은 TPS(초당 트랜잭션 수)를 유지하는 서버를 구축하고자 하는 것은 많은 엔지니어의 목표입니다. 저 역시 위대한 엔지니어들이 그러했듯, 현재의 상태에 안주하지 않고 개선을 추구하고 있습니다.
특히, 대용량 데이터를 효율적으로 처리하기 위한 목표를 위해 Kafka 서버를 도입하려고 합니다.
이 포스팅에서는 `Kafka 서버 구축 과정을 단계별로` 설명하며, 스프링 같은 백엔드 서버와 연결하지 않습니다. Kafka를 직접 작동시켜보며, 그 원리와 구조를 파악하는 것이 목표입니다.
카프카(Kafka) 란?
Apache Kafka는 고성능 데이터 파이프라인, 스트리밍 분석, 데이터 통합 및 미션 크리티컬 애플리케이션을 위한 오픈 소스 분산 이벤트 스트리밍 플랫폼입니다. 현재 많은 기업들이 Kafka의 이벤트 스트리밍을 사용하고 있으며, 그 사용 빈도는 점차 증가하고 있습니다.
특히 백엔드 개발자 채용 공고에서 자주 보이는 것을 보면 말입니다.
`메시지 큐(Message Queue, MQ)`
메시지 지향 미들웨어(MOM, Message Oriented Middleware)는 비동기 메시지를 사용하여 각 응용 프로그램 간에 데이터를 송수신하는 것을 의미하며, 메시지(이벤트) 기반의 매개체라고 할 수 있습니다.
MOM을 구현한 시스템을 MQ(메시지 큐)라고 합니다. 현재 많이 사용되는 오픈 소스 MQ로는 RabbitMQ, Kafka, ActiveMQ 등이 있습니다.
`이벤트 스트리밍 플랫폼`
Kafka는 세 가지 주요 기능을 결합하여 end-to-end 이벤트 스트리밍을 구현할 수 있습니다:
이벤트 스트림을 지속적으로 발행(publish)하고 구독(subscribe)할 수 있습니다. 이벤트 스트림을 내구성 있고 안정적으로 저장(store)할 수 있습니다.
이러한 특징과 더불어 Kafka는 확장성, 탄력성, 내결함성, 그리고 보안성을 갖춘 방식으로 제공됩니다. Kafka 환경은 자가 관리하거나 다양한 공급 업체에서 제공하는 완전 관리형 서비스를 사용할 수 있습니다.
카프카 서버 구축하기
Docker 를 이용해서 카프카 서버를 구축할 수도 있지만, 이 글에서는 직접 다운로드한 카프카를 이용해서 진행합니다.
Kafka 다운로드
가장 먼저, Apache Kafka 다운로드 공식 홈페이지에 들어가서 Kafka 최신 버전을 다운로드합니다.
(저는 2024년 6월에 출시된 3.7.1 버전을 다운받았습니다)
자 이제
다운로드한 kafka를 적절한 디렉토리로 옮겨주시고, 터미널에서 살펴봅시다.
여기서 주로 사용하는 bin, config 폴더에 주목합니다.
- `bin` : kafka 관련 각종 실행 쉘 커맨드 파일이 있음
- `config` : 설정 관련 파일이 존재함
Kafka Zookeeper 구동
루트 디렉토리인 kafka_2.13-3.7.1에서 모든 쉘 커맨드를 실행합니다!
Kakfa Cluster를 관리하고 분산 처리를 조정하는 역할을 하는 `Zookeeper를 구동`시킵니다.
아래의 쉘 커맨드를 입력합니다.
./bin/zookeeper-server-start.sh
./config/zookeeper.properties
위 두 개의 명령어의 뜻은 다음과 같습니다.
1. bin 폴더에 존재하는 zookeeper-server-start.sh 쉘 커맨드를 구동
2. 이때 config 폴더에 존재하는 zookeepr.properties 설정 파일을 참조
그리고 Zookeeper는 2181 포트에서 구동된다고 합니다.
Kafka Broker 구동
Kafka의 핵심 Kafka Broker를 구동해 보겠습니다.
주의할 점은 `Zookeeper 가 구동 중이어야만` Kafka Broker의 구동이 가능합니다.
Kafka 폴더에서 쉘 커맨드를 날려줍니다.
./bin/kafka-server-start.sh
./config/server.properties
위 두 개의 명령어의 뜻은 다음과 같습니다.
1. bin 폴더에 존재하는 kafka-server-start.sh 쉘 커맨드를 구동하며
2. cofig 폴더의 server.properties 설정 파일을 참조합니다.
Kafka Broker는 기본적으로 9092 포트에서 구동됩니다.
Topic 확인 및 생성과 삭제
이제 서버 구축의 마지막 단계까지 왔습니다.
Kafka Broker에 새로운 topic을 만들겠습니다.
다운로드하였던 Kafka 폴더는 topic 관련 쉘 커맨드 또한 제공합니다.
topic 생성
./bin/kafka-topics.sh --create --topic [생성할 topic 이름] --bootstrap-server localhost:9092 --partitions 1
`bootstrap-server localhost:9092` 옵션은 Kafka 클러스터에 연결하기 위한 초기 주소로, 로컬 머신의 9092 포트에서 실행 중인 Kafka 브로커를 가리킵니다. 이 초기 연결 주소를 통해 Kafka 클라이언트는 브로커와 통신을 시작하며, 이후 필요한 작업(예: 토픽 생성, 데이터 전송 등)을 수행할 수 있습니다.
`Partitons 뒤의 N` 은 `topic을 구성하는 partition의 복제수`를 의미합니다.
Kafka의 고가용성(High Availability)을 보장합니다.
topic 삭제
./bin/kafka-topics.sh --delete --topic [삭제할 topic 이름] --bootstrap-server localhost:9092
해당 명령어를 통해 생성한 topic을 삭제할 수 있습니다.
topic 목록 확인
./bin/kafka-topics.sh --bootstrap-server localhost:9092 --list
이번에는 생성한 topic 목록을 확인해 보겠습니다.
이미지처럼 생성한 topic 인 my-topic 이 조회되는 것을 확인할 수 있습니다.
topic 정보 확인
./bin/kafka-topics.sh --describe --topic [확인할 topic 이름] --bootstrap-server localhost:9092
특정 topic의 정보를 확인할 수도 있습니다.
여러 가지 정보가 나오는데요. 연습 단계에서 그 의미를 알 필요는 없어 보입니다.
Producer & Concumer를 구동하고 테스트 진행
이번에는 메시지(이벤트)를 생성하는 Producer와 Consumer를 쉘 커맨드를 통해 구현하고 테스트해 보겠습니다. Producer와 Consumer를 구동하기 위해서는 앞서 구동시켰던 `Zookeeper와 Kafka Broker가 실행 중이어야 합니다.`
Producer 구동하기
./bin/kafka-console-producer.sh --broker-list localhost:9092 --topic [발행할 topic 이름]
Kafak 폴더에서 제공된 쉘 커맨드로 구동합니다.
명령어가 정상적으로 실행되고 > 입력창이 뜨는 것을 보실 수 있습니다.
여기에 메시지(이벤트)를 발행하면 zoozoo-topic을 구독한 Consumer가 해당 메시지(이벤트)를 읽어올 수 있습니다.
Consumer 구동하기
./bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic [구독할 topic 이름] --from-beginning
`--from-beginning` 옵션은 Consumer 가 구독하는 topic에 저장된 이전의 모든 메시지를 읽어오는 옵션입니다.
커맨드 실행 시 별도의 텍스트가 출력되지는 않습니다.
Producer를 통해 메시지를 발행하고 Consumer에서 메시지 읽기
Consumer 두 개를 접속시킨 뒤 Producer에서 메시지를 발행해 봤습니다.
`과거에 발행했던 hi를 포함해서 새로 발행한 메시지`가 동일하게 확인되고 있습니다.
✅ 실습을 통해 배운 점
Kafka의 핵심 개념인 토픽 생성, 삭제, 조회, 설명까지의 명령어를 CLI 환경에서 직접 다뤄보면서,
Kafka의 작동 원리를 한층 더 깊이 이해할 수 있었습니다.
또한 Producer와 Consumer를 CLI로 직접 구동해보면서, 메시지 발행-구독 구조의 기본 흐름을 익혔고,
`멀티 Consumer 환경에서도 메시지가 동일하게 전달되는 것을 확인`하며 Kafka의 pub-sub 구조에 대한 이해도를 높일 수 있었습니다.
🚀 앞으로는 Kafka를 이렇게 확장해볼 생각입니다.
`Spring Boot와의 연동`
실제 애플리케이션 레벨에서 @KafkaListener, KafkaTemplate 등을 통해 메시지 송수신을 처리해볼 것입니다.
`실시간 이벤트 처리`
입찰 완료 후 실시간 알림을 전송하는 흐름에서, Kafka를 도입하여 비동기 처리 및 시스템 간 결합도를 낮출 수 있습니다.
이를 통해 사용자 응답 속도를 개선하고, 알림 시스템 장애 시에도 메시지 손실 없이 재처리가 가능한 구조를 설계할 수 있습니다.
Reference