저는 3년 넘게 암호화폐 데이터 파이프라인을 구축하며 다양한 아키텍처를 시도해본 엔지니어입니다. 이 글에서는 ClickHouse와 주요 거래소 API를 활용하여 신뢰할 수 있는 암호화폐 히스토리 데이터웨어하우스를 구축하는 방법과, 이 데이터에 HolySheep AI를 연동하여 고급 분석 파이프라인을 만드는 실전 경험을 공유하겠습니다.

왜 ClickHouse인가?

암호화폐 데이터는典型的으로:

저는 처음에 PostgreSQL로 시작했지만, 1억 건 이상 데이터가 쌓이자 查询延迟가 10초를 넘어서 문제가 되었습니다. ClickHouse는 이러한 시나리오에서 압도적 성능을 보여주며, 제가 테스트한 환경에서:

-- 1억 건 데이터 기준聚合查询 성능
SELECT 
    symbol,
    toStartOfHour(timestamp) as hour,
    avg(price) as avg_price,
    max(price) - min(price) as volatility
FROM ohlcv_minute
WHERE timestamp >= now() - interval 30 day
GROUP BY symbol, hour
ORDER BY hour DESC
LIMIT 1000

-- 실행 시간: 1.2초 (PostgreSQL 대비 85% 단축)
-- 스캔 데이터량: 4.2GB
-- CPU 사용률: 340% (병렬 처리)

아키텍처 개요

+------------------+     +------------------+     +------------------+
|   Binance API    |     |  Coinbase API    |     |   Kraken API     |
|  (WebSocket/     |     |  (Exchange/      |     |  (REST API +     |
|   REST)          |     |   Pro)           |     |   WebSocket)     |
+--------+---------+     +--------+---------+     +--------+---------+
         |                         |                         |
         v                         v                         v
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|  Apache Kafka    |<----+  Apache Kafka    |<----+  Apache Kafka    |
|  (메시지 버스)    |     |  (토픽 분할)      |     |  (장애 복구)      |
|                  |     |                  |     |                  |
+--------+---------+     +--------+---------+     +--------+---------+
         |                         |                         |
         v                         v                         v
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|   ClickHouse     |     |   ClickHouse     |     |   ClickHouse     |
|   Replicated     |     |   Sharded        |     |   MergeTree       |
|   Table          |     |   Cluster        |     |   Engine         |
|                  |     |                  |     |                  |
+--------+---------+     +--------+---------+     +--------+---------+
         |                         |                         |
         v                         v                         v
+------------------+     +------------------+     +------------------+
|                  |     |                  |     |                  |
|  HolySheep AI    |<----+  Grafana         |<----+  BI 대시보드     |
|  (예측/감성분류)  |     |  (모니터링)       |     |  (Superset)      |
|                  |     |                  |     |                  |
+------------------+     +------------------+     +------------------+

ClickHouse 테이블 설계

암호화폐 데이터의 특성을 고려한 스키마 설계는 查询 성능과 저장 효율성에 결정적입니다. 제가 실제 운영 중인 테이블 구조를 공유합니다.

-- 마켓 데이터 테이블 (메인 OHLCV)
CREATE TABLE crypto_data.ohlcv_minute
(
    timestamp DateTime64(3) CODEC(ZSTD(3)),
    symbol String CODEC(ZSTD(3)),
    interval_type Enum8('1m' = 1, '5m' = 2, '15m' = 3, '1h' = 4, '4h' = 5, '1d' = 6),
    open Decimal(20, 8),
    high Decimal(20, 8),
    low Decimal(20, 8),
    close Decimal(20, 8),
    volume Decimal(20, 8),
    quote_volume Decimal(20, 8),
    trade_count UInt32,
    taker_buy_volume Decimal(20, 8),
    exchange Enum8('binance' = 1, 'coinbase' = 2, 'kraken' = 3),
    created_at DateTime DEFAULT now()
)
ENGINE = MergeTree()
PARTITION BY (toYYYYMM(timestamp), exchange)
ORDER BY (symbol, interval_type, timestamp)
TTL timestamp + INTERVAL 2 YEAR
SETTINGS index_granularity = 8192;

-- 틱 데이터 테이블 (고빈도 거래)
CREATE TABLE crypto_data.trades
(
    timestamp DateTime64(3),
    symbol String,
    price Decimal(20, 8),
    quantity Decimal(20, 8),
    quote_quantity Decimal(20, 8),
    is_buyer_maker Bool,
    trade_id UInt64,
    exchange Enum8('binance' = 1, 'coinbase' = 2, 'kraken' = 3)
)
ENGINE = MergeTree()
ORDER BY (symbol, timestamp, trade_id)
PARTITION BY (toYYYYMM(timestamp), exchange);

-- 주문북 스냅샷 테이블
CREATE TABLE crypto_data.orderbook_snapshot
(
    timestamp DateTime64(3),
    symbol String,
    exchange Enum8('binance' = 1, 'coinbase' = 2, 'kraken' = 3),
    bids Array(Tuple(Decimal(20, 8), Decimal(20, 8))),
    asks Array(Tuple(Decimal(20, 8), Decimal(20, 8))),
    last_update_id UInt64
)
ENGINE = MergeTree()
ORDER BY (symbol, exchange, timestamp)
SAMPLE BY timestamp;

Binance API 데이터 수집기

실제 운영에서 제가 사용하는 Binance