Экосистема Arrow: реализации, ADBC и cross-language мир
Одна спецификация — множество реализаций
Apache Arrow — это спецификация, а не библиотека. Byte layout определён раз и навсегда; каждый язык реализует работу с этим layout самостоятельно. С 2024 года языковые реализации живут в отдельных репозиториях:
| Реализация | Язык | Репозиторий | Версия (март 2026) |
|---|---|---|---|
| arrow-rs | Rust | apache/arrow-rs | 55.x (отдельная нумерация) |
| PyArrow | Python (C++ backend) | apache/arrow | 23.0.1 |
| Arrow C++ | C++ | apache/arrow | 23.0.1 |
| Arrow Java | Java | apache/arrow-java | отдельная нумерация |
| Arrow Go | Go | apache/arrow-go | отдельная нумерация |
| Arrow Julia | Julia | apache/arrow-julia | отдельная нумерация |
Версия 23.0.1 — это версия основного apache/arrow репозитория (C++, Python, R, C#, JavaScript). Rust-реализация arrow-rs имеет собственную нумерацию и выпускается каждые 2 недели. DataFusion зависит от arrow-rs, а не от основного Arrow.
arrow-rs: Rust-реализация
arrow-rs — основная зависимость DataFusion. Это чистая Rust-реализация без FFI-вызовов в C++. Ключевые crates:
Модульная структура позволяет зависеть только от нужных crates. DataFusion использует arrow-array, arrow-schema, arrow-select, arrow-compute и parquet — но не arrow-csv или arrow-json напрямую.
Отличия arrow-rs от Arrow C++
| Аспект | arrow-rs | Arrow C++ |
|---|---|---|
| Memory safety | Гарантирована Rust borrow checker | Ручное управление, ASAN в тестах |
| Release cycle | Каждые 2 недели | Каждые 3 месяца (с C++/Python) |
| Async I/O | Нативный (tokio) | callback-based |
| SIMD | Авто-векторизация LLVM | Явные интринсики + авто |
| Зависимости | Минимальные (чистый Rust) | Тяжёлые (CMake, Boost, gRPC, protobuf) |
PyArrow: Python-мост
PyArrow — Python-обёртка над Arrow C++ реализацией. Это основной способ работы с Arrow в Python:
import pyarrow as pa
# Создание таблицы
table = pa.table({
"id": [1, 2, 3],
"name": ["Иван", "Мария", "Пётр"],
"salary": [80000, 95000, None],
})
# Конвертация в Pandas (zero-copy для числовых колонок)
df = table.to_pandas()
# Чтение Parquet (через Arrow C++ Parquet reader)
table = pa.parquet.read_table("data.parquet")
PyArrow интегрируется с:
- Pandas —
to_pandas()/from_pandas()(ArrowDtype в Pandas 2.0+) - Polars — нативный Arrow backend, zero-copy обмен с PyArrow
- DuckDB — прямой обмен Arrow-буферами без копирования
- DataFusion Python — Python-биндинги DataFusion работают с PyArrow таблицами
DataFusion Python (datafusion pip package) принимает PyArrow таблицы на вход и возвращает PyArrow на выход. Переход между DataFusion и Pandas/Polars — одна строка кода через PyArrow как промежуточный формат.
Arrow Java: JVM-мир
Arrow Java — отдельный репозиторий (apache/arrow-java). Основные потребители:
- Apache Spark — использует Arrow для обмена данных с Python (PySpark
toPandas()), Spark Connect - Apache Flink — Arrow для Python UDF
- Dremio — Arrow-нативный query engine на JVM
Arrow Java использует off-heap память (DirectByteBuffer), что позволяет избежать GC-пауз при обработке больших объёмов данных. Однако это требует явного управления lifecycle буферов (allocator.close()).
ADBC: Arrow Database Connectivity
ADBC (Arrow Database Connectivity) — новый стандарт интерфейса к базам данных, проектированный вокруг Arrow:
ADBC определяет C API, который драйверы реализуют. Доступны драйверы для PostgreSQL, SQLite, Flight SQL и DuckDB. Python-пакет adbc-driver-* позволяет получать результаты запросов сразу как PyArrow таблицы.
import adbc_driver_postgresql.dbapi
# ADBC: результат — сразу Arrow, без промежуточного ResultSet
with adbc_driver_postgresql.dbapi.connect("postgresql://...") as conn:
with conn.cursor() as cur:
cur.execute("SELECT * FROM events")
table = cur.fetch_arrow_table() # PyArrow Table напрямую
nanoarrow: минимальная реализация
nanoarrow — облегчённая C-библиотека для чтения/записи Arrow-данных. Нет зависимостей, ~100 KB кода. Предназначена для встраиваемых систем и языковых биндингов, где полный Arrow C++ слишком тяжёл.
nanoarrow реализует:
- Arrow C Data Interface (обмен данными между языками через C ABI)
- Arrow C Stream Interface (потоковый обмен)
- Базовые операции создания и чтения массивов
Используется как FFI-мост: Python-расширение на C может получить Arrow-данные из PyArrow через C Data Interface, обработать через nanoarrow и вернуть результат без копирования.
DataFusion в экосистеме Arrow
DataFusion занимает уникальную позицию: это не просто потребитель Arrow, а query engine, построенный на Arrow с первого дня.
Каждый оператор DataFusion принимает RecordBatch и возвращает RecordBatch. Нет промежуточных форматов, нет конвертации. Вычислительные ядра (arrow-compute) используются напрямую для filter, cast, math операций.
Это даёт DataFusion преимущество перед движками, которые добавляли Arrow-поддержку позже (Spark, Presto): нет legacy-слоёв конвертации.
Итоги
- Arrow — спецификация; arrow-rs, PyArrow, Arrow Java — реализации
- arrow-rs — чистая Rust-реализация, основная зависимость DataFusion
- PyArrow — мост между Arrow и Python-экосистемой (Pandas, Polars, DuckDB)
- ADBC — новый стандарт доступа к БД с нативным Arrow, замена JDBC/ODBC
- nanoarrow — минимальная C-реализация для FFI и встраиваемых систем
- DataFusion — Arrow-native query engine без legacy-слоёв конвертации