perf(vindex): parallelize Parquet reads and multipart index uploads - #736
Draft
jerry-024 wants to merge 17 commits into
Draft
perf(vindex): parallelize Parquet reads and multipart index uploads#736jerry-024 wants to merge 17 commits into
jerry-024 wants to merge 17 commits into
Conversation
The default_training_vector_count call was only used to populate a timing log field, but it ran unconditionally and propagated errors, introducing a new build failure path even when timing diagnostics were disabled. Compute it only when timing is enabled and fall back to 0 on error instead of failing the build. Co-Authored-By: Claude <noreply@anthropic.com>
The vector index (~2 GB) is serialized as a sequential stream into an opendal writer that uploads its 8 MiB multipart chunks strictly one at a time -- ~244 serial round trips per index on object storage. Add async_writer_with_concurrency and let the index upload keep 4 parts in flight (32 MiB buffer), overlapping serialization with uploads. Parquet and other async_writer users keep the previous serial behavior.
jerry-024
marked this pull request as draft
August 21, 2026 02:18
* main: perf: vectorize raw vector search (apache#734) feat(file_index): add predicate evaluation foundation (apache#721) feat(go): add postpone fixed-bucket write bindings (apache#722) perf(vindex): split build timing logs by phase (apache#723) fix(avro): read TIME, BLOB, MULTISET and non-string-key map columns (apache#724) fix(datafusion): surface tag create-time and retention in $tags (apache#728) [core] Support multivalue global index (apache#731) feat: add Java-compatible array predicate pushdown (apache#732) fix: serialize unbounded varchar as string (apache#730) perf(vindex): decouple vector read threads and remove chunk barrier (apache#720) feat(vindex): add DiskANN and IVF-SQ/RQ support (apache#726) # Conflicts: # crates/paimon/src/table/data_file_reader.rs # crates/paimon/src/table/vindex_index_build_builder.rs
A row group whose projected bytes exceed the whole read budget previously clamped to every byte permit, so one oversized row group serialized the scan: wide vector columns project ~294 MiB per row group against the 256 MiB default budget, and parallel row-group reads silently degraded to 1 in flight unless the user hand-tuned max-inflight-bytes. Cap a single acquisition at budget / min(parallelism, 4) instead. Row groups at or below their fair share keep exact accounting (no behavior change for ordinary layouts); oversized row groups admit up to four concurrent reads, matching what the 768 MiB hand-tuned budget achieved (source wait -43.7% on a 10M-row 768-dim build) without configuration. The byte budget thereby becomes a fair-admission mechanism for large row groups rather than a strict projected-byte ceiling; the share divisor is capped at 4 until wider RSS measurements justify more.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
Speed up vector-index builds by removing two object-storage bottlenecks:
Changes
row_rangeswithout a deletion vector as an unfiltered scan, allowing the existing parallel row-group path to run. Partial ranges, deletion vectors, and empty ranges keep their previous semantics.max_inflight_bytesas a strict projected-byte admission limit, and warn once when a row group exceeds it.Reproduce the IVF-PQ build benchmark
The benchmark is in
ivfpq_build_benchmark.rs. It builds an IVF-PQ index with dimension 768, cosine distance,nlist=4096, andpq.m=192on an existing Paimon table:Benchmark
Cohere 10M × 768 dimensions, cosine IVF-PQ (
nlist=4096,pq.m=192, 8 bits), 10 Parquet files / 100 row groups, direct OSS, and no local cache.Parallel Parquet reads
Both baseline and this PR use an explicit 512 MiB Parquet read budget, so the comparison isolates the changes in this PR while retaining strict byte accounting.
The 512 MiB budget is a workload-specific benchmark setting and must be configured explicitly. The default remains 256 MiB.
Concurrent multipart upload
With all other benchmark inputs held constant, four in-flight multipart uploads reduced the serialize/upload phase from 30.3s to 4.6s (−84.8%). The vector-index writer alone uses this concurrency; other writers keep their existing behavior.
Tests
_ROW_IDparity.API and format
No public API or file/index format changes. The concurrent writer helper is crate-private.