Prefetch Parquet row groups with a bounded I/O budget - #23492
Conversation
|
Thank you for opening this pull request! Reviewer note: cargo-semver-checks reported the current version number is not SemVer-compatible with the changes in this pull request (compared against the base branch). Details |
|
run benchmarks |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing codex/parquet-pushdecoder-prefetch (4d02e1e) to 2880e10 (merge-base) diff using: tpch File an issue against this benchmark runner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing codex/parquet-pushdecoder-prefetch (4d02e1e) to 2880e10 (merge-base) diff using: tpcds File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpcds — base (merge-base)
tpcds — branch
File an issue against this benchmark runner |
|
run benchmarks |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing codex/parquet-pushdecoder-prefetch (4d02e1e) to 2880e10 (merge-base) diff using: clickbench_partitioned File an issue against this benchmark runner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing codex/parquet-pushdecoder-prefetch (4d02e1e) to 2880e10 (merge-base) diff using: tpcds File an issue against this benchmark runner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing codex/parquet-pushdecoder-prefetch (4d02e1e) to 2880e10 (merge-base) diff using: tpch File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpch — base (merge-base)
tpch — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usageclickbench_partitioned — base (merge-base)
clickbench_partitioned — branch
File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagetpcds — base (merge-base)
tpcds — branch
File an issue against this benchmark runner |
4d02e1e to
2d0806b
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #23492 +/- ##
==========================================
+ Coverage 80.88% 80.89% +0.01%
==========================================
Files 1102 1102
Lines 375813 376300 +487
Branches 375813 376300 +487
==========================================
+ Hits 303966 304409 +443
- Misses 53745 53781 +36
- Partials 18102 18110 +8 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
You might be interested in such a change :) Around 1.5-2x (or more) performance improvements on S3. I did some benchmarking on S3 in #23492 (comment) which shows it basically improves performance overall without regressing anything. |
|
What can we expect for memory consumption? Will we use more memory because we prefetch? |
Yes. The extra memory consumption is pretty low (and can be configured) - it is roughly max the IO budget x partitions (probably slightly higher because of overhead / Tokio tasks running, but generally much lower). Thus 16 (partitions/cores) * 8 MiB = ~128 MiB |
Switch `prefetched_row_groups` to the `datafusion_common` HashSet re-export so the opener no longer needs an inline `std::collections` path, and drop a redundant assertion in the prefetch budget test. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
I will review this PR later this week -- sorry for the dealy |
|
Also #24086 from @adriangb has some interesting experiments. Some other thoughts:
|
Which issue does this PR close?
#18470
Rationale for this change
Sequential Parquet row-group reads are expensive when object-store requests have meaningful latency. Batching projected ranges can hide much of that latency without eagerly decoding data.
What changes are included in this PR?
datafusion.execution.parquet.prefetch_sizebyte budget, disabled by default.Results
In the picture you can see it gives a 1.5-2x or more (up to 6x) on several TPC-H / Clickbench queries without really regressing anything (the regressions that show up are s3 variance - I only ran the suite x3 to average it somewhat but tail S3 latency is very high.
This is tested on a 16 core AWS CPU (5-15 Gbps) node with data in S3.
(Image rendered / generated using Claude - I checked/verified the numbers).
On a 20 MiB budget, simulated object-store latency is 2-3x (see results brlow).
With latency disabled, performance remained effectively neutral: 1.02x for TPC-H and 1.01x for ClickBench. Raising the budget to 100 MiB provided no further aggregate benefit.
Are these changes tested?
Are there any user-facing changes?
Users can opt in by setting
datafusion.execution.parquet.prefetch_size; the default remains disabled.