2828
2929import javax .annotation .Nonnull ;
3030
31+ import java .time .Duration ;
3132import java .time .Instant ;
3233import java .util .HashMap ;
34+ import java .util .LinkedList ;
3335import java .util .Map ;
3436
37+ import static org .apache .flink .util .Preconditions .checkState ;
38+
3539/** All delayed scale down requests. */
3640public class DelayedScaleDown {
3741
42+ @ Data
43+ private static class RecommendedParallelism {
44+ @ Nonnull private final Instant triggerTime ;
45+ private final int parallelism ;
46+ }
47+
3848 /** The delayed scale down info for vertex. */
3949 @ Data
4050 public static class VertexDelayedScaleDownInfo {
4151 private final Instant firstTriggerTime ;
42- private int maxRecommendedParallelism ;
52+ // TODO : add the comment to explain how to calculate the max parallelism within the sliding
53+ // window.
54+ private final LinkedList <RecommendedParallelism > recommendedParallelisms ;
55+
56+ public VertexDelayedScaleDownInfo (Instant firstTriggerTime ) {
57+ this .firstTriggerTime = firstTriggerTime ;
58+ this .recommendedParallelisms = new LinkedList <>();
59+ }
4360
4461 @ JsonCreator
4562 public VertexDelayedScaleDownInfo (
4663 @ JsonProperty ("firstTriggerTime" ) Instant firstTriggerTime ,
47- @ JsonProperty ("maxRecommendedParallelism" ) int maxRecommendedParallelism ) {
64+ @ JsonProperty ("recommendedParallelisms" )
65+ LinkedList <RecommendedParallelism > recommendedParallelisms ) {
4866 this .firstTriggerTime = firstTriggerTime ;
49- this .maxRecommendedParallelism = maxRecommendedParallelism ;
67+ this .recommendedParallelisms = recommendedParallelisms ;
68+ }
69+
70+ /** Record current recommended parallelism. */
71+ public void recordRecommendedParallelism (
72+ Instant triggerTime , int parallelism , Duration scaleDownInterval ) {
73+ var windowStartTime = triggerTime .minus (scaleDownInterval );
74+
75+ // Remove all recommended parallelisms before the window start time.
76+ while (!recommendedParallelisms .isEmpty ()
77+ && recommendedParallelisms
78+ .peekFirst ()
79+ .getTriggerTime ()
80+ .isBefore (windowStartTime )) {
81+ recommendedParallelisms .pollFirst ();
82+ }
83+
84+ // Remove all recommended parallelisms that are lower than the latest parallelism.
85+ while (!recommendedParallelisms .isEmpty ()
86+ && recommendedParallelisms .peekLast ().getParallelism () <= parallelism ) {
87+ recommendedParallelisms .pollLast ();
88+ }
89+
90+ recommendedParallelisms .addLast (new RecommendedParallelism (triggerTime , parallelism ));
91+ }
92+
93+ public int getMaxRecommendedParallelism () {
94+ var maxRecommendedParallelism = recommendedParallelisms .peekFirst ();
95+ checkState (
96+ maxRecommendedParallelism != null ,
97+ "The getMaxRecommendedParallelism should be called after triggering a scale down, it may be a bug." );
98+ return maxRecommendedParallelism .getParallelism ();
5099 }
51100 }
52101
@@ -63,18 +112,18 @@ public DelayedScaleDown() {
63112 /** Trigger a scale down, and return the corresponding {@link VertexDelayedScaleDownInfo}. */
64113 @ Nonnull
65114 public VertexDelayedScaleDownInfo triggerScaleDown (
66- JobVertexID vertex , Instant triggerTime , int parallelism ) {
115+ JobVertexID vertex , Instant triggerTime , int parallelism , Duration scaleDownInterval ) {
116+ // The vertexDelayedScaleDownInfo is updated once scale down is triggered due to we need
117+ // update the triggerTime each time.
118+ updated = true ;
119+
67120 var vertexDelayedScaleDownInfo = delayedVertices .get (vertex );
68121 if (vertexDelayedScaleDownInfo == null ) {
69- // It's the first trigger
70- vertexDelayedScaleDownInfo = new VertexDelayedScaleDownInfo (triggerTime , parallelism );
122+ vertexDelayedScaleDownInfo = new VertexDelayedScaleDownInfo (triggerTime );
71123 delayedVertices .put (vertex , vertexDelayedScaleDownInfo );
72- updated = true ;
73- } else if (parallelism > vertexDelayedScaleDownInfo .getMaxRecommendedParallelism ()) {
74- // Not the first trigger, but the maxRecommendedParallelism needs to be updated.
75- vertexDelayedScaleDownInfo .setMaxRecommendedParallelism (parallelism );
76- updated = true ;
77124 }
125+ vertexDelayedScaleDownInfo .recordRecommendedParallelism (
126+ triggerTime , parallelism , scaleDownInterval );
78127
79128 return vertexDelayedScaleDownInfo ;
80129 }
0 commit comments