Kafka · 2025-09-08 · 1분 읽기

Kafka 입문 - 왜 쓰고, 어떻게 동작하나

목차
  • 1. Kafka vs 기존 메시지 큐
  • 2. 핵심 개념
  • 3. Spring Kafka 기본 설정
  • 4. Producer
  • 5. Consumer
  • 6. 파티션 키 전략

1. Kafka vs 기존 메시지 큐

구분RabbitMQKafka
모델PushPull
메시지 보관소비 후 삭제디스크에 보관 (기간 설정)
처리량중간매우 높음
순서 보장큐 단위파티션 단위
재처리어려움offset으로 재처리 가능

2. 핵심 개념

Producer → Topic → Consumer Group
              ↓
         Partition 0  → Consumer A
         Partition 1  → Consumer B
         Partition 2  → Consumer C

Topic: 메시지 카테고리 Partition: 병렬 처리 단위. 파티션 수 = 최대 병렬 컨슈머 수 Offset: 파티션 내 메시지 위치. 컨슈머가 직접 관리 Consumer Group: 같은 그룹 내에서 파티션을 나눠 소비

3. Spring Kafka 기본 설정

spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: my-service
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer

4. Producer

@Service
@RequiredArgsConstructor
public class OrderEventPublisher {
    private final KafkaTemplate<String, OrderEvent> kafkaTemplate;
 
    public void publish(OrderEvent event) {
        kafkaTemplate.send("order-events", event.getOrderId().toString(), event)
            .whenComplete((result, ex) -> {
                if (ex != null) {
                    log.error("Failed to send event: {}", event, ex);
                } else {
                    log.debug("Event sent: partition={}, offset={}",
                        result.getRecordMetadata().partition(),
                        result.getRecordMetadata().offset());
                }
            });
    }
}

5. Consumer

@Component
public class OrderEventConsumer {
 
    @KafkaListener(topics = "order-events", groupId = "inventory-service")
    public void consume(OrderEvent event, Acknowledgment ack) {
        try {
            inventoryService.reserve(event);
            ack.acknowledge();
        } catch (InsufficientStockException e) {
            // Dead Letter Topic으로 이동
            throw e;
        }
    }
}

6. 파티션 키 전략

같은 키는 항상 같은 파티션으로 가기 때문에 순서가 보장된다.

// 같은 userId의 이벤트는 항상 같은 파티션 → 순서 보장
kafkaTemplate.send("order-events", order.getUserId().toString(), event);

파티션 수보다 컨슈머가 많으면 유휴 컨슈머가 생긴다.

'Kafka ' 카테고리의 다른 글

  • 이 카테고리에 다른 글이 없습니다.