andygrove opened a new pull request, #1946:
URL: https://github.com/apache/datafusion-ballista/pull/1946

   # Which issue does this PR close?
   
   Closes #1943.
   
   # Rationale for this change
   
   At high `target_partitions`, distributed queries intermittently failed 
during shuffle
   reads with `FetchFailed` — either `EADDRNOTAVAIL` ("Cannot assign requested 
address",
   with client caching off) or an `h2` `BrokenPipe` ("error reading a body from
   connection", with caching on).
   
   Instrumenting the executors with `h2=debug` and reproducing on a 2-executor 
× 8-core
   cluster (TPC-H SF100 from S3) showed the cause: the shuffle client **opened 
and tore
   down thousands of connections per query** — ~3,500 client-initiated `GOAWAY` 
frames in a
   single run, all graceful `NO_ERROR`, with zero `RST_STREAM` (so not h2 
rapid-reset). The
   failure is an intermittent race: the client's own connection **close racing 
an in-flight
   body read** produces the broken pipe, and the same churn exhausts ephemeral 
ports when
   caching is off.
   
   The churn comes from the pool's model: `acquire` checked out an **exclusive 
connection
   per fetch** and returned it on drop, so a shuffle-heavy stage cycled through 
thousands of
   short-lived connections.
   
   # What changes are included in this PR?
   
   Replace the exclusive-connection-per-fetch pool with a small, bounded set of
   **reused, multiplexed connections per endpoint**. 
`DefaultBallistaClientPool` now keeps up
   to `CONNECTIONS_PER_ENDPOINT` (8) shared `BallistaClient`s per `(host, port, 
config)` and
   `acquire` hands out cheap **clones round-robin**. Each underlying 
`tonic::Channel`
   multiplexes concurrent requests over its connection and reconnects 
transparently, so:
   
   - per-query connections collapse from thousands to a handful, removing the 
churn-driven
     broken-pipe / port-exhaustion races, and
   - load is spread across enough connections that no single one stalls under 
high
     shuffle-fetch concurrency (a single shared connection deadlocks — hence a 
small pool
     rather than one).
   
   Dropping a handed-out clone is a no-op (the shared clients stay cached); the 
background
   task still evicts endpoints unused within `idle_timeout`. The change is 
contained to
   `ballista/executor/src/client_pool.rs`; there are no public API changes.
   
   # Are there any user-facing changes?
   
   No API changes. Fixes intermittent shuffle `FetchFailed` at high 
`target_partitions`.
   
   <!-- How tested (verification in progress on a live cluster; will finalize 
before marking
   ready): 2 executors × 8 cores, TPC-H SF100 from S3/MinIO, 
target_partitions=128/256 — the
   partition counts that fail ~2 of 3 runs on `main`. With this change the Q3 
shuffle stage
   (where the failures cluster) completes normally and per-query times are on 
par with (a
   touch faster than) `main`. An h2=debug run confirms client-initiated GOAWAYs 
drop from
   ~3,500/run to a handful. -->
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to