Kafka 핵심 개념 및 동작 원리
Apache Kafka는 다음과 같은 주요 구성 요소로 이루어져 있습니다:
-
브로커 (Broker): Kafka 서버를 지칭하며, 메시지(이벤트)의 수신, 저장, 제공을 담당합니다. 여러 브로커가 클러스터를 형성하여 고가용성을 제공합니다.
-
이벤트 (Event): Kafka를 통해 주고받는 데이터 단위로, 브로커 디스크에 바이트 형태로 저장됩니다.
-
프로듀서 (Producer) & 컨슈머 (Consumer): 프로듀서는 이벤트를 Kafka로 전송하고, 컨슈머는 Kafka에서 이벤트를 읽어 처리합니다. 하나의 서비스가 양쪽 역할을 모두 수행할 수 있습니다.
-
토픽 (Topic): 메시지를 카테고리별로 분류하는 논리적인 채널입니다. 예를 들어,
payment-details나user-details와 같이 특정 유형의 메시지를 담습니다. -
파티션 (Partition): 토픽은 처리량 향상을 위해 여러 파티션으로 분할될 수 있습니다. 각 파티션은 토픽 메시지의 하위 집합을 저장하는 최소 저장 단위이며, 파티션 내에서는 메시지 순서가 항상 보존됩니다.
-
오프셋 (Offset): 컨슈머가 특정 파티션에서 메시지를 어디까지 읽었는지 추적하는 지표(북마크)입니다. 컨슈머 장애 시 마지막 오프셋부터 다시 읽기를 시작할 수 있습니다.
-
컨슈머 그룹 (Consumer Group): 여러 컨슈머가 함께 작동하는 그룹입니다. 토픽의 각 파티션은 그룹 내에서 정확히 하나의 컨슈머에 의해 소비되어 중복 처리 없이 병렬 처리가 가능합니다.
Kafka 이벤트 흐름 이해
-
단일 파티션 시나리오: 프로듀서가 생성한 모든 이벤트는 단일 파티션의 토픽으로 전송되며, 이벤트의 순서가 생산된 순서와 동일하게 보존됩니다. 컨슈머는 이벤트를 순차적으로 읽지만, 확장성에는 한계가 있습니다.
-
다중 파티션 시나리오: 토픽이 여러 파티션으로 분할되면, 프로듀서의 이벤트는 이 파티션들로 분산되어 기록됩니다. 각 이벤트는 정확히 하나의 파티션에 기록되며, 이를 통해 Kafka는 훨씬 더 많은 양의 데이터를 효율적으로 처리할 수 있는 높은 처리량을 달성합니다.
Docker를 활용한 Kafka 클러스터 구축
로컬 환경에서 Kafka 클러스터를 빠르게 시작하는 가장 쉬운 방법은 Docker를 활용하는 것입니다.
-
Docker 이미지 다운로드:
bash docker pull apache/kafka:4.0.0 -
Kafka 컨테이너 실행:
bash docker run -p 9092:9092 apache/kafka:4.0.0이 명령은 Kafka를 로컬 포트 9092에서 실행하여 접근 가능하게 합니다.
Rails 애플리케이션과 Karafka 통합
Karafka Gem은 Rails 애플리케이션에서 Kafka를 손쉽게 사용할 수 있도록 도와줍니다.
-
Karafka Gem 추가:
Gemfile에gem 'karafka'를 추가하고bundle install을 실행합니다. -
Karafka 스캐폴드 설치:
bundle exec karafka install명령을 실행하여karafka.rb설정 파일과 기본 컨슈머 파일을 생성합니다. -
Karafka 설정 (
karafka.rb):bootstrap.servers를 통해 Kafka 브로커 정보를 설정하고,routes.draw블록 내에서 토픽과 컨슈머 클래스를 매핑합니다. 선택적으로dead_letter_queue를 구성하여 실패한 메시지를 별도의 토픽으로 전송할 수 있습니다. -
컨슈머 구현:
ApplicationConsumer를 상속받는 사용자 정의 컨슈머 클래스(예:ProductsConsumer)를 구현하여 특정 토픽에서 메시지를 받아 처리하는 로직을 작성합니다. -
프로듀서 구현:
Karafka.producer.produce_async메서드를 사용하여 Rails 애플리케이션에서 비동기적으로 Kafka 토픽으로 메시지를 발행합니다.
이러한 아키텍처를 통해 Rails 애플리케이션은 실시간 이벤트 스트림을 효율적으로 처리하며, 다양한 서비스 간의 원활한 데이터 흐름을 보장하는 이벤트 기반 시스템을 구축할 수 있습니다.