Skip to content

Commit b332786

Browse files
authored
Pipe: improve progress coverage checks (#17940)
* Pipe: improve progress coverage checks * Pipe: address shutdown progress review comments * Pipe: refine Chinese shutdown progress messages
1 parent 3767282 commit b332786

9 files changed

Lines changed: 455 additions & 61 deletions

File tree

iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodePipeMessages.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,45 @@ public final class DataNodePipeMessages {
140140
+ "node may not be ready yet, and meta will be pushed by config node later.";
141141
public static final String FAILED_TO_PERSIST_PROGRESS_INDEX_TO_CONFIGNODE =
142142
"Failed to persist progress index to configNode, status: {}";
143+
public static final String SHUTDOWN_PROGRESS_NOT_CONFIRMED =
144+
"This shutdown progress was not confirmed to be persisted on ConfigNode.";
145+
public static final String START_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
146+
"Start to persist all pipe progress indexes during shutdown, pipe count {}, deadline {} ms";
147+
public static final String
148+
INTERRUPTED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
149+
"Interrupted while persisting all pipe progress indexes during shutdown. "
150+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
151+
public static final String
152+
TIMED_OUT_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
153+
"Timed out after {} ms while persisting all pipe progress indexes during shutdown. "
154+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
155+
public static final String FAILED_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
156+
"Failed to persist all pipe progress indexes during shutdown within {} ms. "
157+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
158+
public static final String COLLECTED_PIPE_METAS_FOR_SHUTDOWN_PROGRESS_PERSIST =
159+
"Collected pipe metas for shutdown progress persist, pipe count {}, pipe meta count {}, "
160+
+ "pipe meta size {} bytes, took {} ms";
161+
public static final String COLLECTED_EMPTY_PIPE_METAS_DURING_SHUTDOWN =
162+
"Collected empty pipe metas for {} pipes during shutdown.";
163+
public static final String START_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
164+
"Start to pushHeartbeat shutdown pipe meta to ConfigNode, dataNode id {}, pipe count {}, "
165+
+ "pipe meta count {}, pipe meta size {} bytes";
166+
public static final String FAILED_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
167+
"Failed to pushHeartbeat shutdown pipe meta to ConfigNode, status {}, took {} ms. "
168+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
169+
public static final String
170+
SUCCESSFULLY_FINISHED_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
171+
"Successfully finished pushHeartbeat shutdown pipe meta to ConfigNode, pipe count {}, "
172+
+ "pipe meta count {}, pipe meta size {} bytes, took {} ms";
173+
public static final String
174+
EXCEPTION_OCCURRED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
175+
"Exception occurred while persisting all pipe progress indexes during shutdown. "
176+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
177+
public static final String PERSISTING_PIPE_PROGRESS_INDEXES_BEFORE_SHUTDOWN =
178+
"Persisting pipe progress indexes before shutdown with timeout {} ms.";
179+
public static final String PIPE_PROGRESS_INDEXES_WERE_NOT_CONFIRMED_DURING_SHUTDOWN =
180+
"Pipe progress indexes were not confirmed by ConfigNode during shutdown. "
181+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
143182
public static final String FAILURE_WHEN_REGISTER_PIPE_PLUGIN_SKIP_THIS =
144183
"Failure when register pipe plugin {}. Skip this plugin and continue startup.";
145184
public static final String

iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodePipeMessages.java

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,46 @@ public final class DataNodePipeMessages {
132132
"获取 pipe task meta from config node. Ignore the exception 失败,原因:config node may not be "
133133
+ "ready yet, and meta will be pushed by config node later.";
134134
public static final String FAILED_TO_PERSIST_PROGRESS_INDEX_TO_CONFIGNODE =
135-
"持久化 progress index 到 configNode 失败,状态:{}";
135+
"持久化进度索引到 ConfigNode 失败,状态:{}";
136+
public static final String SHUTDOWN_PROGRESS_NOT_CONFIRMED =
137+
"本次关闭流程中的进度未确认已持久化到 ConfigNode。";
138+
public static final String START_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
139+
"开始在关闭期间持久化所有 Pipe 进度索引,Pipe 数量 {},超时时间 {} ms";
140+
public static final String
141+
INTERRUPTED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
142+
"在关闭期间持久化所有 Pipe 进度索引时被中断。"
143+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
144+
public static final String
145+
TIMED_OUT_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
146+
"在关闭期间持久化所有 Pipe 进度索引超时,耗时 {} ms。"
147+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
148+
public static final String FAILED_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
149+
"在关闭期间持久化所有 Pipe 进度索引失败,耗时 {} ms。"
150+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
151+
public static final String COLLECTED_PIPE_METAS_FOR_SHUTDOWN_PROGRESS_PERSIST =
152+
"已收集关闭期间进度持久化所需的 Pipe 元数据,Pipe 数量 {},Pipe 元数据数量 {},"
153+
+ "Pipe 元数据大小 {} 字节,耗时 {} ms";
154+
public static final String COLLECTED_EMPTY_PIPE_METAS_DURING_SHUTDOWN =
155+
"关闭期间为 {} 个 Pipe 收集到空 Pipe 元数据。";
156+
public static final String START_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
157+
"开始向 ConfigNode 推送关闭期间的 Pipe 元数据心跳,DataNode ID {},Pipe 数量 {},"
158+
+ "Pipe 元数据数量 {},Pipe 元数据大小 {} 字节";
159+
public static final String FAILED_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
160+
"向 ConfigNode 推送关闭期间的 Pipe 元数据心跳失败,状态 {},耗时 {} ms。"
161+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
162+
public static final String
163+
SUCCESSFULLY_FINISHED_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE =
164+
"成功向 ConfigNode 推送关闭期间的 Pipe 元数据心跳,Pipe 数量 {},Pipe 元数据数量 {},"
165+
+ "Pipe 元数据大小 {} 字节,耗时 {} ms";
166+
public static final String
167+
EXCEPTION_OCCURRED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN =
168+
"在关闭期间持久化所有 Pipe 进度索引时发生异常。"
169+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
170+
public static final String PERSISTING_PIPE_PROGRESS_INDEXES_BEFORE_SHUTDOWN =
171+
"关闭前正在持久化 Pipe 进度索引,超时时间 {} ms。";
172+
public static final String PIPE_PROGRESS_INDEXES_WERE_NOT_CONFIRMED_DURING_SHUTDOWN =
173+
"关闭期间 Pipe 进度索引未被 ConfigNode 确认。"
174+
+ SHUTDOWN_PROGRESS_NOT_CONFIRMED;
136175
public static final String FAILURE_WHEN_REGISTER_PIPE_PLUGIN_SKIP_THIS =
137176
"注册 pipe plugin {} 失败。将跳过该插件并继续启动。";
138177
public static final String
@@ -209,7 +248,7 @@ public final class DataNodePipeMessages {
209248
"subtask {} 已关闭, ignore exception";
210249
public static final String SUBTASK_WORKER_IS_INTERRUPTED = "子任务工作线程被中断";
211250
public static final String SUCCESSFULLY_PERSISTED_ALL_PIPE_S_INFO_TO =
212-
"成功 persisted all pipe's info to configNode。";
251+
"成功将所有 Pipe 信息持久化到 ConfigNode。";
213252
public static final String THE_EXECUTOR_AND_HAS_BEEN_SUCCESSFULLY_SHUTDOWN =
214253
"执行器 {} 和 {} 已成功关闭。";
215254

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/agent/task/PipeDataNodeTaskAgent.java

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
import java.util.concurrent.Future;
100100
import java.util.concurrent.ThreadPoolExecutor;
101101
import java.util.concurrent.TimeUnit;
102+
import java.util.concurrent.atomic.AtomicBoolean;
102103
import java.util.function.Consumer;
103104
import java.util.stream.Collectors;
104105

@@ -623,25 +624,129 @@ public void runPipeTasks(
623624

624625
///////////////////////// Shutdown Logic /////////////////////////
625626

627+
public long getShutdownProgressPersistTimeoutInMs() {
628+
return Math.max(
629+
1_000L,
630+
(long) CommonDescriptor.getInstance().getConfig().getCnConnectionTimeoutInMS()
631+
+ CommonDescriptor.getInstance().getConfig().getDnConnectionTimeoutInMS());
632+
}
633+
634+
public boolean persistAllProgressIndex(final long timeoutInMs) {
635+
final long normalizedTimeoutInMs = Math.max(1L, timeoutInMs);
636+
final long startTime = System.currentTimeMillis();
637+
final AtomicBoolean isConfirmed = new AtomicBoolean(false);
638+
final Thread persistThread =
639+
new Thread(
640+
() -> isConfirmed.set(persistAllProgressIndexInternal()),
641+
ThreadName.PIPE_RUNTIME_META_SYNCER.getName() + "-Shutdown-Persist");
642+
persistThread.setDaemon(true);
643+
644+
LOGGER.info(
645+
DataNodePipeMessages.START_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN,
646+
getPipeCount(),
647+
normalizedTimeoutInMs);
648+
persistThread.start();
649+
try {
650+
final long deadlineInMs = startTime + normalizedTimeoutInMs;
651+
while (persistThread.isAlive()) {
652+
final long remainingTimeInMs = deadlineInMs - System.currentTimeMillis();
653+
if (remainingTimeInMs <= 0) {
654+
break;
655+
}
656+
persistThread.join(remainingTimeInMs);
657+
}
658+
} catch (final InterruptedException e) {
659+
Thread.currentThread().interrupt();
660+
LOGGER.info(
661+
DataNodePipeMessages
662+
.INTERRUPTED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN);
663+
return false;
664+
}
665+
666+
if (persistThread.isAlive()) {
667+
LOGGER.warn(
668+
DataNodePipeMessages.TIMED_OUT_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN,
669+
System.currentTimeMillis() - startTime);
670+
return false;
671+
}
672+
673+
if (!isConfirmed.get()) {
674+
LOGGER.warn(
675+
DataNodePipeMessages.FAILED_TO_PERSIST_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN,
676+
System.currentTimeMillis() - startTime);
677+
}
678+
return isConfirmed.get();
679+
}
680+
626681
public void persistAllProgressIndex() {
627-
try (final ConfigNodeClient configNodeClient =
628-
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
629-
// Send request to some API server
682+
persistAllProgressIndex(getShutdownProgressPersistTimeoutInMs());
683+
}
684+
685+
private boolean persistAllProgressIndexInternal() {
686+
final long collectStartTime = System.currentTimeMillis();
687+
final int pipeCount = getPipeCount();
688+
try {
630689
final TPipeHeartbeatResp resp = new TPipeHeartbeatResp(new ArrayList<>());
631690
collectPipeMetaList(new TPipeHeartbeatReq(Long.MIN_VALUE), resp);
691+
final int pipeMetaCount = resp.getPipeMetaList().size();
692+
final int pipeMetaSizeInBytes =
693+
resp.getPipeMetaList().stream()
694+
.filter(Objects::nonNull)
695+
.mapToInt(ByteBuffer::remaining)
696+
.sum();
697+
LOGGER.info(
698+
DataNodePipeMessages.COLLECTED_PIPE_METAS_FOR_SHUTDOWN_PROGRESS_PERSIST,
699+
pipeCount,
700+
pipeMetaCount,
701+
pipeMetaSizeInBytes,
702+
System.currentTimeMillis() - collectStartTime);
703+
632704
if (resp.getPipeMetaList().isEmpty()) {
633-
return;
705+
if (pipeCount != 0) {
706+
LOGGER.info(DataNodePipeMessages.COLLECTED_EMPTY_PIPE_METAS_DURING_SHUTDOWN, pipeCount);
707+
return false;
708+
}
709+
return true;
634710
}
635-
final TSStatus result =
636-
configNodeClient.pushHeartbeat(
637-
IoTDBDescriptor.getInstance().getConfig().getDataNodeId(), resp);
638-
if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != result.getCode()) {
639-
LOGGER.warn(DataNodePipeMessages.FAILED_TO_PERSIST_PROGRESS_INDEX_TO_CONFIGNODE, result);
640-
} else {
641-
LOGGER.info(DataNodePipeMessages.SUCCESSFULLY_PERSISTED_ALL_PIPE_S_INFO_TO);
711+
712+
try (final ConfigNodeClient configNodeClient =
713+
ConfigNodeClientManager.getInstance().borrowClient(ConfigNodeInfo.CONFIG_REGION_ID)) {
714+
LOGGER.info(
715+
DataNodePipeMessages.START_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE,
716+
IoTDBDescriptor.getInstance().getConfig().getDataNodeId(),
717+
pipeCount,
718+
pipeMetaCount,
719+
pipeMetaSizeInBytes);
720+
final long pushStartTime = System.currentTimeMillis();
721+
final TSStatus result =
722+
configNodeClient.pushHeartbeat(
723+
IoTDBDescriptor.getInstance().getConfig().getDataNodeId(), resp);
724+
final long pushCostTime = System.currentTimeMillis() - pushStartTime;
725+
if (TSStatusCode.SUCCESS_STATUS.getStatusCode() != result.getCode()) {
726+
LOGGER.warn(DataNodePipeMessages.FAILED_TO_PERSIST_PROGRESS_INDEX_TO_CONFIGNODE, result);
727+
LOGGER.warn(
728+
DataNodePipeMessages.FAILED_TO_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE,
729+
result,
730+
pushCostTime);
731+
return false;
732+
} else {
733+
LOGGER.info(
734+
DataNodePipeMessages
735+
.SUCCESSFULLY_FINISHED_PUSH_HEARTBEAT_SHUTDOWN_PIPE_META_TO_CONFIGNODE,
736+
pipeCount,
737+
pipeMetaCount,
738+
pipeMetaSizeInBytes,
739+
pushCostTime);
740+
LOGGER.info(DataNodePipeMessages.SUCCESSFULLY_PERSISTED_ALL_PIPE_S_INFO_TO);
741+
return true;
742+
}
642743
}
643744
} catch (final Exception e) {
644-
LOGGER.warn(e.getMessage());
745+
LOGGER.warn(
746+
DataNodePipeMessages
747+
.EXCEPTION_OCCURRED_WHILE_PERSISTING_ALL_PIPE_PROGRESS_INDEXES_DURING_SHUTDOWN,
748+
e);
749+
return false;
645750
}
646751
}
647752

0 commit comments

Comments
 (0)