본문 바로가기
Backend2025년 9월 28일6분 읽기

Kafka 입문 — 메시지 브로커의 핵심 개념과 실습

YS
김영삼
조회 159

Kafka 핵심 개념

Apache Kafka는 분산 이벤트 스트리밍 플랫폼으로, 높은 처리량과 내구성을 제공합니다. 실시간 데이터 파이프라인과 이벤트 기반 아키텍처의 핵심 인프라입니다.

주요 구성 요소

구성 요소역할비유
Topic메시지 분류 단위DB 테이블
Partition병렬 처리 단위테이블 샤드
Producer메시지 발행INSERT 쿼리
Consumer메시지 구독SELECT 쿼리
Consumer Group파티션 분배 단위워커 풀
Offset메시지 위치 추적커서

Docker Compose로 Kafka 실행

version: '3.8'
services:
  kafka:
    image: confluentinc/cp-kafka:7.5.0
    ports:
      - "9092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LOG_DIRS: /var/lib/kafka/data
      CLUSTER_ID: 'MkU3OEVBNTcwNTJENDM2Qk'
    volumes:
      - kafka-data:/var/lib/kafka/data
volumes:
  kafka-data:

Node.js Producer 구현

const { Kafka } = require('kafkajs');

const kafka = new Kafka({
  clientId: 'my-app',
  brokers: ['localhost:9092'],
});

const producer = kafka.producer();

async function sendMessage(topic, messages) {
  await producer.connect();
  await producer.send({
    topic,
    messages: messages.map(msg => ({
      key: msg.key,
      value: JSON.stringify(msg.value),
      headers: { source: 'my-app' },
    })),
  });
}

await sendMessage('orders', [
  {
    key: 'order-123',
    value: {
      orderId: 123,
      userId: 456,
      items: [{ productId: 1, quantity: 2 }],
      status: 'created',
      timestamp: Date.now(),
    },
  },
]);

await producer.disconnect();

Node.js Consumer 구현

const consumer = kafka.consumer({ groupId: 'order-service' });

async function startConsumer() {
  await consumer.connect();
  await consumer.subscribe({
    topics: ['orders'],
    fromBeginning: false,
  });

  await consumer.run({
    eachMessage: async ({ topic, partition, message }) => {
      const order = JSON.parse(message.value.toString());
      console.log('[Partition ' + partition + '] Order: ' + order.orderId);

      switch (order.status) {
        case 'created':
          await processNewOrder(order);
          break;
        case 'paid':
          await fulfillOrder(order);
          break;
      }
    },
  });
}

startConsumer().catch(console.error);

파티션과 컨슈머 그룹 이해

# 토픽 생성 (파티션 3개)
kafka-topics --create --topic orders \
  --partitions 3 \
  --replication-factor 1 \
  --bootstrap-server localhost:9092

# 같은 Consumer Group의 컨슈머 3개 실행 시:
# Consumer A → Partition 0
# Consumer B → Partition 1
# Consumer C → Partition 2
  • 파티션 수는 최대 병렬 처리 단위를 결정하므로 신중하게 설정합니다
  • 메시지 순서는 같은 파티션 내에서만 보장됩니다 (key 기반 파티셔닝)
  • Consumer Group 별로 독립적인 offset을 유지합니다
  • RabbitMQ 대비 Kafka는 대용량 스트리밍에 강하고, 메시지 재처리가 가능합니다

Kafka는 높은 처리량과 내구성이 필요한 이벤트 기반 시스템의 핵심 인프라입니다. 올바른 파티션 설계와 컨슈머 그룹 전략이 시스템 성능을 좌우합니다.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록