DevOps

메시지 큐(Message Queue)와 Kafka

code2772 2025. 2. 26. 07:56
728x90
반응형

 

대규모 시스템에서는 데이터 처리를 효율적으로 관리하기 위해 메시지 큐(Message Queue, MQ)를 사용합니다. 메시지 큐는 다양한 구현체가 있으며, 그중에서도 Apache Kafka는 가장 널리 사용되는 분산 메시징 시스템 중 하나입니다. 이 글에서는 메시지 큐의 개념과 Kafka의 내부 구조 및 동작 방식을 깊이 있게 살펴보겠습니다.

 


 

1. 메시지 큐(Message Queue)란?

메시지 큐는 생산자(Producer)가 보낸 메시지를 소비자(Consumer)가 받아 처리하는 비동기 방식의 통신 시스템입니다.

이 방식은 여러 시스템이 독립적으로 동작할 수 있도록 하며, 부하 분산(Load Balancing)비동기 처리(Asynchronous Processing)를 가능하게 합니다.

 

 

메시지 큐의 핵심 개념

  1. 프로듀서(Producer)
    • 메시지를 생성하여 큐로 전송하는 역할
    • 예: 사용자의 주문 요청, 로그 데이터 전송
  2. 브로커(Broker)
    • 메시지를 저장하고 전달하는 역할
    • RabbitMQ, Kafka, ActiveMQ 등 다양한 메시지 큐 시스템이 존재
  3. 컨슈머(Consumer)
    • 메시지를 브로커로부터 가져와 처리하는 역할
    • 예: 주문 처리 시스템, 알림 시스템
  4. 큐(Queue)
    • 메시지가 저장되는 공간
    • 메시지는 순서대로(First In, First Out, FIFO) 처리됨

 


 

2. 메시지 큐의 동작 방식

 

기본적인 메시지 처리 흐름

  1. Producer가 메시지를 브로커로 전송
  2. Broker가 메시지를 저장
  3. Consumer가 메시지를 읽어 처리
  4. 처리가 완료되면 메시지는 삭제됨 (일반적인 큐 시스템의 경우)

 

메시지 큐의 장점

  1. 비동기 처리 가능: 프로듀서가 메시지를 보낸 후 즉시 다음 작업 수행 가능
  2. 부하 분산 가능: 여러 개의 컨슈머가 분산 처리 가능
  3. 서비스 독립성 보장: 프로듀서와 컨슈머가 서로 직접적으로 연결되지 않음
  4. 안정성 보장: 메시지가 브로커에 저장되므로 장애 발생 시에도 데이터 손실 방지 가능

 


 

3. 메시지 큐의 대표적인 구현체

 

메시지 큐 시스템 주요 특징

RabbitMQ AMQP(Advanced Message Queuing Protocol) 기반, 높은 안정성
ActiveMQ 자바 기반 메시지 브로커, JMS(Java Message Service) 지원
Apache Kafka 대용량 데이터 스트리밍에 최적화된 분산 메시징 시스템
Redis Pub/Sub 인메모리 기반 메시지 큐로 빠른 처리 가능

 

4. Apache Kafka란?

 

Kafka는 대량의 데이터를 고속 처리하고 확장성을 보장하는 분산 메시징 시스템입니다.

기본적인 메시지 큐 시스템과 달리, 이벤트 스트리밍(Event Streaming)을 기반으로 하며 데이터의 영속성(Persistence)을 보장하는 것이 특징입니다.

 

Kafka의 주요 특징

  1. 분산 처리(Distributed Processing)
    • 여러 개의 브로커(서버)로 구성되어 대량의 메시지를 처리 가능
  2. 데이터 영속성(Persistence)
    • 메시지가 저장(Log)되므로 컨슈머가 장애 발생 후에도 다시 읽을 수 있음
  3. 확장성(Scalability)
    • 프로듀서, 브로커, 컨슈머를 독립적으로 확장 가능
  4. 고성능 처리(High Throughput)
    • 배치 처리 및 압축 기술을 사용하여 빠른 속도로 대량의 데이터 처리

 


 

5. Kafka의 내부 구조

Kafka는 Topic, Partition, Broker, Producer, Consumer, Zookeeper 등의 주요 구성 요소로 이루어져 있습니다.

Kafka의 핵심 구성 요소

  1. Topic (토픽)
    • 메시지가 저장되는 공간
    • 하나의 토픽은 여러 개의 파티션(Partition)으로 나뉨
    • 예: "주문 데이터", "로그 데이터" 등의 주제로 구성 가능
  2. Partition (파티션)
    • 토픽을 여러 개의 파티션으로 나누어 데이터 저장
    • 여러 개의 브로커에 분산 저장하여 성능 및 확장성 보장
  3. Broker (브로커)
    • Kafka 서버 자체를 의미
    • 여러 개의 브로커가 클러스터를 형성하여 동작
  4. Producer (프로듀서)
    • 메시지를 생성하여 Kafka의 특정 토픽으로 전송
    • 예: 웹 서버에서 사용자 행동 데이터를 Kafka로 전송
  5. Consumer (컨슈머)
    • Kafka에서 메시지를 읽어 가는 역할
    • 여러 개의 컨슈머가 하나의 토픽을 동시에 읽을 수 있음
  6. Zookeeper
    • Kafka의 메타데이터(토픽, 파티션 정보, 리더 선출 등) 관리
    • 클러스터 노드 간의 동기화 역할 수행

 


 

6. Kafka의 동작 방식

 

메시지 생성 및 전송

  1. Producer가 특정 Topic으로 메시지를 보냄
  2. Kafka는 메시지를 Partition 단위로 나누어 저장
  3. 메시지는 Broker에 저장되며, 컨슈머가 가져갈 때까지 유지됨

메시지 소비

  1. Consumer는 특정 토픽의 메시지를 구독
  2. Kafka는 Offset을 사용하여 마지막으로 읽은 메시지를 관리
  3. Consumer Group을 사용하면 여러 개의 컨슈머가 하나의 토픽을 병렬 처리 가능

 


 

7. Kafka를 활용한 코드 예제

 

(1) 메시지 전송 (Producer)

import org.apache.kafka.clients.producer.*;

import java.util.Properties;

public class KafkaProducerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        Producer<String, String> producer = new KafkaProducer<>(props);
        producer.send(new ProducerRecord<>("my_topic", "key1", "Hello Kafka!"));

        producer.close();
    }
}

 

(2) 메시지 수신 (Consumer)

import org.apache.kafka.clients.consumer.*;

import java.util.Collections;
import java.util.Properties;

public class KafkaConsumerExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        props.put("group.id", "test_group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        Consumer<String, String> consumer = new KafkaConsumer<>(props);
        consumer.subscribe(Collections.singletonList("my_topic"));

        while (true) {
            ConsumerRecords<String, String> records = consumer.poll(100);
            for (ConsumerRecord<String, String> record : records) {
                System.out.println("Received: " + record.value());
            }
        }
    }
}


 

8. 결론

Kafka는 단순한 메시지 큐를 넘어 대용량 데이터 스트리밍 처리에 최적화된 강력한 도구입니다.

비동기 메시징고속 데이터 처리가 필요할 때 Kafka를 사용하면 큰 효과를 볼 수 있습니다.

반응형