Выбор стратегии распределения
Мы разобрали три подхода к распределению DataFusion: Ballista (уроки 2–3), DataFusion Ray (урок 4) и Comet (модуль 7). Каждый решает свою задачу. В этом уроке — матрица сравнения, дерево решений и реальные примеры кастомного распределения поверх DataFusion как библиотеки.
Три подхода: обзор
Ключевое различие: Ballista и DataFusion Ray — самостоятельные распределённые системы, выполняющие DataFusion-запросы. Comet — ускоритель внутри Spark, а не замена его распределённой модели.
Матрица сравнения
| Критерий | Ballista | DataFusion Ray | Comet |
|---|---|---|---|
| Язык | Rust | Python + Rust | Scala/Java + Rust |
| Требует | Собственный кластер | Ray-кластер | Spark-кластер |
| API | DataFusion SQL/DataFrame | DataFusion Python SQL | Spark SQL/DataFrame |
| Расширяемость | TableProvider, UDF, ExtensionPlanner | Через DataFusion Python API | Ограничена Spark plugin API |
| Отказоустойчивость | Task retry через scheduler | Ray retry (ограничен) | Spark retry (зрелый) |
| Производительность | 2.9x vs Spark (TPC-H) | Не бенчмаркировано | 2.2x vs Spark (TPC-H) |
| Сценарий | Новая аналитическая система | SQL в ML-пайплайне | Ускорение Spark без миграции |
Дерево решений
target_partitions = N ядерОднопроцессный DataFusion: target_partitions = N ядер, spill-to-disk для больших join/sort
Zero-change ускорение SparkComet: подключается как Spark-плагин, zero code changes, 2.2x ускорение на аналитике
или кастомное решениеBallista для готовой системы или кастомное решение (DataFusion как библиотека) для специфических требований
(ранняя стадия)DataFusion Ray: ранняя стадия, подходит для экспериментов в существующем Ray-кластере
Выбирайте Comet, если:
- У вас уже есть Spark-кластер с рабочими пайплайнами
- Нужно ускорение без переписывания приложений
- Нагрузки — аналитические запросы по Parquet/Iceberg
- Не готовы мигрировать на новую платформу
Выбирайте Ballista, если:
- Строите новую аналитическую систему с нуля
- Команда работает в Rust-экосистеме
- Нужен полный контроль над расширениями (TableProvider, UDF, OptimizerRule)
- Требуется Flight SQL/JDBC доступ для BI-инструментов
Выбирайте DataFusion Ray, если:
- В организации уже есть Ray-кластер
- Команда работает в Python-экосистеме
- SQL-аналитика — часть ML-пайплайна
- Готовы принять ограничения ранней стадии проекта
Четвёртый путь: DataFusion как библиотека
Ballista, DataFusion Ray и Comet — готовые решения. Но DataFusion изначально проектировался как библиотека для встраивания. Многие production-системы строят собственное распределение, используя DataFusion как query engine внутри каждого узла.
Spice AI
Spice AI — федеративный аналитический движок. DataFusion обрабатывает запросы на каждом узле, а Spice AI координирует маршрутизацию и pushdown к удалённым источникам (PostgreSQL, MySQL, DuckDB, S3, Databricks). Подробнее — в уроке по паттернам расширяемости.
Ключевая точка расширения: кастомные TableProvider для каждого источника + OptimizerRule для federation-aware планирования.
InfluxDB IOx
InfluxDB IOx (основа InfluxDB 3.0) использует DataFusion как query engine, но хранит данные в собственном columnar формате, распределённом по шардам. Каждый узел выполняет DataFusion-запрос над своим фрагментом данных, а координатор собирает результаты.
Ключевая точка расширения: кастомный TableProvider для доступа к внутреннему хранилищу + кастомные PhysicalOptimizerRule для time-series оптимизаций (деталь — дедупликация через DeduplicateExec).
GreptimeDB
GreptimeDB — мультимодальная time-series СУБД, объединяющая метрики, логи и события. Как и InfluxDB IOx, использует DataFusion для SQL, но распределяет выполнение по собственной архитектуре.
Ключевая точка расширения: ExtensionPlanner для планирования распределённого выполнения — тот же механизм, который используется для кастомных ExecutionPlan.
Общий паттерн
Все три системы следуют одной модели:
Этот подход требует больше работы (свой coordinator, свой протокол shuffle), но даёт полный контроль над семантикой распределения. DataFusion предоставляет query planning, оптимизацию и выполнение на каждом узле — распределение и координация остаются за вами.
Выбирайте кастомное решение, если:
- Данные уже шардированы по вашей логике
- Требуется специфическая семантика (time-series дедупликация, federation pushdown)
- Нужна интеграция с собственным хранилищем и протоколами
- Готовы инвестировать в инфраструктурную разработку
Что объединяет все подходы
Независимо от стратегии распределения — Ballista, DataFusion Ray, Comet или кастомное решение — все они строятся на одних и тех же примитивах DataFusion:
- ExecutionPlan — единица выполнения. Каждый stage — это DataFusion ExecutionPlan
- Partitioning — партиционная модель определяет степень параллелизма и точки shuffle
- EnforceDistribution/EnforceSorting — физические правила (М06 урок 5) вставляют RepartitionExec, который становится границей stage
- Arrow — columnar формат для данных в памяти и на диске (Arrow IPC для shuffle)
- SessionContext — единый API для планирования и выполнения
DataFusion не предписывает, как распределять выполнение. Он предоставляет примитивы, из которых можно построить любую распределённую архитектуру — от простого scatter-gather до полноценного DAG scheduler.
Ключевые выводы
- Ballista — Rust-нативная система со scheduler/executor, production-ориентирована, 2.9x vs Spark, собственный кластер
- DataFusion Ray — Python-first, ранняя стадия, имеет смысл при наличии Ray-кластера
- Comet — ускоритель существующего Spark, не самостоятельная распределённая система
- Кастомные решения (InfluxDB IOx, GreptimeDB, Spice AI) — DataFusion как библиотека внутри каждого узла
- Все подходы строятся на одних примитивах: ExecutionPlan, партиционирование, Arrow, SessionContext
- Выбор зависит от: существующей инфраструктуры (Spark / Ray / свой стек), языка (Rust / Python / JVM), уровня контроля и зрелости проекта