ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kafka 파티션 키 전략
    Develop 2025. 9. 5. 13:47

    개요

    이커머스 시스템에서 Kafka 파티션 키를 어떻게 설계하고 적용했는지에 대해 다룹니다. 감사 로그, 좋아요 집계, 주문 처리 등 각 도메인별로 어떤 파티션 키 전략을 선택했는지와 그 이유를 설명합니다.

    파티션 키의 중요성

    Kafka에서 파티션 키는 다음과 같은 역할을 합니다:

    • 순서 보장: 동일한 키를 가진 메시지는 같은 파티션으로 전송되어 순서가 보장됩니다
    • 부하 분산: 키의 해시값으로 파티션을 결정하여 부하를 분산시킵니다
    • 스케일링: 파티션 수만큼 컨슈머를 병렬로 실행할 수 있습니다

    도메인별 파티션 키 전략

    1. 주문 도메인 - OrderEventPublisher

    @Component
    public class OrderEventPublisher {
        public void publishSuccess(Long orderId, String userId) {
            OrderSuccessEvent event = OrderSuccessEvent.create(orderId, userId);
            kafkaTemplate.send(KafkaTopics.ORDER, orderId.toString(), event);
        }
    }

    파티션 키: OrderId

    선택 이유:

    • 동일한 주문에 대한 모든 이벤트(생성, 결제, 완료, 취소)가 순서대로 처리되어야 함
    • 주문 상태 변경의 정합성 보장
    • 주문별로 이벤트를 그룹핑하여 추적 및 디버깅 용이

    장점:

    • 주문 생명주기 이벤트의 순서 보장
    • 주문별 장애 격리 가능
    • 특정 주문에 문제가 생겨도 다른 주문에 영향 없음

    2. 결제 도메인 - PaymentEventPublisher

    @Component
    public class PaymentEventPublisher {
        public void publishSuccess(Long orderId, String paymentId) {
            PaymentSuccessEvent event = PaymentSuccessEvent.create(orderId, paymentId);
            kafkaTemplate.send(KafkaTopics.PAYMENT_SUCCESS, orderId.toString(), event);
        }
    }

    파티션 키: OrderId

    선택 이유:

    • 결제는 주문과 강하게 연결된 도메인
    • 주문-결제 이벤트 간의 순서 보장 필요
    • 주문 도메인과 동일한 파티션 키로 일관성 있는 설계

    장점:

    • 주문과 결제 이벤트가 같은 파티션에서 순서대로 처리
    • 결제 실패 시 보상 트랜잭션의 순서 보장
    • 주문별 결제 히스토리 추적 용이

    3. 좋아요 감사 로그 - LikeEventPublisher

    @Component
    public class LikeEventPublisher {
        public void publishLike(String userId, Long productId) {
            // 감사용 이벤트
            ProductLikedEvent auditEvent = ProductLikedEvent.create(userId, productId);
            kafkaTemplate.send(KafkaTopics.PRODUCT_LIKE, productId.toString(), auditEvent);
        }
    }

    파티션 키: productId

    선택 이유:

    • 상품별로 좋아요 이벤트를 그룹핑
    • 동일한 상품에 대한 좋아요/취소 이벤트 순서 보장
    • 상품별 감사 로그 추적 및 분석 용이

    장점:

    • 특정 상품의 좋아요 히스토리 순차 처리
    • 상품별 이상 패턴 탐지 가능 (급작스러운 좋아요 증가 등)
    • 상품 도메인 이벤트와의 일관성

    파티션 키 선택 시 고려사항

    1. 데이터 분산 (Data Distribution)

    // ❌ 잘못된 예: 카디널리티가 낮은 키
    kafkaTemplate.send(topic, event.getStatus(), event); // "SUCCESS", "FAILED" 등
    
    // ✅ 올바른 예: 카디널리티가 높은 키
    kafkaTemplate.send(topic, event.getOrderId().toString(), event); // 고유한 주문 ID

    문제점: 카디널리티가 낮으면 특정 파티션에 데이터가 집중됨
    해결책: 고유값이 많은 필드를 키로 선택

    2. 순서 보장 (Ordering Requirements)

    // 주문 상태 변경 이벤트들이 순서대로 처리되어야 하는 경우
    kafkaTemplate.send(KafkaTopics.ORDER, orderId.toString(), orderCreatedEvent);
    kafkaTemplate.send(KafkaTopics.ORDER, orderId.toString(), orderPaidEvent);

    핵심: 순서가 중요한 이벤트들은 반드시 같은 파티션으로 전송

    3. Hot Partition 방지

    // ❌ Hot Partition 발생 가능
    kafkaTemplate.send(topic, popularProductId, event);
    
    // ✅ 시간 기반으로 분산
    String partitionKey = popularProductId + ":" + LocalDate.now();
    kafkaTemplate.send(topic, partitionKey, event);

    전략: 시간, 해시 등을 조합하여 부하 분산

    실제 구현 시 주의사항

    1. 파티션 키 일관성

    public class KafkaTopics {
        public static final String ORDER = "order-events";
        public static final String PAYMENT_SUCCESS = "payment-success-events";
        public static final String PAYMENT_FAILED = "payment-failed-events";
        public static final String PRODUCT_LIKE = "product-like-events";
        public static final String LIKE_AGGREGATION = "like-aggregation-events";
    }

    토픽별로 명확한 파티션 키 전략 문서화

    2. 배치 처리 고려

    @KafkaListener(
        topics = LIKE_AGGREGATION,
        groupId = "Metrics",
        containerFactory = "BATCH_LISTENER"
    )
    public void handleLikeChangedEvent(
        List<ConsumerRecord<String, ProductLikeAggregationEvent>> records,
        Acknowledgment acknowledgment
    ) {
        // 같은 파티션의 레코드들은 순서가 보장됨
        // 배치 내에서 동일한 (productId, date) 조합은 함께 처리됨
    }

    배치 처리 시 파티션 키의 이점 활용

    결론

    효과적인 파티션 키 전략은 다음을 고려해야 합니다:

    1. 비즈니스 로직의 순서 보장 요구사항
    2. 데이터 분산과 부하 균형
    3. 도메인별 특성과 접근 패턴
    4. 확장성과 유지보수성

    각 도메인의 특성에 맞는 파티션 키 전략을 적용하여:

    • 주문/결제: 트랜잭션 순서 보장
    • 감사 로그: 상품별 이벤트 추적
    • 집계: 시간 기반 병렬 처리

    이를 통해 안정적이고 확장 가능한 이벤트 스트리밍 시스템을 구축할 수 있었습니다.

    댓글

Designed by Tistory.