Розробка системи зберігання tick-даних
Уявіть: ви аналізуєте ринок криптовалют, і ваша стратегія потребує доступу до кожного трейду за останні два роки. Без правильного зберігання tick-даних це неможливо. Між тим навіть досвідчені команди стикаються з типовими проблемами: повільний запис, високі витрати на зберігання, складнощі з агрегацією. Ми спроектували та впровадили десятки подібних систем — від прототипів до продакшен-інсталяцій з мільярдами рядків. Нещодавно до нас звернувся маркет-мейкер, у якого PostgreSQL не справлявся з навантаженням: запис займав більше 5 секунд, а запити по одному дню торгівлі виконувалися хвилинами. Після міграції на ClickHouse latency запису впала до 50 мс, а агрегація на льоту стала займати секунди.
Обсяги даних
Щоб зрозуміти масштаб завдання: Binance по BTC/USDT генерує порядка 50,000–200,000 трейдів на добу. По всіх парах на всіх біржах — сотні мільйонів записів на день. Рік даних — десятки мільярдів рядків. Звичайний PostgreSQL з цим не впорається без спеціальних рішень.
Які технології зберігання tick-даних обрати?
| Технологія | Тип | Стиснення | Продуктивність запису | Продуктивність читання | Сценарій використання |
|---|---|---|---|---|---|
| ClickHouse | Колонкова | 5–20x | ~10 млн рядків/с (на одному сервері) | Аналітика по мільярдах рядків <1 сек | Основне сховище для великих обсягів |
| TimescaleDB | Реляційна (гіпертаблиці) | 2–5x | ~1 млн рядків/с | Агрегації по мільйонах рядків за секунди | Гібридні навантаження, помірні обсяги |
| Arctic (MongoDB) | Документна | 1.5–2x | ~500 тис. рядків/с | Вивантаження DataFrame | Прототипування, невеликі проекти |
ClickHouse — колонкова СУБД від 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; LowCardinality для рядків з невеликою кількістю унікальних значень — автоматичний dictionary encoding дає значну економію місця.
TimescaleDB — якщо вже використовуєте PostgreSQL і обсяги помірні (< 1 млрд рядків). Підтримує hypertables та compression policies.
Arctic — спеціалізоване рішення для фінансових часових рядів на Python, з версіонуванням та підтримкою tick-даних.
Як ми проектуємо Ingestion Pipeline?
Для максимальної продуктивності запису використовуємо буферну таблицю:
-- Буфер: накопичує дані в пам’яті, скидає кожні 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 ...; Pipeline на Python з асинхронним буферизованням:
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 цей запит по 50M рядків виконується за 1–3 секунди. Альтернативний підхід — матеріалізовані представлення, які попередньо розраховують свічки при вставці. Порівняємо обидва методи:
| Підхід | Latency запиту | Навантаження на запис | Гнучкість |
|---|---|---|---|
| On-the-fly | Секунди | Немає | Максимальна (будь-який інтервал) |
| Materialized view | Мілісекунди | Помірна (додатковий MergeTree) | Фіксований інтервал |
Вибір залежить від сценарію: для ad-hoc аналітики — on-the-fly, для дашбордів реального часу — materialized view.
Компресія та retention
ClickHouse стискає дані автоматично. Додатково вмикаємо cold storage через TTL:
ALTER TABLE trades MODIFY TTL timestamp + INTERVAL 1 YEAR TO DISK 'cold_storage'; Дані старше року автоматично переносяться на дешевше сховище (S3-сумісне).
Бекфілл історичних даних
Для заповнення історичних даних використовуємо публічні API бірж. Binance надає trade history через /api/v3/aggTrades з пагінацією по fromId. Паралельний backfill за часовими діапазонами з rate limiting дозволяє завантажити роки даних за кілька годин.
Що входить в роботу (deliverables)
- Архітектурна документація: вибір СУБД, схема партиціонування, політика retention та стиснення
- Розробка ingestion pipeline: буферизація, дедуплікація, моніторинг затримок
- Інтеграція з джерелами: WebSocket бірж, REST API, Kafka
- Конфігурація ClickHouse/TimescaleDB під ваш hardware профіль
- Навантажувальне тестування: симуляція пікових навантажень до 1 млн записів/с
- Документація з експлуатації: backup/restore, upgrade, моніторинг
- Гарантія: 30 днів post-launch підтримки та усунення інцидентів
Залиште заявку на безкоштовну консультацію — ми проаналізуємо ваше навантаження та запропонуємо оптимальну архітектуру.
Чому нас обирають?
Ми маємо 5+ років досвіду в розробці систем зберігання даних для криптовалютних бірж. Реалізували понад 30 проектів із загальним обсягом даних понад 100 мільярдів записів. Наші клієнти — від стартапів до великих маркет-мейкерів. Ми гарантуємо, що система працюватиме із заявленою продуктивністю і не «просяде» під ростом обсягів.
Строки та вартість
Термін розробки — від 4 до 12 тижнів залежно від складності та обсягів. Вартість розраховується індивідуально на основі оцінки обсягу даних, кількості джерел та вимог до затримок. Зв'яжіться з нами, щоб отримати demo-доступ до працюючої системи під ваше навантаження — ми проведемо попередню оцінку та запропонуємо рішення.







