פיתוח מערכת אחסון נתוני Tick
דמיינו שאתם מנתחים את שוק הקריפטו והאסטרטגיה שלכם דורשת גישה לכל עסקה בשנתיים האחרונות. ללא אחסון נתוני tick מתאים, זה בלתי אפשרי. אפילו צוותים מנוסים נתקלים בבעיות טיפוסיות: כתיבה איטית, עלויות אחסון גבוהות וקשיים באגרגציה. תכננו ופרסנו עשרות מערכות כאלה—מאבות טיפוס ועד התקנות production עם מיליארדי שורות. לאחרונה, market maker פנה אלינו כי PostgreSQL שלהם לא עמד בעומס: כתיבה ארכה מעל 5 שניות, ושאילתות ליום מסחר אחד ארכו דקות. לאחר מעבר ל-ClickHouse, זמן הכתיבה ירד ל-50 ms, ואגרגציה בזמן אמת אורכת שניות.
נפחי נתונים
כדי להבין את ההיקף: Binance על BTC/USDT מייצרת כ-50,000–200,000 עסקאות ביום. בכל הזוגות בכל הבורסות—מאות מיליוני רשומות ביום. שנה של נתונים משמעותה עשרות מיליארדי שורות. PostgreSQL רגיל לא יכול להתמודד עם זה ללא פתרונות מיוחדים.
אילו טכנולוגיות אחסון נתוני Tick לבחור?
| טכנולוגיה | סוג | דחיסה | ביצועי כתיבה | ביצועי קריאה | מקרה שימוש |
|---|---|---|---|---|---|
| ClickHouse | Columnar | 5–20x | ~10 מיליון שורות/שנייה (שרת יחיד) | אנליטיקה על מיליארדי שורות <1 שנייה | אחסון ראשי לנפחים גדולים |
| TimescaleDB | Relational (hypertables) | 2–5x | ~1 מיליון שורות/שנייה | אגרגציות על מיליוני שורות בשניות | עומסי עבודה היברידיים, נפחים בינוניים |
| Arctic (MongoDB) | Document | 1.5–2x | ~500,000 שורות/שנייה | ייצוא DataFrame | אבות טיפוס, פרויקטים קטנים |
ClickHouse הוא DBMS columnar מ-Yandex המותאם לשאילתות אנליטיות. הוא דוחס סדרות זמן טוב יותר ממתחרים ומריץ אגרגציות על מיליארדי שורות בשניות. טבלה המחולקת לפי בורסה וחודש נראית כך:
CREATE TABLE trades (
exchange LowCardinality(String),
symbol LowCardinality(String),
trade_id String,
timestamp DateTime64(3, 'UTC'),
price Decimal(24, 8),
quantity Decimal(24, 8),
side LowCardinality(String),
is_maker Bool
) ENGINE = MergeTree()
PARTITION BY (exchange, toYYYYMM(timestamp))
ORDER BY (exchange, symbol, timestamp)
SETTINGS index_granularity = 8192;CREATE TABLE trades ( exchange LowCardinality(String), symbol LowCardinality(String), trade_id String, timestamp DateTime64(3, 'UTC'), price Decimal(24, 8), quantity Decimal(24, 8), side LowCardinality(String), is_maker Bool ) ENGINE = MergeTree() PARTITION BY (exchange, toYYYYMM(timestamp)) ORDER BY (exchange, symbol, timestamp) SETTINGS index_granularity = 8192; עבור מחרוזות עם ערכים ייחודיים מעטים—קידוד מילון אוטומטי חוסך מקום משמעותי.
TimescaleDB הוא בחירה טובה אם אתם כבר משתמשים ב-PostgreSQL ויש לכם נפחים בינוניים (<1 מיליארד שורות). הוא תומך ב-hypertables ובמדיניות דחיסה.
Arctic הוא פתרון ייעודי לסדרות זמן פיננסיות ב-Python, עם versioning ותמיכה בנתוני tick.
כיצד אנו מתכננים את צינור הקליטה
לביצועי כתיבה מקסימליים, אנו משתמשים בטבלת buffer:
-- Буфер: накапливает данные в памяти, сбрасывает каждые 10 сек или 1M строк
CREATE TABLE trades_buffer AS trades ENGINE = Buffer(currentDatabase(), 'trades', 16, 10, 100, 10000, 1000000, 10000000, 100000000);
-- Записываем в буфер, читаем из основной таблицы
INSERT INTO trades_buffer VALUES (...);
SELECT * FROM trades WHERE ...;צינור Python עם buffering אסינכרוני:
import asyncio
from collections import deque
class TickDataIngester:
BATCH_SIZE = 10000
FLUSH_INTERVAL = 5.0 # seconds
def __init__(self, clickhouse_client):
self.buffer = deque()
self.client = clickhouse_client
async def on_trade(self, trade: NormalizedTrade):
self.buffer.append(trade)
if len(self.buffer) >= self.BATCH_SIZE:
await self.flush()
async def flush(self):
if not self.buffer:
return
batch = [self.buffer.popleft() for _ in range(min(self.BATCH_SIZE, len(self.buffer)))]
await self.client.insert('trades_buffer', batch)
async def flush_loop(self):
while True:
await asyncio.sleep(self.FLUSH_INTERVAL)
await self.flush()
כיצד לאגד נתוני Tick לנרות OHLCV
אגרגציה בזמן אמת באמצעות פונקציות חלון של ClickHouse:
SELECT toStartOfInterval(timestamp, INTERVAL 1 MINUTE) AS candle_time,
argMin(price, timestamp) AS open,
max(price) AS high,
min(price) AS low,
argMax(price, timestamp) AS close,
sum(quantity) AS volume,
count() AS trade_count
FROM trades
WHERE exchange = 'binance'
AND symbol = 'BTC/USDT'
AND timestamp BETWEEN '2023-01-01' AND '2023-01-02'
GROUP BY candle_time
ORDER BY candle_time;ב-ClickHouse, שאילתה זו על 50 מיליון שורות מתבצעת ב-1–3 שניות. גישה חלופית היא materialized views שמחשבות נרות מראש בעת הכנסה. השוואה:
| גישה | זמן השהיית שאילתה | עומס כתיבה | גמישות |
|---|---|---|---|
| בזמן אמת | שניות | ללא | מקסימלית (כל מרווח) |
| Materialized view | מילישניות | בינוני (MergeTree נוסף) | מרווח קבוע |
הבחירה תלויה בתרחיש: לאנליטיקה ad-hoc השתמשו בזמן אמת, ללוחות מחוונים בזמן אמת השתמשו ב-materialized views.
דחיסה ושמירה
ClickHouse דוחס נתונים אוטומטית. בנוסף, אנו מאפשרים אחסון קר באמצעות TTL:
ALTER TABLE trades MODIFY TTL timestamp + INTERVAL 1 YEAR TO DISK 'cold_storage'; נתונים ישנים משנה מועברים אוטומטית לאחסון זול יותר (תואם S3).
מילוי נתונים היסטוריים
למילוי נתונים היסטוריים, אנו משתמשים ב-API ציבורי של בורסות. Binance מספקת היסטוריית עסקאות דרך LowCardinality עם pagination לפי -- Буфер: накапливает данные в памяти, сбрасывает каждые 10 сек или 1M строк CREATE TABLE trades_buffer AS trades ENGINE = Buffer(currentDatabase(), 'trades', 16, 10, 100, 10000, 1000000, 10000000, 100000000); -- Записываем в буфер, читаем из основной таблицы INSERT INTO trades_buffer VALUES (...); SELECT * FROM trades WHERE ...; . מילוי מקביל על פני טווחי זמן עם rate limiting טוען שנים של נתונים בכמה שעות.
מה כלול בעבודה (תוצרים)
- תיעוד ארכיטקטוני: בחירת DBMS, תכנית חלוקה, מדיניות שמירה ודחיסה
- פיתוח צינור קליטה: buffering, deduplication, ניטור זמן השהיה
- אינטגרציית מקורות: WebSocket של בורסה, REST API, Kafka
- הגדרת ClickHouse/TimescaleDB המותאמת לפרופיל החומרה שלכם
- בדיקות עומס: סימולציית עומסי שיא עד 1 מיליון רשומות בשנייה
- תיעוד תפעולי: גיבוי/שחזור, שדרוג, ניטור
- אחריות: 30 ימי תמיכה לאחר השקה וטיפול בתקלות
בקשו ייעוץ חינם—ננתח את עומס העבודה שלכם ונציע ארכיטקטורה אופטימלית.
למה לבחור בנו?
יש לנו 5+ שנות ניסיון בפיתוח מערכות אחסון נתונים לבורסות קריפטו. השלמנו מעל 30 פרויקטים עם נפח נתונים כולל העולה על 100 מיליארד רשומות. הלקוחות שלנו נעים מסטארטאפים ועד market makers גדולים. אנו מבטיחים שהמערכת תפעל כפי שצוין ולא תתדרדר תחת נפחים גדלים.
לוח זמנים ועלות
לוח זמנים לפיתוח: מ-4 עד 12 שבועות תלוי במורכבות ובנפח. העלות מחושבת באופן אישי לפי נפח נתונים, מספר מקורות ודרישות זמן השהיה. צרו קשר כדי לקבל גישת demo למערכת עובדת תחת העומס שלכם—נבצע הערכה מקדימה ונציע פתרון.







