This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/dev/pr-12789-fb8e7a7eeaa8ece1a4fc169619a8cc7b2c3f69f2 in repository https://gitbox.apache.org/repos/asf/seatunnel.git
commit ee83c538ebfadd29d60d5622afd9a12213f02d36 Author: SEZ <[email protected]> AuthorDate: Wed Oct 21 23:08:54 2026 +0000 [Improve][Zeta] Make the checkpoint monitor history size configurable (#12789) --- .../fault-tolerance/checkpoint-mechanism.md | 25 +++++++ docs/en/engines/zeta/hybrid-cluster-deployment.md | 9 +++ .../fault-tolerance/checkpoint-mechanism.md | 21 ++++++ docs/zh/engines/zeta/hybrid-cluster-deployment.md | 9 +++ .../config/YamlSeaTunnelDomConfigProcessor.java | 9 +++ .../common/config/server/CheckpointConfig.java | 26 +++++++ .../common/config/server/ServerConfigOptions.java | 39 +++++++++++ .../config/YamlSeaTunnelConfigParserTest.java | 37 ++++++++++ .../src/test/resources/seatunnel.yaml | 1 + .../checkpoint/PipelineCheckpointOverviewTest.java | 81 ++++++++++++++++++++++ .../seatunnel/engine/server/SeaTunnelServer.java | 23 +++++- 11 files changed, 279 insertions(+), 1 deletion(-) diff --git a/docs/en/architecture/fault-tolerance/checkpoint-mechanism.md b/docs/en/architecture/fault-tolerance/checkpoint-mechanism.md index 31f55a179b..53de3a28a1 100644 --- a/docs/en/architecture/fault-tolerance/checkpoint-mechanism.md +++ b/docs/en/architecture/fault-tolerance/checkpoint-mechanism.md @@ -513,6 +513,31 @@ env { Checkpoint storage is configured on the engine side (e.g., `config/seatunnel.yaml` under `seatunnel.engine.checkpoint.storage`), rather than as job-level `env` options. +The size of the checkpoint history the monitor retains is also engine-side: + +```yaml +seatunnel: + engine: + checkpoint: + monitor-history-size: 32 # default +``` + +This is how many checkpoint history entries are kept per pipeline for the +`/jobs/checkpoints/{jobId}` REST endpoint; completed and failed checkpoints +share the window. Valid values are 1 to 4096. + +It bounds how far back a client can compare a job against its own past, which +matters for spotting a gradual slowdown. Note that it is a count, not a +duration: how much time it covers depends on each job's own +`checkpoint.interval`, while the option itself is cluster-wide. At the default +interval of 300000ms, 32 entries cover roughly 2.5 hours; on a job +checkpointing every 10000ms they cover only about 5 minutes. + +The history is stored in the cluster-wide checkpoint overview map, and every +checkpoint event rewrites that whole entry, so a larger window costs master +CPU, network and backup traffic as well as heap — not heap alone. The value is +read once at master startup, so changing it requires a restart. + ### 5.2 Tuning Guidelines **Checkpoint Interval**: diff --git a/docs/en/engines/zeta/hybrid-cluster-deployment.md b/docs/en/engines/zeta/hybrid-cluster-deployment.md index cd81845ca4..ad12feb0b8 100644 --- a/docs/en/engines/zeta/hybrid-cluster-deployment.md +++ b/docs/en/engines/zeta/hybrid-cluster-deployment.md @@ -93,6 +93,14 @@ The timeout for checkpoints. If the checkpoint cannot be completed within the ti The minimum pause (in milliseconds) between consecutive checkpoints. This ensures that checkpoints are not triggered too frequently. +**monitor-history-size** + +How many checkpoint history entries the monitor keeps per pipeline for the `/jobs/checkpoints/{jobId}` REST endpoint, between 1 and 4096, defaulting to 32. Values above 256 are accepted but log a warning at master startup, since the cost below is paid on every checkpoint event. Completed and failed checkpoints share the window. + +This is a count rather than a duration, so how much time it covers depends on each job's own `checkpoint.interval` while this option is cluster-wide: 32 entries cover about 2.5 hours at the default interval of 300000ms, but only about 5 minutes at an interval of 10000ms. Raise it if you run jobs with short intervals and want to compare a job against a longer stretch of its own past. + +The history is stored in the cluster-wide checkpoint overview map, and every checkpoint event rewrites that whole entry, so a larger window costs master CPU, network and backup traffic as well as heap. The value is read once at master startup, so changing it requires a restart. + Example ```yaml @@ -106,6 +114,7 @@ seatunnel: interval: 300000 timeout: 10000 min-pause: 5000 + monitor-history-size: 32 ``` diff --git a/docs/zh/architecture/fault-tolerance/checkpoint-mechanism.md b/docs/zh/architecture/fault-tolerance/checkpoint-mechanism.md index dce94220d3..715fffb6d9 100644 --- a/docs/zh/architecture/fault-tolerance/checkpoint-mechanism.md +++ b/docs/zh/architecture/fault-tolerance/checkpoint-mechanism.md @@ -356,6 +356,27 @@ seatunnel: namespace: /tmp/seatunnel/checkpoint_snapshot ``` +监控保留的 checkpoint 历史条数同样在引擎侧配置: + +```yaml +seatunnel: + engine: + checkpoint: + monitor-history-size: 32 # 默认值 +``` + +它表示为 `/jobs/checkpoints/{jobId}` REST 端点按 pipeline 保留多少条 checkpoint +历史记录,已完成和失败的 checkpoint 共用这个窗口,取值范围 1 到 4096。 + +这个窗口决定了客户端最多能把作业和自己多久之前的历史做对比,对发现"逐渐变慢" +尤为关键。注意它是**条数**而不是时长:覆盖多长时间取决于每个作业自己的 +`checkpoint.interval`,而本选项是集群级的。按默认 300000ms 的间隔,32 条约覆盖 +2.5 小时;若作业每 10000ms 做一次 checkpoint,则只覆盖约 5 分钟。 + +历史保存在集群级的 checkpoint overview map 中,每次 checkpoint 事件都会重写整条 +记录,因此窗口越大,除堆内存外还会增加 master 的 CPU、网络与副本复制开销——不只是 +堆内存。该值只在 master 启动时读取一次,修改后需要重启。 + 说明: - BATCH 模式下如果作业 env 未配置 `checkpoint.interval`,当前实现会禁用 checkpoint(以源码实现为准)。 - checkpoint storage 主要由引擎侧配置管理;作业级配置不应假设可以随意指定 storage type/path。 diff --git a/docs/zh/engines/zeta/hybrid-cluster-deployment.md b/docs/zh/engines/zeta/hybrid-cluster-deployment.md index 142fd79823..9d7d4b05af 100644 --- a/docs/zh/engines/zeta/hybrid-cluster-deployment.md +++ b/docs/zh/engines/zeta/hybrid-cluster-deployment.md @@ -93,6 +93,14 @@ seatunnel: 连续检查点之间的最小暂停时间(以毫秒为单位),确保检查点不会频繁触发。 +**monitor-history-size** + +监控为 `/jobs/checkpoints/{jobId}` REST 接口按 pipeline 保留的 checkpoint 历史条数,取值 1 到 4096,默认 32。超过 256 的值仍然可用,但 master 启动时会打印一条警告——因为下面提到的开销是每次 checkpoint 事件都要付的。已完成和失败的 checkpoint 共用这个窗口。 + +它是**条数**而不是时长,因此覆盖多长时间取决于每个作业自己的 `checkpoint.interval`,而本选项是集群级的:按默认 300000ms 的间隔,32 条约覆盖 2.5 小时;若间隔为 10000ms,则只覆盖约 5 分钟。如果集群上有间隔很短的作业,并且希望拿作业和更长一段自身历史做对比,应调大该值。 + +历史保存在集群级的 checkpoint overview map 中,每次 checkpoint 事件都会重写整条记录,因此窗口越大,除堆内存外还会增加 master 的 CPU、网络与副本复制开销。该值只在 master 启动时读取一次,修改后需要重启。 + 示例 ```yaml @@ -106,6 +114,7 @@ seatunnel: interval: 300000 timeout: 10000 min-pause: 5000 + monitor-history-size: 32 ``` **checkpoint storage** diff --git a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelDomConfigProcessor.java b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelDomConfigProcessor.java index 94f34f6dc3..6d47a3a16a 100644 --- a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelDomConfigProcessor.java +++ b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelDomConfigProcessor.java @@ -383,6 +383,15 @@ public class YamlSeaTunnelDomConfigProcessor extends AbstractDomConfigProcessor ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_MIN_PAUSE .key(), getTextContent(node))); + } else if (ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_MONITOR_HISTORY_SIZE + .key() + .equals(name)) { + checkpointConfig.setMonitorHistorySize( + getIntegerValue( + ServerConfigOptions.MasterServerConfigOptions + .CHECKPOINT_MONITOR_HISTORY_SIZE + .key(), + getTextContent(node))); } else if (ServerConfigOptions.MasterServerConfigOptions .SCHEMA_CHANGE_CHECKPOINT_TIMEOUT .key() diff --git a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/CheckpointConfig.java b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/CheckpointConfig.java index a7a39a1854..13ec39026f 100644 --- a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/CheckpointConfig.java +++ b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/CheckpointConfig.java @@ -34,6 +34,9 @@ public class CheckpointConfig implements Serializable { ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_TIMEOUT.defaultValue(); private long checkpointMinPause = ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_MIN_PAUSE.defaultValue(); + private int monitorHistorySize = + ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_MONITOR_HISTORY_SIZE + .defaultValue(); private long schemaChangeCheckpointTimeout = ServerConfigOptions.MasterServerConfigOptions.SCHEMA_CHANGE_CHECKPOINT_TIMEOUT .defaultValue(); @@ -51,6 +54,29 @@ public class CheckpointConfig implements Serializable { return retainAfterJobCancelled; } + public void setMonitorHistorySize(int monitorHistorySize) { + // Bounded on both sides. The upper bound is not cosmetic: the history + // lives in the cluster-wide checkpoint overview IMap, and + // HazelcastCheckpointOverviewStateStore.updateOverview rewrites that + // whole entry through IMap.compute on every checkpoint event, with the + // entry listener registered includeValue=true. So an oversized window + // multiplies master CPU, replication and listener traffic on every + // trigger and acknowledgement, not just heap -- and it would do so + // silently. + checkArgument( + monitorHistorySize >= 1 + && monitorHistorySize + <= ServerConfigOptions.MasterServerConfigOptions + .MAX_CHECKPOINT_MONITOR_HISTORY_SIZE, + "The checkpoint monitor history size must be between 1 and " + + ServerConfigOptions.MasterServerConfigOptions + .MAX_CHECKPOINT_MONITOR_HISTORY_SIZE + + ", but was " + + monitorHistorySize + + "."); + this.monitorHistorySize = monitorHistorySize; + } + public void setCheckpointInterval(long checkpointInterval) { checkArgument( checkpointInterval >= MINIMAL_CHECKPOINT_TIME, diff --git a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/ServerConfigOptions.java b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/ServerConfigOptions.java index 16971f3e85..a55ae2430e 100644 --- a/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/ServerConfigOptions.java +++ b/seatunnel-engine/seatunnel-engine-common/src/main/java/org/apache/seatunnel/engine/common/config/server/ServerConfigOptions.java @@ -215,6 +215,45 @@ public class ServerConfigOptions { .defaultValue(30000) .withDescription("The timeout (in milliseconds) for a checkpoint."); + /** + * Upper bound for {@link #CHECKPOINT_MONITOR_HISTORY_SIZE}. The history lives in the + * cluster-wide checkpoint overview IMap, whose whole value is re-serialised on every + * checkpoint event, so an unbounded value would multiply master CPU, replication and + * listener traffic rather than just heap. A few thousand entries is far beyond any useful + * comparison window while staying well clear of that cost. + */ + public static final int MAX_CHECKPOINT_MONITOR_HISTORY_SIZE = 4096; + + /** + * Above this, {@link #CHECKPOINT_MONITOR_HISTORY_SIZE} is legal but worth a word at + * startup. The hard cap stops the pathological case; this catches the merely expensive one, + * where an operator has chosen a window large enough to be felt on a cluster with many + * pipelines or a short checkpoint interval. A warning rather than a rejection, because + * whether the cost is acceptable depends on the cluster, not on the number. + */ + public static final int CHECKPOINT_MONITOR_HISTORY_SIZE_WARN_THRESHOLD = 256; + + public static final Option<Integer> CHECKPOINT_MONITOR_HISTORY_SIZE = + Options.key("monitor-history-size") + .intType() + .defaultValue(32) + .withDescription( + "How many checkpoint history entries the monitor keeps per pipeline " + + "for the /jobs/checkpoints endpoint. Completed and failed " + + "checkpoints share the window. This is a count, not a " + + "duration: how much time it covers depends on each job's " + + "own checkpoint.interval, while this option is " + + "cluster-wide, so the same value covers about 2.5 hours at " + + "the default interval of 300000ms but only about 5 minutes " + + "at an interval of 10000ms. The history is stored in the " + + "cluster-wide checkpoint overview map, and every " + + "checkpoint event rewrites the whole overview entry, so a " + + "larger window costs master CPU, network and backup " + + "traffic as well as heap. Read once at master startup, so " + + "a change needs a restart. Must be between 1 and " + + MAX_CHECKPOINT_MONITOR_HISTORY_SIZE + + "."); + public static final Option<Integer> CHECKPOINT_MIN_PAUSE = Options.key("min-pause") .intType() diff --git a/seatunnel-engine/seatunnel-engine-common/src/test/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelConfigParserTest.java b/seatunnel-engine/seatunnel-engine-common/src/test/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelConfigParserTest.java index 828d2d3879..8fe4cbe4f6 100644 --- a/seatunnel-engine/seatunnel-engine-common/src/test/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelConfigParserTest.java +++ b/seatunnel-engine/seatunnel-engine-common/src/test/java/org/apache/seatunnel/engine/common/config/YamlSeaTunnelConfigParserTest.java @@ -18,7 +18,9 @@ package org.apache.seatunnel.engine.common.config; import org.apache.seatunnel.common.utils.ReflectionUtils; +import org.apache.seatunnel.engine.common.config.server.CheckpointConfig; import org.apache.seatunnel.engine.common.config.server.HttpConfig; +import org.apache.seatunnel.engine.common.config.server.ServerConfigOptions; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -58,6 +60,9 @@ public class YamlSeaTunnelConfigParserTest { Assertions.assertEquals( 7000, config.getEngineConfig().getCheckpointConfig().getCheckpointTimeout()); + Assertions.assertEquals( + 64, config.getEngineConfig().getCheckpointConfig().getMonitorHistorySize()); + Assertions.assertEquals( "hdfs", config.getEngineConfig().getCheckpointConfig().getStorage().getStorage()); @@ -154,6 +159,38 @@ public class YamlSeaTunnelConfigParserTest { Assertions.assertEquals( Runtime.getRuntime().availableProcessors() * 2, config.getEngineConfig().getSlotServiceConfig().getSlotNum()); + // This yaml has no checkpoint block at all, so it pins the default that + // keeps behaviour identical to the previously hard-coded value. + Assertions.assertEquals( + ServerConfigOptions.MasterServerConfigOptions.CHECKPOINT_MONITOR_HISTORY_SIZE + .defaultValue() + .intValue(), + config.getEngineConfig().getCheckpointConfig().getMonitorHistorySize()); + Assertions.assertEquals( + 32, config.getEngineConfig().getCheckpointConfig().getMonitorHistorySize()); + } + + @Test + public void testCheckpointMonitorHistorySizeIsBounded() { + CheckpointConfig checkpointConfig = new CheckpointConfig(); + int max = ServerConfigOptions.MasterServerConfigOptions.MAX_CHECKPOINT_MONITOR_HISTORY_SIZE; + + // The bounds exist because the history lives in the cluster-wide + // checkpoint overview IMap, whose whole value is re-serialised on every + // checkpoint event -- an oversized window would multiply master CPU and + // replication traffic silently. + Assertions.assertThrows( + IllegalArgumentException.class, () -> checkpointConfig.setMonitorHistorySize(0)); + Assertions.assertThrows( + IllegalArgumentException.class, () -> checkpointConfig.setMonitorHistorySize(-1)); + Assertions.assertThrows( + IllegalArgumentException.class, + () -> checkpointConfig.setMonitorHistorySize(max + 1)); + + checkpointConfig.setMonitorHistorySize(1); + Assertions.assertEquals(1, checkpointConfig.getMonitorHistorySize()); + checkpointConfig.setMonitorHistorySize(max); + Assertions.assertEquals(max, checkpointConfig.getMonitorHistorySize()); } @Test diff --git a/seatunnel-engine/seatunnel-engine-common/src/test/resources/seatunnel.yaml b/seatunnel-engine/seatunnel-engine-common/src/test/resources/seatunnel.yaml index 3775207470..9c2527da84 100644 --- a/seatunnel-engine/seatunnel-engine-common/src/test/resources/seatunnel.yaml +++ b/seatunnel-engine/seatunnel-engine-common/src/test/resources/seatunnel.yaml @@ -28,6 +28,7 @@ seatunnel: checkpoint: interval: 6000 timeout: 7000 + monitor-history-size: 64 storage: type: hdfs max-retained: 3 diff --git a/seatunnel-engine/seatunnel-engine-core/src/test/java/org/apache/seatunnel/engine/core/checkpoint/PipelineCheckpointOverviewTest.java b/seatunnel-engine/seatunnel-engine-core/src/test/java/org/apache/seatunnel/engine/core/checkpoint/PipelineCheckpointOverviewTest.java new file mode 100644 index 0000000000..2cc8a2a2f2 --- /dev/null +++ b/seatunnel-engine/seatunnel-engine-core/src/test/java/org/apache/seatunnel/engine/core/checkpoint/PipelineCheckpointOverviewTest.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.seatunnel.engine.core.checkpoint; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +/** + * Tests the retained checkpoint history window, which is what {@code + * seatunnel.engine.checkpoint.monitor-history-size} configures. + */ +public class PipelineCheckpointOverviewTest { + + private static CheckpointHistoryEntry entry(long checkpointId) { + CheckpointInfo info = new CheckpointInfo(); + info.setCheckpointId(checkpointId); + CheckpointHistoryEntry historyEntry = new CheckpointHistoryEntry(); + historyEntry.setCheckpointInfo(info); + return historyEntry; + } + + @Test + public void testHistoryIsTrimmedToTheGivenMaximum() { + PipelineCheckpointOverview overview = new PipelineCheckpointOverview(); + + for (long id = 1; id <= 10; id++) { + overview.addHistory(entry(id), 3); + } + + List<CheckpointHistoryEntry> history = new ArrayList<>(overview.getHistory()); + Assertions.assertEquals(3, history.size()); + + // Newest first: addHistory prepends, so the retained window is the most + // recent entries, not the oldest. Anything consuming this as a trend + // depends on that order. + Assertions.assertEquals(10L, history.get(0).getCheckpointInfo().getCheckpointId()); + Assertions.assertEquals(9L, history.get(1).getCheckpointInfo().getCheckpointId()); + Assertions.assertEquals(8L, history.get(2).getCheckpointInfo().getCheckpointId()); + } + + @Test + public void testHistoryHonoursAWindowLargerThanTheEntryCount() { + PipelineCheckpointOverview overview = new PipelineCheckpointOverview(); + + for (long id = 1; id <= 4; id++) { + overview.addHistory(entry(id), 64); + } + + Assertions.assertEquals(4, overview.getHistory().size()); + } + + @Test + public void testAWindowOfOneKeepsOnlyTheNewestEntry() { + PipelineCheckpointOverview overview = new PipelineCheckpointOverview(); + + overview.addHistory(entry(1), 1); + overview.addHistory(entry(2), 1); + + Assertions.assertEquals(1, overview.getHistory().size()); + Assertions.assertEquals( + 2L, overview.getHistory().peekFirst().getCheckpointInfo().getCheckpointId()); + } +} diff --git a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/SeaTunnelServer.java b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/SeaTunnelServer.java index b226e13b7a..90ee8642e7 100644 --- a/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/SeaTunnelServer.java +++ b/seatunnel-engine/seatunnel-engine-server/src/main/java/org/apache/seatunnel/engine/server/SeaTunnelServer.java @@ -22,6 +22,7 @@ import org.apache.seatunnel.common.utils.RetryUtils; import org.apache.seatunnel.engine.common.Constant; import org.apache.seatunnel.engine.common.config.EngineConfig; import org.apache.seatunnel.engine.common.config.SeaTunnelConfig; +import org.apache.seatunnel.engine.common.config.server.ServerConfigOptions; import org.apache.seatunnel.engine.common.exception.SeaTunnelEngineException; import org.apache.seatunnel.engine.common.exception.SeaTunnelEngineRetryableException; import org.apache.seatunnel.engine.core.classloader.ClassLoaderService; @@ -215,7 +216,27 @@ public class SeaTunnelServer private void startMaster() { checkpointService = new CheckpointService(seaTunnelConfig.getEngineConfig().getCheckpointConfig()); - checkpointMonitorService = new CheckpointMonitorService(engineContext, 32); + int monitorHistorySize = + seaTunnelConfig.getEngineConfig().getCheckpointConfig().getMonitorHistorySize(); + if (monitorHistorySize + > ServerConfigOptions.MasterServerConfigOptions + .CHECKPOINT_MONITOR_HISTORY_SIZE_WARN_THRESHOLD) { + // Legal but worth saying out loud: every checkpoint event rewrites + // the whole checkpoint overview entry in the IMap, so a large + // window is paid on every trigger and acknowledgement rather than + // once. Logged here, at the only place the value is read, so the + // line appears in the master log next to the rest of startup. + log.warn( + "seatunnel.engine.checkpoint.monitor-history-size is set to {}, above the " + + "recommended {}. The checkpoint overview is rewritten in full on " + + "every checkpoint event, so a window this large costs master CPU, " + + "network and backup traffic proportional to history size x running " + + "pipelines. Lower it unless you need that much history.", + monitorHistorySize, + ServerConfigOptions.MasterServerConfigOptions + .CHECKPOINT_MONITOR_HISTORY_SIZE_WARN_THRESHOLD); + } + checkpointMonitorService = new CheckpointMonitorService(engineContext, monitorHistorySize); monitorService = Executors.newSingleThreadScheduledExecutor(); coordinatorService = new CoordinatorService(
