For the complete documentation index, see llms.txt. This page is also available as Markdown.

Apache Arrow

Apache Arrow integration in DataVec — ArrowRecordReader and zero-copy data exchange

Apache Arrow is an in-memory columnar data format designed for high-performance analytics. It defines a standard binary layout for batches of typed columnar data that enables zero-copy reads between systems — no serialization or deserialization overhead when passing data between a DataVec pipeline and an Arrow-aware consumer.

DataVec's Arrow integration lets you use Arrow-formatted data as input to record readers and as an exchange format for large batch operations.

What Arrow Provides

Traditional row-oriented formats (like Java ArrayList<Map<String,Object>>) scatter each record's fields across memory. Arrow lays out each column's values contiguously in memory:

Row-oriented:    [row0_col0, row0_col1, row0_col2], [row1_col0, row1_col1, row1_col2], ...
Column-oriented: [row0_col0, row1_col0, row2_col0, ...], [row0_col1, row1_col1, row2_col1, ...]

Columnar layout enables:

  • Vectorized computation: apply an operation to an entire column using SIMD CPU instructions

  • Better compression: repeated values and similar values are adjacent, compressing well

  • Zero-copy sharing: share data between JVM and native code (Python, C++) without copying

  • Selective column reads: read only the columns you need without deserializing the rest

Arrow is used by Apache Spark (Spark's vectorized execution engine uses Arrow internally), Pandas (via PyArrow), Apache Parquet (Arrow as the in-memory representation after Parquet deserialization), and many other data tools.

ArrowRecordReader

ArrowRecordReader reads Arrow-formatted data and produces List<Writable> records compatible with the rest of the DataVec pipeline.

import org.datavec.arrow.recordreader.ArrowRecordReader;

ArrowRecordReader reader = new ArrowRecordReader();
reader.initialize(new FileSplit(new File("/data/batch.arrow")));

while (reader.hasNext()) {
    List<Writable> record = reader.next();
    // use the record
}

Arrow files can be created by Python (via PyArrow), Spark (via df.write.format("arrow")), or any Arrow IPC writer. The Arrow IPC file format (sometimes called "Feather v2") is the standard format for on-disk Arrow data.

ArrowWritableRecordBatch

ArrowWritableRecordBatch is a List<List<Writable>> backed directly by Arrow columnar memory. It provides zero-copy access to Arrow batches — individual Writable values are read directly from the Arrow buffer without copying into Java heap objects.

This is particularly useful when processing large batches where copying each value would be expensive. The batch holds a reference to the underlying Arrow buffers; individual Writable objects returned from batch.get(i).get(j) read directly from those buffers.

Converting Between Arrow and DataVec

From Arrow VectorSchemaRoot to List<List>

From List<List> to Arrow

This conversion enables sending DataVec-processed data to Arrow-compatible consumers (Python via IPC, Spark, etc.) without an intermediate CSV or JSON step.

Use Cases

High-Performance Batch Loading

When loading large pre-processed datasets for repeated training epochs, Arrow's columnar format allows reading an entire column in a single contiguous memory region, which is much faster than reading individual records from CSV.

Python-Java Interoperability

If your data preparation runs in Python (feature engineering in Pandas, image preprocessing, NLP tokenization), you can write Arrow format from Python and read it in DataVec without going through CSV:

Python side:

Java side:

Spark to DataVec

Spark's Arrow-based Pandas UDFs and the spark.createDataFrame path can produce Arrow IPC files. These can be read directly by ArrowRecordReader for local fine-tuning or evaluation after Spark-based feature engineering.

Type Mapping

Arrow types map to DataVec Writable types as follows:

Arrow Type
DataVec Writable

Int8, Int16, Int32

IntWritable

Int64

LongWritable

Float32

FloatWritable

Float64

DoubleWritable

Utf8 (string)

Text

Bool

BooleanWritable

FixedSizeBinary, Binary

BytesWritable

FixedSizeList / Tensor

NDArrayWritable

Null

NullWritable

Memory Management

Arrow allocates memory outside the JVM heap using BufferAllocator. Always close Arrow resources when done to avoid native memory leaks:

ArrowRecordReader manages its own allocator internally and releases memory when close() is called. Always call reader.close() (or use try-with-resources) when done reading.

Last updated

Was this helpful?