Skip to content

[Spark] Evaluate the FileFormat rewrite (vortex-data/vortex#9658) against our findings #31

Open

Description

@gitRasheed

Tracking our evaluation of the Spark FileFormat rewrite, vortex-data#9658, on branch rasheed/spark-fileformat (vortex-data#9658 plus our fixes). The current connector is replaced wholesale by vortex-data#9658, so instead of fixing it further, we check each problem we found against vortex-data#9658 and fix what it still gets wrong on this branch, to send upstream as comments or commits on vortex-data#9658.

Baseline (9a9afba66): vortex-data#9658's tests didn't compile (a missing import java.util.List, fixed). With that, 1007 tests pass across Spark 3.5/2.12, 3.5/2.13, 4.0, and the 4.1 and 4.2 compat runs, except the two S3 mock tests in each: S3AFileSystem not found, since vortex-data#9658 reads through Hadoop's filesystem and the tests don't put hadoop-aws on the classpath.

Finding Current connector Under vortex-data#9658
#2 one task per file fixed by #8 (opt-in splitting) to check
#3 row copies on write fixed by #7 to check
#4 string reads copied each value fixed by #6 to check
#9, #16 nested schema pruning, struct fields in arrays #10; #16 blocked to check
#19 count(*) decoded every column PR #19 to check
#20 sidecar files broke reads PR #20 to check
#21 partition directory names, encoding draft PR #24 to check
#22 failed attempts' files duplicated rows PR #22 to check
#26 dynamic overwrite deleted every partition open to check
#27 files at final paths before job commit open to check
#28 date/timestamp partitions as epoch counts open to check
#29 native workers attach as non-daemon threads open to check
#30 appends from separate applications collide fix ready, not pushed to check
#18 schema export leak in VortexWriter.build() PR #18 to check
#23 no native worker threads on writes PR #23 to check
#25 Kryo without a registrator PR #25 to check
Nested path two levels below a nullable struct vortex-data#10952 (native) to check
Timestamps beyond jiff's range vortex-data#10953 (native) to check

Results will be filled in per area: write lifecycle, partition layout, reads, write performance, and configuration/ops.

Activity

  1. gitRasheed commented on Oct 29, 2026

    @gitRasheed
    CollaboratorAuthor

    Results for write lifecycle (A) and partition layout (B). Astra wrote each scenario as a JUnit test through the DataFrame API and SQL, on Spark 4.0.4 and 4.2.0 (B also 4.1.2). The tests are kept on the evaluation worktrees and will go onto rasheed/spark-fileformat as regression tests.

    vortex-data#9658 fixes:

    Still broken, and the same with Parquet (Spark's FileOutputCommitter, not Vortex):

    • A driver killed mid-job leaves its committed tasks under _temporary/0, and the next append publishes them: 257 rows instead of 129.
    • A job commit that fails halfway leaves the partitions it already published.
    • With committer algorithm 2, a failed job keeps the files of tasks that finished.
    • Timestamps with six-digit fractions infer as strings; reading with an explicit schema works.
    • A percent-encoded URI root (file:///tmp/a%20b) is taken literally, as Spark does for Parquet.

    Only matters for data written by the current connector: old p=with+space, p=C%C3%B4te and epoch-count date partitions read differently. Nobody has production Vortex tables yet, so I don't think this needs a migration path.

    Conclusion: for #20, #21, #22, #26, #27, #28 and #30, fixing the current connector is wasted once vortex-data#9658 lands. Open questions now are reads (C), write performance (D) and configuration/ops (E), which are running.

  2. gitRasheed commented on Oct 29, 2026

    @gitRasheed
    CollaboratorAuthor

    Results for reads (C) and configuration/ops (E). C ran on Spark 4.0.4; E ran on 3.5.9 (Scala 2.12 and 2.13), 4.0.4, 4.1.2 and 4.2.0 with the same results on each.

    Fixed by vortex-data#9658: count(*) reads only footers (#19); float filters with NaN and signed zero match Spark; Kryo with registrationRequired works (#25); mixed-case options are recognized; catalog SQL (CREATE TABLE, INSERT, INSERT OVERWRITE, saveAsTable, CTAS) works; S3 works once hadoop-aws is on the classpath.

    Fork features vortex-data#9658 drops:

    Still broken:

    So vortex-data#9658 is the right base, but it loses the three read optimizations the fork added. Next step: port them, plus the fixes above, as PRs into rasheed/spark-fileformat.

  3. gitRasheed commented on Oct 29, 2026

    @gitRasheed
    CollaboratorAuthor

    Results for write performance and resources (D), Spark 4.0.4, local[4], 4M rows, median of three rounds (shared machine, so directional).

    Shape Old connector, 4 tasks / 1 task vortex-data#9658, 4 tasks / 1 task
    6 columns, 4 workers 11.3 s / 17.4 s 11.9 s / 21.5 s
    nested, 4 workers 14.5 s / 20.7 s 15.1 s / 22.5 s
    100 columns, 4 workers 130.9 s / 154.6 s 123.2 s / 158.1 s

    Fixed by vortex-data#9658: writes configure the native worker pool (default 4), so #23 isn't needed there.

    Regressed:

    • Row copies are back: VortexOutputWriter calls row.copy() into a list and converts per value, which perf(spark): append rows straight into the Arrow batch #7 removed on the fork.
    • Every batch exports the Arrow schema and never releases it: 1,728 bytes after a five-batch write, and 2,400 leaked allocators (4.2 MB) across three jobs of small partitioned writers. The allocator-close failure is swallowed (VortexOutputWriter.java:372-376). Repeated 100-column writes ran out of a 1 GiB heap in round two, where the old connector finished all three; the leak is the likely cause, not yet confirmed.
    • The JVM doesn't exit after a default write: Vortex spark integration is a fileformat not a tableprovider vortex-data/vortex#9658 writes through Java streams (HadoopWritable), so native workers make Java upcalls and attach as non-daemon threads ([JNI] Native workers attach as non-daemon JVM threads #29). main returned after spark.stop(), and the JVM was still alive at 45 seconds. With zero workers it exits.

    Still broken:

    Next on rasheed/spark-fileformat: port #7's direct Arrow writers with a single schema export per writer, and fix #29.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions