[Ideas] Anser: Folding a segment's parallel workers stat before the coordinator sees them #2021
Unanswered
leborchuk
asked this question in
Ideas / Feature Requests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Description
Folding a segment's workers before the coordinator sees them
Status: idea, not implemented. No wire-protocol change. Original PR with Anser - #1942
The problem
A parallel slice runs
numsegments × parallel_workersprocesses and every oneof them publishes its own part. The coordinator folds them all and then returns
the merged payload to every consumer, one blocking write at a time. Both halves
scale with the process count rather than the segment count, and the payload does
not shrink along the way: a bloom union is a bitwise OR, so each part is a whole
bitset.
Measured on 4 segments with a 1 MB filter, and extrapolated to 128 segments with
a 64 MB one (the ceiling
anser.max_info_sizeallows):parallel_workersPer join, over one coordinator NIC, single-threaded, with a base64 decode and a
CRC per part. At 4 segments and 16 workers the fan-out already took 1140 ms,
which overran the old 1 s consumer deadline and left every consumer unfiltered.
Raising the deadline (now 100 s by default) makes the filter arrive but does not
make it cheap: the first subscriber is served in under a millisecond and the last
over a second later.
The idea
The workers of one segment are processes on one host. They do not need the
coordinator to combine their parts with each other — only to combine them with
other segments'. So fold locally first, and let one process per segment speak
to the coordinator on behalf of the rest.
Effect on the numbers above: parts folded and deliveries both drop by a factor
of
parallel_workers, back to the rows where it equals 1. The 128-segment,8-worker case falls from 149.3 GiB to 18.7 GiB — the coordinator stops paying
for parallelism it gains nothing from.
What it does not fix: the remaining
numsegmentsparts still cross thecoordinator, so a 128-segment cluster still moves ~19 GiB per join for a 64 MB
filter. A full fix is an all-reduce over the interconnect, where per-node
traffic is ~2 × payload regardless of cluster size. Local folding is the cheaper
first step and is a prerequisite for that anyway — the interconnect exchange
wants one participant per segment, not one per worker.
Why this fits the existing design
ANSER_WIRE_KIND_PARTmessage it publishes now, and the coordinator stillfolds N parts without caring what N is. Only
ANSER_RF_PRIV_N_PRODUCERSgetsa different value:
numsegmentsinstead ofnumsegments × parallel_workers.fold()already exists inAnserPayloadOps(anserpayload.c) and is thesame bitwise OR the coordinator uses. The local fold calls the same function
on the same payload type; nothing type-specific is duplicated.
cdbgang_createGang_async()either returns a full gang or raises — sonumsegmentsis exactly the number of leaders that will run, just asnumsegments × parallel_workersis exactly the number of processes today.What has to be built
deposit a part and somewhere to read the merged result. A DSM segment keyed
by
(gp_session_id, gp_command_count, condition_id)is the obvious shape;the QEs of one gang share a host but not a
ParallelContext, so nothingexisting can be reused directly.
deposited. This is where the design earns its keep or fails: a worker that
never arrives — squelched, or erroring — must not strand the segment. The
barrier needs the same fail-open discipline the consumer deadline has, and
the leader should publish what it has rather than wait indefinitely.
distinguishable.
Gp_is_writeris not it (all the QEs in the log arewriters); this needs an explicit answer.
workers need it. Same shared segment, in the other direction.
Risks
barrier it can cost a whole segment's progress. Every wait must have a
deadline and a fail-open path, and the leader must never block on a worker
that has already finished or died.
abort as well as on completion — the same problem
dl_resource.csolves fordatalake_fdw with a resource-owner callback, and
comm/pax_resource.ccforPAX.
the target is large clusters with large filters, this buys time; it is not the
destination.
Use case/motivation
No response
Related issues
No response
Are you willing to submit a PR?
All reactions