You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Spark] Evaluate the FileFormat rewrite (vortex-data/vortex#9658) against our findings #31
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.
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.
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.
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.
vortex.* settings in the Spark session conf are ignored.
Malformed batch.size or session-provider values fail on executors after overwrite has deleted the old files; out-of-range batch sizes fall back to the default silently.
The S3 mock tests fail: no hadoop-aws on the test classpath. Deployments need it too, and that should be documented.
The docs list Spark 4.0 and 4.1 only; 4.2 passes the same tests.
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.
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.
Activity
gitRasheed commentedon Oct 29, 2026
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-fileformatas regression tests.vortex-data#9658 fixes:
Côte. Failed partition closes and task commits leave no files..save()and SQLINSERT OVERWRITE._SUCCESS._SUCCESS,.crc,_temporary/0/...,.hiddenand_metadataare ignored.Still broken, and the same with Parquet (Spark's
FileOutputCommitter, not Vortex):_temporary/0, and the next append publishes them: 257 rows instead of 129.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%B4teand 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.
gitRasheed commentedon Oct 29, 2026
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 withregistrationRequiredworks (#25); mixed-case options are recognized; catalog SQL (CREATE TABLE,INSERT,INSERT OVERWRITE,saveAsTable, CTAS) works; S3 works oncehadoop-awsis on the classpath.Fork features vortex-data#9658 drops:
s.aors.t.x.qreads all ofs, 10.8 MB either way.VortexScanBuilderleaves nested pruning off, andVortexPartitionReaderprojects top-level names only.isSplitablereturns false, so two 3.6 MB files withmaxPartitionBytes=1 MiBgive 2 partitions, andvortex.read.splitFilesis ignored.StringViewAccessorstill copies every value (UTF8String.fromBytes).VortexTable.scala:85merges case-sensitive maps first, so the winner depends on iteration order.Still broken:
vortex.*settings in the Spark session conf are ignored.batch.sizeor session-provider values fail on executors after overwrite has deleted the old files; out-of-range batch sizes fall back to the default silently.hadoop-awson the test classpath. Deployments need it too, and that should be documented.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.gitRasheed commentedon Oct 29, 2026
Results for write performance and resources (D), Spark 4.0.4,
local[4], 4M rows, median of three rounds (shared machine, so directional).Fixed by vortex-data#9658: writes configure the native worker pool (default 4), so #23 isn't needed there.
Regressed:
VortexOutputWritercallsrow.copy()into a list and converts per value, which perf(spark): append rows straight into the Arrow batch #7 removed on the fork.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.HadoopWritable), so native workers make Java upcalls and attach as non-daemon threads ([JNI] Native workers attach as non-daemon JVM threads #29).mainreturned afterspark.stop(), and the JVM was still alive at 45 seconds. With zero workers it exits.Still broken:
VortexWriter.build()(fix(jni): release the schema export in VortexWriter.build() #18), 288 bytes per writer; fixed by fix: native fixes the FileFormat connector needs (nested over-read, timestamp range, schema export leak) #34.Next on
rasheed/spark-fileformat: port #7's direct Arrow writers with a single schema export per writer, and fix #29.