[FLINK-39981] [Autoscaler] Correct dynamic source topology from active split metrics#1153
Conversation
| } | ||
|
|
||
| int activeSplitCount = (int) activeSplitCountMetric.getCurrent(); | ||
| if (activeSplitCount >= currentParallelism) { |
There was a problem hiding this comment.
Could we keep activeSplitCount as the upper bound after the first correction too?
For example, P=10 and N=5 gets corrected to 5. But once P=N, this falls through to regular scaling, which still uses stale NUM_SOURCE_PARTITIONS
Under load it can scale above 5 again, then get capped back on the next pass. Maybe clamp later scale ups to N too when the metric is valid
There was a problem hiding this comment.
Good catch — addressed in 234725a. When the optional gauge is valid, ordinary utilization scaling now also clamps its upper bound to activeSplitCount, so after P=10/N=5 is corrected to P=5, stale legacy partition metrics cannot scale it back above 5. Missing or invalid gauges still use the legacy path. I also added tests for the steady-state cap and missing-gauge fallback.
| return ParallelismChange.noChange(currentParallelism); | ||
| } | ||
|
|
||
| int activeSplitCount = (int) activeSplitCountMetric.getCurrent(); |
There was a problem hiding this comment.
Could we make N < P persist for a bit before bypassing the scale down delay?
During a DynamicKafkaSource metadata refresh, the enumerator sends MetadataUpdateEvent before the new enumerators start. Readers can briefly report a lower positive count while new splits are still in flight
One autoscaler poll in that window could cause an unnecessary downscale or restart. Maybe use the same stability idea as the N >= P path, or a shorter window
There was a problem hiding this comment.
Good point — the previous full-window check only covered the N >= P && min == 0 recovery path. Addressed in 9bc4e47: N < P is now only exposed to the scaler after every retained metrics-window sample reports valid 0 < N < P. A transient or missing sample falls back to legacy behavior.
|
@gyfora can you or anyone you know who has more expertise here can help review? |
8955a88 to
29ec301
Compare
…e split metrics Generated-by: Codex (GPT-5)
29ec301 to
118b0bd
Compare
What is the purpose of the change
Dynamic Kafka sources can remove clusters and splits while stale
KafkaSourceReader...currentOffsetmetric names remain visible to the autoscaler. Thelegacy partition count can therefore stay above the source's actual active split count, leaving
empty source subtasks without a rescale or recovery action.
This change adds an opt-in topology correction path for
FLINK-39981using theDynamicKafkaSource.activeSplitCountgauge added byFLINK-39990. The metric is optional:disabled, missing, incomplete, or malformed data keeps the existing behavior. An exact all-zero
aggregate is retained only as a non-scaling signal that clears and re-arms a prior recovery latch.
The
N >= Precovery branch depends on the connector recovery semantics merged inapache/flink-connector-kafka#278for
FLINK-39980. That change adoptsSupportsSplitReassignmentOnRecovery: restored active splits are reported back to the enumeratorand requeued for redistribution. Without that connector support, a same-parallelism restart could
restore the same skewed reader ownership, so operators should not rely on this recovery branch.
Brief change log
job.autoscaler.dynamic-source.topology-correction.enabled, defaulting tofalse.minimum active splits from its aggregated value without replacing legacy
NUM_SOURCE_PARTITIONS; an exact all-zero aggregate is retained only to clear a priorrecovery latch and never becomes a scaling target.
N < P) for the full metrics window,caps source parallelism without waiting for the ordinary scale-down delay.
utilization scale-ups, so stale legacy partition metrics cannot scale the source back above
its active split count.
N >= Pand the minimum active splitcount is zero for the full metrics window, then requests one durable same-parallelism recovery;
apache/flink-connector-kafka#278turns that recovery into active-split redistribution.
restart nonce for
LAST_STATEjobs and reuses an already pending restart nonce.compatibility coverage.
Verifying this change
This change added tests and can be verified as follows:
mvn -q -pl flink-autoscaler -am testmvn -q -pl flink-autoscaler-plugin-jdbc -am -Dtest=JdbcAutoScalerStateStoreTest -Dsurefire.failIfNoSpecifiedTests=false testmvn -q -pl flink-kubernetes-operator -am -Dtest=KubernetesAutoScalerStateStoreTest,KubernetesScalingRealizerTest -Dsurefire.failIfNoSpecifiedTests=false testmvn -q -pl flink-kubernetes-docs -am -DskipTests -Pgenerate-docs packagemvn -q spotless:checkDoes this pull request potentially affect one of the following parts:
CustomResourceDescriptors: noDocumentation
AI assistance
This contribution was prepared with Codex (GPT-5); the author reviewed, adapted, and tested the
changes.