이커머스 실시간 판매 분석 파이프라인: Kafka부터 Grafana 대시보드까지

커머스

실시간 분석Kafka데이터 파이프라인Grafana이커머스 데이터

이 글은 누구를 위한 것인가

  • 실시간 판매 현황을 모니터링하고 빠른 의사결정을 하고 싶은 이커머스 운영팀
  • 이커머스 데이터 파이프라인을 처음 구축하는 데이터 엔지니어
  • 현재 배치 처리 방식에서 실시간 스트리밍으로 전환하려는 팀

들어가며

"지금 얼마나 팔리고 있나?"라는 질문에 즉각 답할 수 있는가? 많은 이커머스가 전날 데이터를 오전에 확인하거나, 심지어 주간 리포트로 현황을 파악한다. 이런 지연은 프로모션 효과 측정, 재고 문제 감지, 시스템 장애 탐지를 늦춘다.

실시간 분석 파이프라인은 주문, 결제, 반품, 재고 이벤트를 수초 내에 집계하여 의사결정 속도를 높인다. 블랙프라이데이에 특정 카테고리가 폭발적으로 팔리는 순간 재고 보충과 프로모션을 즉시 조정할 수 있다.

이 글은 bluefoxdev.kr의 데이터 엔지니어링 파이프라인 설계 를 참고하고, 이커머스 실시간 분석 관점에서 확장하여 작성했습니다.


1. 파이프라인 전체 아키텍처

[이커머스 서비스]
주문 서비스  결제 서비스  재고 서비스  회원 서비스
    ↓            ↓           ↓           ↓
            [Kafka]
     order-events  payment-events  inventory-events
            ↓
    [Kafka Consumer]
    Flink / Spark Streaming
            ↓
    [저장소]
    ClickHouse (실시간)  BigQuery (배치/ML)
            ↓
    [시각화]
    Grafana  Metabase  자체 대시보드
            ↓
    [알림]
    Slack / PagerDuty (이상 탐지)

2. 이벤트 스키마 설계

2.1 주문 이벤트

interface OrderCreatedEvent {
  eventType: 'ORDER_CREATED';
  eventId: string;
  occurredAt: string;  // ISO 8601
  
  orderId: string;
  userId: string;
  totalAmount: number;
  itemCount: number;
  channel: 'web' | 'mobile_app' | 'mobile_web';
  couponUsed: boolean;
  paymentMethod: string;
  
  items: Array<{
    productId: string;
    categoryId: string;
    quantity: number;
    unitPrice: number;
  }>;
  
  shipping: {
    region: string;     // 배송 권역
    type: 'standard' | 'express' | 'pickup';
  };
}

2.2 Kafka Producer 구현

import { Kafka } from 'kafkajs';

const kafka = new Kafka({
  clientId: 'order-service',
  brokers: ['kafka-1:9092', 'kafka-2:9092', 'kafka-3:9092'],
});

const producer = kafka.producer({
  idempotent: true,  // 중복 방지
});

export async function publishOrderEvent(event: OrderCreatedEvent): Promise<void> {
  await producer.send({
    topic: 'order-events',
    messages: [{
      key: event.orderId,
      value: JSON.stringify(event),
      headers: {
        eventType: event.eventType,
        version: '1.0',
      },
    }],
  });
}

3. 실시간 집계: ClickHouse

3.1 ClickHouse 테이블 설계

-- 주문 이벤트 원본 테이블
CREATE TABLE order_events (
  event_id        String,
  occurred_at     DateTime64(3),  -- 밀리초 정밀도
  order_id        String,
  user_id         String,
  total_amount    Decimal(12, 2),
  item_count      UInt16,
  channel         LowCardinality(String),
  payment_method  LowCardinality(String),
  region          LowCardinality(String),
  category_ids    Array(String)
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(occurred_at)
ORDER BY (occurred_at, order_id);

-- 실시간 집계 뷰 (분 단위)
CREATE MATERIALIZED VIEW orders_per_minute
ENGINE = SummingMergeTree()
ORDER BY (minute, channel)
AS SELECT
  toStartOfMinute(occurred_at) AS minute,
  channel,
  count() AS order_count,
  sum(total_amount) AS total_revenue,
  avg(total_amount) AS avg_order_value
FROM order_events
GROUP BY minute, channel;

3.2 실시간 KPI 쿼리

-- 지난 1시간 채널별 매출 현황
SELECT
  channel,
  count() AS orders,
  sum(total_amount) AS revenue,
  avg(total_amount) AS aov,
  countIf(item_count > 1) / count() * 100 AS multi_item_rate_pct
FROM order_events
WHERE occurred_at >= now() - INTERVAL 1 HOUR
GROUP BY channel
ORDER BY revenue DESC;

-- 1분 단위 매출 추이 (최근 2시간)
SELECT
  toStartOfMinute(occurred_at) AS minute,
  count() AS orders,
  sum(total_amount) AS revenue
FROM order_events
WHERE occurred_at >= now() - INTERVAL 2 HOUR
GROUP BY minute
ORDER BY minute;

4. Grafana 대시보드 설계

4.1 필수 패널 구성

[이커머스 실시간 대시보드]

Row 1: 핵심 KPI (Big Number)
  - 오늘 주문 수       - 오늘 매출
  - 전일 대비 주문     - 전일 대비 매출
  - 현재 진행 주문     - 결제 성공률

Row 2: 시계열 트렌드 (Time Series)
  - 분당 주문 수 추이
  - 분당 매출 추이
  - 채널별 주문 분포

Row 3: 카테고리/상품 (Bar Chart, Table)
  - 실시간 인기 카테고리 Top 10
  - 실시간 인기 상품 Top 20
  - 지역별 주문 히트맵

Row 4: 시스템 상태
  - 결제 성공/실패율
  - 평균 결제 처리 시간
  - 재고 부족 알림

4.2 이상 탐지 알림 설정

# Grafana Alert Rule 예시
- name: "주문량 급감 감지"
  condition: |
    orders_per_minute < 
    avg(orders_per_minute offset 1w) * 0.5
  for: 5m
  annotations:
    summary: "주문량이 평소 대비 50% 이하"
    description: "결제 시스템 또는 서비스 장애 가능성"
  labels:
    severity: critical
  notification:
    channels: ["slack-ops", "pagerduty"]

5. 성능 최적화 팁

항목권장 설정이유
Kafka 파티션 수주문 서비스 인스턴스 × 3병렬 처리 극대화
ClickHouse 샤드일일 데이터 100GB당 1샤드쿼리 병렬화
Grafana 새로고침30초 간격DB 부하 방지
데이터 보존 기간원시 3개월, 집계 2년스토리지 비용 절감

마무리: 구축 우선순위

  1. 1주 차: Kafka 클러스터 구성 + 주문 이벤트 발행
  2. 2주 차: ClickHouse 설치 + Consumer 구현 + 기본 쿼리
  3. 3주 차: Grafana 연동 + 기본 대시보드 완성
  4. 4주 차: 이상 탐지 알림 + 슬랙 연동

실시간 파이프라인은 완벽하게 시작하려 하지 말고, 일단 주문 이벤트 하나로 시작해서 점진적으로 확장하는 것이 현실적이다.