Skip to content

feat: size-balanced file assignment in Partitioner#15

Merged
cigrainger merged 2 commits into
mainfrom
cg/size-balanced-partitioner
Mar 24, 2026
Merged

feat: size-balanced file assignment in Partitioner#15
cigrainger merged 2 commits into
mainfrom
cg/size-balanced-partitioner

Conversation

@cigrainger

@cigrainger cigrainger commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace round-robin with greedy first-fit-decreasing bin-packing for distributing Parquet files across workers. Files are sorted largest-first and assigned to the worker with the smallest current total load. O(n log k) time, within 11/9 OPT of optimal.
  • Tiered file size fetching: File.stat for local files. Remote (S3/HTTP) files default to round-robin but support opt-in size balancing via parquet_file_metadata (reads Parquet footers for num_rows).
  • S3 glob expansion on coordinator: S3/HTTP globs are now expanded via DuckDB's glob() (uses ListObjectsV2) on the coordinator, so individual files are distributed across workers instead of each worker expanding the full glob independently.
  • Consolidates Parquet glob and DuckLake file distribution into a single distribute_parquet_files/5 codepath.

How it works

Before (round-robin):  [10GB, 1MB, 1MB, 1MB, 1MB, 1MB] across 3 workers
  Worker 1: [10GB, 1MB]  — massively overloaded
  Worker 2: [1MB, 1MB]
  Worker 3: [1MB, 1MB]

After (size-balanced):  same files, 3 workers
  Worker 1: [10GB]        — big file gets its own worker
  Worker 2: [1MB, 1MB, 1MB]
  Worker 3: [1MB, 1MB]

Test plan

  • Skewed file sizes produce balanced assignment (big file isolated)
  • Balance ratio < 4x on synthetic skewed data (5000/3000/1000/100/100/100 row files)
  • S3 paths expand via glob and fall back gracefully
  • All existing partitioner, DuckLake, coordinator, and distributed tests pass
  • 578 tests, 0 failures, Credo clean

🤖 Generated with Claude Code

cigrainger and others added 2 commits March 24, 2026 11:02
Replace round-robin with greedy first-fit-decreasing bin-packing for
Parquet file distribution across workers. Files are sorted largest-first
and assigned to the worker with the smallest current total load.

Tiered file size fetching: File.stat for local files, falls back to
round-robin for S3/HTTP paths where local stat is unavailable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Expand S3/HTTP globs via DuckDB's glob() (ListObjectsV2) on the
coordinator so files are distributed individually across workers
instead of each worker expanding the full glob.

Remote file size balancing via parquet_file_metadata (reads Parquet
footers for num_rows) is available but opt-in via
fetch_remote_sizes: true, since footer reads add latency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cigrainger
cigrainger merged commit 9bcbc26 into main Mar 24, 2026
3 checks passed
@cigrainger
cigrainger deleted the cg/size-balanced-partitioner branch March 24, 2026 00:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant