compute: coalesce MV sink batches across workers - #37591
Conversation
b01dfbe to
dd6fa4a
Compare
afcdb73 to
1580c0f
Compare
QA LLM Review1. HIGH -- Cleanup sweep's
|
`SharedBatches` hands out a `SharedBatchBuilder` per batch id. Handles for the same id feed one process-global builder task, so the workers running in one process contribute their parts to a single, larger batch instead of each writing its own small one. The last handle to `finish` receives the batch; the others receive `None`. `BatchBuilder::add_part` accepts a pre-encoded part and concatenates parts until they reach the blob target size, which is what lets the shared builder accept work from several workers without re-encoding it. Building a batch now goes through `PersistClient::batch_builder` rather than a `WriteHandle`, so a shared builder needs no writer registration of its own. Co-authored-by: Moritz Hoffmann <mh@materialize.com>
Wire the shared-batch builder into the sync (v2) materialized-view sink so the workers in one process coalesce their parts for a given batch interval into a single, larger batch instead of each writing its own small batch. All workers building an interval share the batch description broadcast by the mint operator, so they share a batch id and their parts land in one process-global shared batch. Only the last worker to finish receives that batch; the rest get nothing, which maps to the empty-batch response the write operator already handles. Every worker still finishes its builder even when it pushed no data, since any one of them may be the last holder responsible for delivering all workers' parts. The behavior is gated behind the new enable_compute_sync_mv_sink_shared_batches dyncfg, default off. The prior per-worker path is retained unchanged for the off case. Measured locally on an 8-worker replica with a churning view: blob PUTs down ~67% and consensus state-diff bytes down ~54%, at unchanged consensus command count. Adds a testdrive test asserting the view equals the equivalent one-shot aggregation across a multi-worker cluster with churn, enables the flag in the CI system-parameter defaults, and registers it with parallel-workload's flag flipper. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Both confirmed and fixed in the first commit. Branch is now at 1. Cleanup sweep orphaning a finished batch. Confirmed, including the consequence. The sweep holds the registry mutex, Applied the suggested fix, with the reasoning recorded at the call site: // Probe the count rather than `upgrade()`: the temporary strong reference an upgrade
// creates can make a concurrent `SharedBatchBuilder::finish` see a strong count above
// one and hand the batch to nobody, which seals the interval with no data. A stale
// count is harmless in both directions, since zero cannot become live again and a
// stale non-zero only keeps a dead entry until the next sweep.
inner.states.retain(|_, weak| weak.strong_count() > 0);Two other 2. Quadratic Two things also changed since the reviewed revision, both from the same pass:
Reviewed and applied by Claude Code. |
Continues #35411 (draft by @bkirwi), rebased onto
main.With many workers each MV sink worker writes its own small batch per interval, so the sink emits many small parts and a large consensus state diff. This coalesces the parts the workers in one process write for a batch interval into a single, larger shared batch.
SharedBatcheshands out aSharedBatchBuilderper batch id; handles for the same id feed one process-global builder task, and the last handle to finish receives the batch. The sync (v2) sink is wired to it, best-effort and default off (enable_compute_sync_mv_sink_shared_batches). On an 8-worker replica this cut persist blob PUTs ~67% and consensus state-diff bytes ~54%, at unchanged consensus command count.Best-effort means a worker only merges its part into the shared batch when its write overlaps the others still building in the same interval, so parts per append land around 1.4 rather than the ideal 1.0. The barrier that closes that gap to exactly 1.0 is split into the follow-up #37617.
The v1 sink is untouched apart from carrying a shared batch id on
BatchDescription. @bkirwi's draft also rewired v1 onto the shared builder, but that path is the default sink and the rewiring is not flag-gated, so it is left out here.Original authorship by @bkirwi is preserved in the first commit.