Skip to content

fix(arrow-flight): adaptively re-split oversized FlightData based on actual encoded size - #11048

Open
DevMattG wants to merge 5 commits into
apache:mainfrom
DevMattG:flight/adaptive-grpc-response-splitting
Open

fix(arrow-flight): adaptively re-split oversized FlightData based on actual encoded size#11048
DevMattG wants to merge 5 commits into
apache:mainfrom
DevMattG:flight/adaptive-grpc-response-splitting

Conversation

@DevMattG

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

FlightDataEncoder splits record batches based on a cheap, buffer-memory-size heuristic before IPC encoding. That heuristic can be significantly wrong -- it ignores IPC framing/padding overhead, and undercounts batches with dictionaries or highly skewed row sizes -- so pieces produced by the initial split can still end up well over max_flight_data_size once actually encoded.

What changes are included in this PR?

  • After the initial heuristic split, each piece is now IPC-encoded and its actual encoded size is checked against max_flight_data_size in FlightDataEncoder::encode_piece_adaptive. If it's still too large, the piece is re-split using the real size ratio and the sub-pieces are recursively re-checked, so oversized pieces get corrected regardless of why the initial estimate was wrong.
  • Dictionaries are queued unconditionally as soon as they're encoded, independent of whether the record batch carrying them ends up split further.
  • Fixed split_batch_for_grpc_response's batch-count calculation to round up (div_ceil) instead of using floor division, which could previously produce one too few batches.

Are these changes tested?

Yes. Added/extended unit tests in arrow-flight/src/encode.rs covering:

  • Repeated/deep adaptive re-splitting under a heavily skewed dictionary size distribution.
  • Adaptive re-splitting with both DictionaryHandling::Resend and the default DictionaryHandling::Hydrate.
  • A single row whose own encoded size exceeds max_flight_data_size (can't be split further, must still be emitted).

Are there any user-facing changes?

No breaking API changes.

… size

`split_batch_for_grpc_response` only estimates a RecordBatch's encoded
size from `get_buffer_memory_size()`, which ignores IPC framing/padding
overhead and can badly undercount for variable-length data (dictionaries,
strings). This let `FlightDataEncoder` silently emit `FlightData` messages
larger than `max_flight_data_size` (see apache#3478).

`FlightDataEncoder::encode_batch` now delegates to a new
`encode_piece_adaptive`, which encodes each heuristic-split piece, queues
any dictionaries unconditionally (they're keyed by id and correct to send
regardless of how the batch body ends up sliced), and if the *actual*
encoded size still exceeds the limit, re-splits, recursively if necessary.

To avoid paying for that fallback on every batch whose estimated size
lands right at the limit, the first-pass heuristic now targets 90% of
`max_flight_data_size` (`SPLIT_HEURISTIC_MARGIN_DIVISOR`), leaving
headroom for the framing overhead the estimate doesn't account for.
@DevMattG
DevMattG marked this pull request as ready for review September 10, 2026 14:28
@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-flight Changes to the arrow-flight crate labels Sep 10, 2026

@Rich-T-kid Rich-T-kid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't taken a deeper look but from the description it seems we arrived at the same conclusion.

@DevMattG do you mind taking a glance at #10383, we might be able to close the issues related to that PR as well.

Will try and review this PR today

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

Labels

arrow Changes to the arrow crate arrow-flight Changes to the arrow-flight crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve ability of FlightDataEncoder to respect max_flight_data_size for certain data types (strings, dictionaries, etc)

2 participants