This is an automated email from the ASF dual-hosted git repository.
dwysakowicz pushed a commit to branch release-1.15
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/release-1.15 by this push:
new d6e8e4287ea [FLINK-22243] Reactive Mode parallelism changes are not
shown in the job graph visualization in the UI
d6e8e4287ea is described below
commit d6e8e4287eaaf144a3a4798b89825370170dce97
Author: Dawid Wysakowicz <[email protected]>
AuthorDate: Fri Sep 30 11:14:19 2022 +0200
[FLINK-22243] Reactive Mode parallelism changes are not shown in the job
graph visualization in the UI
Update the JsonPlan of ExecutionGraph with the correct parallelism instead
of using the original one from the JobGraph.
---
.../jobgraph/jsonplan/JsonPlanGenerator.java | 50 ++++++++++++++++---
.../scheduler/adaptive/CreatingExecutionGraph.java | 19 ++++++++
.../adaptive/StateTrackingMockExecutionGraph.java | 8 ++--
.../flink/test/scheduling/ReactiveModeITCase.java | 56 ++++++++++++++++++++++
4 files changed, 122 insertions(+), 11 deletions(-)
diff --git
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
index 63e95ea81f6..30414506435 100644
---
a/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
+++
b/flink-runtime/src/main/java/org/apache/flink/runtime/jobgraph/jsonplan/JsonPlanGenerator.java
@@ -18,9 +18,14 @@
package org.apache.flink.runtime.jobgraph.jsonplan;
+import org.apache.flink.annotation.Internal;
+import org.apache.flink.api.common.JobID;
import org.apache.flink.runtime.jobgraph.JobEdge;
import org.apache.flink.runtime.jobgraph.JobGraph;
+import org.apache.flink.runtime.jobgraph.JobType;
import org.apache.flink.runtime.jobgraph.JobVertex;
+import org.apache.flink.runtime.jobgraph.JobVertexID;
+import org.apache.flink.runtime.scheduler.adaptive.allocator.VertexParallelism;
import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonFactory;
import
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonGenerator;
@@ -28,14 +33,43 @@ import
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.core.JsonGenerator
import org.apache.commons.lang3.StringEscapeUtils;
import java.io.StringWriter;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
+@Internal
public class JsonPlanGenerator {
private static final String NOT_SET = "";
private static final String EMPTY = "{}";
+ private static final VertexParallelism EMPTY_VERTEX_PARALLELISM =
+ new VertexParallelism() {
+ @Override
+ public Map<JobVertexID, Integer>
getMaxParallelismForVertices() {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public int getParallelism(JobVertexID jobVertexId) {
+ return -1;
+ }
+ };
public static String generatePlan(JobGraph jg) {
+ return generatePlan(
+ jg.getJobID(),
+ jg.getName(),
+ jg.getJobType(),
+ jg.getVertices(),
+ EMPTY_VERTEX_PARALLELISM);
+ }
+
+ public static String generatePlan(
+ JobID jobID,
+ String jobName,
+ JobType jobType,
+ Iterable<JobVertex> vertices,
+ VertexParallelism vertexParallelism) {
try {
final StringWriter writer = new StringWriter(1024);
@@ -44,13 +78,13 @@ public class JsonPlanGenerator {
// start of everything
gen.writeStartObject();
- gen.writeStringField("jid", jg.getJobID().toString());
- gen.writeStringField("name", jg.getName());
- gen.writeStringField("type", jg.getJobType().name());
+ gen.writeStringField("jid", jobID.toString());
+ gen.writeStringField("name", jobName);
+ gen.writeStringField("type", jobType.name());
gen.writeArrayFieldStart("nodes");
// info per vertex
- for (JobVertex vertex : jg.getVertices()) {
+ for (JobVertex vertex : vertices) {
String operator =
vertex.getOperatorName() != null ?
vertex.getOperatorName() : NOT_SET;
@@ -81,8 +115,12 @@ public class JsonPlanGenerator {
gen.writeStartObject();
// write the core properties
- gen.writeStringField("id", vertex.getID().toString());
- gen.writeNumberField("parallelism", vertex.getParallelism());
+ JobVertexID vertexID = vertex.getID();
+ int storeParallelism =
vertexParallelism.getParallelism(vertexID);
+ gen.writeStringField("id", vertexID.toString());
+ gen.writeNumberField(
+ "parallelism",
+ storeParallelism != -1 ? storeParallelism :
vertex.getParallelism());
gen.writeStringField("operator", operator);
gen.writeStringField("operator_strategy", operatorDescr);
gen.writeStringField("description", description);
diff --git
a/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
b/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
index a4db25a552c..08ce28e3b51 100644
---
a/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
+++
b/flink-runtime/src/main/java/org/apache/flink/runtime/scheduler/adaptive/CreatingExecutionGraph.java
@@ -24,6 +24,8 @@ import org.apache.flink.runtime.execution.ExecutionState;
import org.apache.flink.runtime.executiongraph.ArchivedExecutionGraph;
import org.apache.flink.runtime.executiongraph.ExecutionGraph;
import org.apache.flink.runtime.executiongraph.ExecutionVertex;
+import org.apache.flink.runtime.jobgraph.JobType;
+import org.apache.flink.runtime.jobgraph.jsonplan.JsonPlanGenerator;
import org.apache.flink.runtime.scheduler.DefaultOperatorCoordinatorHandler;
import org.apache.flink.runtime.scheduler.ExecutionGraphHandler;
import org.apache.flink.runtime.scheduler.GlobalFailureHandler;
@@ -41,6 +43,7 @@ import java.util.Collections;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledFuture;
+import java.util.stream.StreamSupport;
/**
* State which waits for the creation of the {@link ExecutionGraph}. If the
creation fails, then the
@@ -115,6 +118,22 @@ public class CreatingExecutionGraph implements State {
operatorCoordinatorHandler.initializeOperatorCoordinators(
context.getMainThreadExecutor());
operatorCoordinatorHandler.startAllOperatorCoordinators();
+ String updatedPlan =
+ JsonPlanGenerator.generatePlan(
+ executionGraph.getJobID(),
+ executionGraph.getJobName(),
+ JobType.STREAMING, // Adaptive scheduler works
only with STREAMING
+ // jobs
+ () ->
+ StreamSupport.stream(
+ executionGraph
+
.getAllExecutionVertices()
+ .spliterator(),
+ false)
+ .map(v ->
v.getJobVertex().getJobVertex())
+ .iterator(),
+
executionGraphWithVertexParallelism.getVertexParallelism());
+ executionGraph.setJsonPlan(updatedPlan);
context.goToExecuting(
result.getExecutionGraph(),
executionGraphHandler,
diff --git
a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
index 222bf986a8a..0ab8623a65f 100644
---
a/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
+++
b/flink-runtime/src/test/java/org/apache/flink/runtime/scheduler/adaptive/StateTrackingMockExecutionGraph.java
@@ -172,6 +172,9 @@ class StateTrackingMockExecutionGraph implements
ExecutionGraph {
return "";
}
+ @Override
+ public void setJsonPlan(String jsonPlan) {}
+
@Override
public JobID getJobID() {
return jobId;
@@ -274,11 +277,6 @@ class StateTrackingMockExecutionGraph implements
ExecutionGraph {
throw new UnsupportedOperationException();
}
- @Override
- public void setJsonPlan(String jsonPlan) {
- throw new UnsupportedOperationException();
- }
-
@Override
public Configuration getJobConfiguration() {
throw new UnsupportedOperationException();
diff --git
a/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
b/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
index ee09c293b8a..346e3013ac9 100644
---
a/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
+++
b/flink-tests/src/test/java/org/apache/flink/test/scheduling/ReactiveModeITCase.java
@@ -25,6 +25,7 @@ import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.JobManagerOptions;
import org.apache.flink.configuration.SchedulerExecutionMode;
import org.apache.flink.core.execution.JobClient;
+import org.apache.flink.runtime.executiongraph.ArchivedExecutionGraph;
import org.apache.flink.runtime.rest.messages.job.JobDetailsInfo;
import org.apache.flink.runtime.testutils.CommonTestUtils;
import org.apache.flink.runtime.testutils.MiniClusterResourceConfiguration;
@@ -36,11 +37,15 @@ import
org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.test.util.MiniClusterWithClientResource;
import org.apache.flink.util.TestLogger;
+import
org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
+
import org.junit.Rule;
import org.junit.Test;
import java.util.concurrent.ExecutionException;
+import static org.assertj.core.api.Assertions.assertThat;
+
/** Tests for Reactive Mode (FLIP-159). */
public class ReactiveModeITCase extends TestLogger {
private static final int NUMBER_SLOTS_PER_TASK_MANAGER = 2;
@@ -48,6 +53,8 @@ public class ReactiveModeITCase extends TestLogger {
private static final Configuration configuration =
getReactiveModeConfiguration();
+ private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
@Rule
public final MiniClusterWithClientResource miniClusterResource =
new MiniClusterWithClientResource(
@@ -107,6 +114,55 @@ public class ReactiveModeITCase extends TestLogger {
NUMBER_SLOTS_PER_TASK_MANAGER * (INITIAL_NUMBER_TASK_MANAGERS
+ 1));
}
+ @Test
+ public void testJsonPlanParallelismAfterRescale() throws Exception {
+ StreamExecutionEnvironment env =
StreamExecutionEnvironment.getExecutionEnvironment();
+ final DataStream<String> input = env.addSource(new DummySource());
+ input.addSink(new DiscardingSink<>());
+
+ final JobClient jobClient = env.executeAsync();
+
+ int initialParallelism = NUMBER_SLOTS_PER_TASK_MANAGER *
INITIAL_NUMBER_TASK_MANAGERS;
+ waitUntilParallelismForVertexReached(
+ miniClusterResource.getRestClusterClient(),
+ jobClient.getJobID(),
+ initialParallelism);
+
+ ArchivedExecutionGraph archivedExecutionGraph =
+ miniClusterResource
+ .getMiniCluster()
+ .getArchivedExecutionGraph(jobClient.getJobID())
+ .get();
+
+ assertThat(
+ OBJECT_MAPPER
+ .readTree(archivedExecutionGraph.getJsonPlan())
+ .findValues("parallelism"))
+ .allMatch(n -> n.asInt() == initialParallelism);
+
+ // scale up to 2 TaskManagers:
+ miniClusterResource.getMiniCluster().startTaskManager();
+
+ int rescaledParallelism =
+ NUMBER_SLOTS_PER_TASK_MANAGER * (INITIAL_NUMBER_TASK_MANAGERS
+ 1);
+ waitUntilParallelismForVertexReached(
+ miniClusterResource.getRestClusterClient(),
+ jobClient.getJobID(),
+ rescaledParallelism);
+
+ archivedExecutionGraph =
+ miniClusterResource
+ .getMiniCluster()
+ .getArchivedExecutionGraph(jobClient.getJobID())
+ .get();
+
+ assertThat(
+ OBJECT_MAPPER
+ .readTree(archivedExecutionGraph.getJsonPlan())
+ .findValues("parallelism"))
+ .allMatch(n -> n.asInt() == rescaledParallelism);
+ }
+
@Test
public void testScaleDownOnTaskManagerLoss() throws Exception {
// test preparation: ensure we have 2 TaskManagers running