Commit d29cbf4
[AMORO-4271] AIP-5 Phase 2: demand-driven scale-up for dynamic allocation groups (#4272)
* [AMORO-4271] AIP-5 Phase 2: add dynamic-allocation.executor-parallelism config
The scaling unit of dynamic allocation is one homogeneous K-thread
optimizer instance (the Spark executor model). K is configured by the
new dynamic-allocation.executor-parallelism property (default 1).
validate() rejects K < 1 and K > max-parallelism: a single K-thread
instance already exceeding the cap could never be created, which would
leave an enabled group as a silent no-op.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: pure demand accounting (serviceable planned, thread occupancy)
serviceablePlannedCount implements quota-mode-aware demand counting:
a proportional quota (targetQuota <= 1) scales with availableCore, so
the whole backlog is serviceable; an absolute quota (> 1) is a fixed
limit that scaling cannot raise, so only free slots count.
occupiesThread counts SCHEDULED as occupying: a thread is busy from
assignment (pollTask), not from ack; counting only ACKED would
overestimate headroom during the poll-to-ack window.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: computeScaleUp scale-out decision
Per-group decision state (backlog timer, cadence, exponential ramp)
with injected time, so every scenario is deterministic.
Ordered checks:
- min-parallelism floor: enforced immediately, no timing gate.
- Immediate demand (busy + serviceable > effective): exponential ramp
(1, 2, 4, 8) clamped to the actual need; the ramp resets when the
clamp binds (Spark addExecutors semantics) or when demand clears.
- Future demand (pending tables while all threads are busy, including
the zero-optimizer cold start where nothing polls and planning never
runs): a single probe instance. Pending tables are not quantified
demand before planning, so no exponential growth on this signal.
Demand must persist for scheduler-backlog-timeout before the first
scale-out; later rounds are spaced by sustained-backlog-timeout, so a
trickle drained between rounds never accumulates toward a scale-out.
The max-parallelism cap always wins.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: pending registration accounting with boot deadline
Registration is optimizer-driven (the pod self-registers after boot),
so scale-up counts requested-but-unregistered capacity to avoid
duplicate scale-outs during the boot window. Entries carry their own
boot deadline: a request that never registers (image pull failure,
exhausted ResourceQuota, crash loop) is pruned instead of freezing
scale-up below real demand forever. Heartbeat expiry cannot cover this
window because it only starts after registration.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: dedicated scale keeper for dynamic-allocation groups
DRA-enabled groups are taken over from the legacy floor keeper, whose
min-parallelism-check cadence (minutes, multiplied by consecutive
attempts) would render the DRA backlog timeouts (seconds) physically
unreachable. OptimizerScaleKeeper reuses the AbstractKeeper
infrastructure (HA leader gating, DelayQueue, lifecycle) and evaluates
each group at its own sustained-backlog-timeout; the legacy keeper
keeps watching DRA groups only to resume floor duty if DRA is disabled
later.
Scale-outs are executed in executor-parallelism-thread instance units
(computeScaleUp), with requested-but-unregistered capacity counted via
PendingRegistrations so a booting pod is not re-requested every round;
a synchronous request failure is dropped immediately and retried.
Groups are watched on create, startup load, and update (covering
enabling DRA on an existing group at runtime); deleted or disabled
groups drop out of the watch set on their next evaluation.
OptimizingQueue.collectDynamicAllocationLoad() snapshots the demand
side: busy threads (SCHEDULED and ACKED), quota-mode-aware serviceable
PLANNED tasks, and PENDING tables - the only signal observable on a
cold group with zero optimizers.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: warn when a group is planning-bound instead of scaling
Idle threads while tables wait as PENDING and no PLANNED tasks
materialize means the bottleneck is the serialized planning
(optimizer.max-planning-parallelism), not thread capacity: scaling out
would only add more idle threads. The scale keeper surfaces this as an
edge-triggered warning naming the config to raise, and does not scale.
A cold group (zero threads) stays the future-demand case.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: distinguish the scale keeper's failure modes
The keeper's drop-out path treated every irregularity the same way,
which conflates situations that need opposite handling:
- A transient group-read failure (e.g. a database hiccup) is not a
deletion: there is no periodic re-watch, so dropping the group there
would silently disable its dynamic allocation until the next config
change. Keep the task alive and retry shortly.
- After unwatching a disabled group, re-read it once: an update
re-enabling DRA concurrently would have had its watch() call
swallowed by the still-present watched-set entry, orphaning the
group until its next change.
- An enabled group whose queue is momentarily absent (a delete/create
racing the config watcher) is transient too; unwatch-plus-rewatch
there would spin a delay-0 hot loop of DB reads.
- A scale-out that fails after requestResource succeeded has started a
real pod; erasing its boot-window entry would re-request a duplicate
next round. Only a failure before the request is dropped and retried.
- Disabling DRA keeps the boot-window accounting (re-enabling within
the window must not re-request the same capacity); deleting the
group drops everything immediately, so a same-name group created
before the next evaluation does not inherit phantom capacity.
- The planning-bound warning now counts registered threads only (a
booting pod's phantom capacity is not idle threads) and requires the
condition to persist across two consecutive evaluations, since a
single snapshot can hold transiently while planning is in flight.
Also pins in the integration test that registration clears the
boot-window accounting: double-counted capacity would suppress demand
scaling.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: keep floor handling consistent across validation and scaling
Two floor edge cases:
- A floor unreachable in executor-parallelism units (e.g. min=5, max=6,
K=4: covering the floor needs 2 instances = 8 threads > max) passed
validation and then sat permanently below its floor with no signal -
the same silent no-op the validation rules exist to prevent. Reject
it up front; the keeper-side cap clamp stays as defense in depth for
configs persisted before this rule.
- A floor deficit (optimizers died, or a new group) now resets the
demand-phase state: previously a demand phase before the deficit
left a passed cadence gate and a grown ramp behind, so the first
demand after recovery fired immediately and oversized instead of
re-proving backlog persistence.
Also pins that a fractional absolute quota truncates like the poll
gate does ((int) 2.5 = 2 slots), keeping the two accountings aligned.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: snapshot table runtimes under the scheduling lock
SchedulingPolicy's table runtime map is a plain HashMap whose
canonical accesses all hold tableLock; the dynamic-allocation load
snapshot iterated it lock-free from the scale keeper thread, so a
concurrent addTable/removeTable could throw
ConcurrentModificationException and skip that whole evaluation round.
Add a snapshot accessor that copies the runtimes under the lock and
use it for the load snapshot.
Also covers collectDynamicAllocationLoad with a queue-level test on a
real table: the PENDING table is the only demand signal before any
poll (the cold-start case), and a polled task occupies its thread from
SCHEDULED on.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
* [AMORO-4271] AIP-5 Phase 2: document the dynamic-allocation group properties
Add the dynamic-allocation.* properties to the optimizer group
property table, mark the flat min-parallelism row deprecated in favor
of the namespaced key, and recommend executor-parallelism 4-8 for
Kubernetes groups so per-pod JVM overhead is shared across threads.
The scale-down-related properties are documented as landing in a later
release.
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
---------
Signed-off-by: Jiwon Park <jpark92@outlook.kr>
Co-authored-by: ZhouJinsong <zhoujinsong0505@163.com>1 parent cbd7d65 commit d29cbf4
14 files changed
Lines changed: 1542 additions & 12 deletions
File tree
- amoro-ams/src
- main/java/org/apache/amoro/server
- optimizing
- dra
- test/java/org/apache/amoro/server
- optimizing
- dra
- amoro-common/src/main/java/org/apache/amoro
- docs/admin-guides
Lines changed: 270 additions & 11 deletions
Large diffs are not rendered by default.
Lines changed: 42 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| |||
418 | 419 | | |
419 | 420 | | |
420 | 421 | | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
421 | 463 | | |
422 | 464 | | |
423 | 465 | | |
| |||
Lines changed: 16 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
146 | 148 | | |
147 | 149 | | |
148 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
149 | 165 | | |
Lines changed: 52 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
45 | 46 | | |
46 | 47 | | |
47 | 48 | | |
| |||
54 | 55 | | |
55 | 56 | | |
56 | 57 | | |
| 58 | + | |
57 | 59 | | |
58 | 60 | | |
59 | 61 | | |
| |||
64 | 66 | | |
65 | 67 | | |
66 | 68 | | |
| 69 | + | |
67 | 70 | | |
68 | 71 | | |
69 | 72 | | |
| |||
88 | 91 | | |
89 | 92 | | |
90 | 93 | | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
91 | 100 | | |
92 | 101 | | |
93 | 102 | | |
94 | 103 | | |
95 | 104 | | |
96 | 105 | | |
| 106 | + | |
97 | 107 | | |
98 | 108 | | |
99 | 109 | | |
| |||
269 | 279 | | |
270 | 280 | | |
271 | 281 | | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
| 293 | + | |
| 294 | + | |
| 295 | + | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
| 305 | + | |
| 306 | + | |
| 307 | + | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
272 | 320 | | |
273 | 321 | | |
274 | 322 | | |
| |||
340 | 388 | | |
341 | 389 | | |
342 | 390 | | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
343 | 395 | | |
344 | 396 | | |
345 | 397 | | |
| |||
Lines changed: 206 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
0 commit comments