Skip to content

Commit a42ea12

Browse files
authored
[Pipe] Avoid no-op consensus writes for covered progress (#18574) (#18684)
(cherry picked from commit 5aae669)
1 parent 46541cc commit a42ea12

2 files changed

Lines changed: 110 additions & 13 deletions

File tree

‎iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/pipe/coordinator/runtime/heartbeat/PipeHeartbeatParser.java‎

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -211,18 +211,12 @@ private void parseHeartbeatAndSaveMetaChangeLocally(
211211
}
212212

213213
// Update progress index
214-
if (!(runtimeMetaFromCoordinator
215-
.getValue()
216-
.getProgressIndex()
217-
.isAfter(runtimeMetaFromAgent.getProgressIndex())
218-
|| runtimeMetaFromCoordinator
219-
.getValue()
220-
.getProgressIndex()
221-
.equals(runtimeMetaFromAgent.getProgressIndex()))) {
214+
final ProgressIndex coordinatorProgressIndex =
215+
runtimeMetaFromCoordinator.getValue().getProgressIndex();
216+
final ProgressIndex agentProgressIndex = runtimeMetaFromAgent.getProgressIndex();
217+
if (!coordinatorProgressIndex.isEqualOrAfter(agentProgressIndex)) {
222218
final ProgressIndex updatedProgressIndex =
223-
runtimeMetaFromCoordinator
224-
.getValue()
225-
.updateProgressIndex(runtimeMetaFromAgent.getProgressIndex());
219+
runtimeMetaFromCoordinator.getValue().updateProgressIndex(agentProgressIndex);
226220
PipeConfigNodeResourceManager.log()
227221
.schedule(
228222
PipeHeartbeatParser.class,
@@ -236,8 +230,8 @@ private void parseHeartbeatAndSaveMetaChangeLocally(
236230
+ "Progress index on coordinator: {}, progress index from agent: {}, updated progressIndex: {}",
237231
pipeMetaFromCoordinator.getStaticMeta().getPipeName(),
238232
runtimeMetaFromCoordinator.getKey(),
239-
runtimeMetaFromCoordinator.getValue().getProgressIndex(),
240-
runtimeMetaFromAgent.getProgressIndex(),
233+
coordinatorProgressIndex,
234+
agentProgressIndex,
241235
updatedProgressIndex));
242236

243237
needWriteConsensusOnConfigNodes.set(true);

‎iotdb-core/confignode/src/test/java/org/apache/iotdb/confignode/manager/pipe/coordinator/runtime/heartbeat/PipeHeartbeatParserTest.java‎

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
import org.apache.iotdb.commons.conf.CommonDescriptor;
2323
import org.apache.iotdb.commons.consensus.index.impl.MinimumProgressIndex;
24+
import org.apache.iotdb.commons.consensus.index.impl.RecoverProgressIndex;
25+
import org.apache.iotdb.commons.consensus.index.impl.SimpleProgressIndex;
2426
import org.apache.iotdb.commons.exception.pipe.PipeRuntimeCriticalException;
2527
import org.apache.iotdb.commons.exception.pipe.PipeRuntimeSinkCriticalException;
2628
import org.apache.iotdb.commons.pipe.agent.task.meta.PipeMeta;
@@ -55,6 +57,7 @@
5557
import java.util.concurrent.atomic.AtomicBoolean;
5658
import java.util.concurrent.atomic.AtomicReference;
5759

60+
import static org.junit.Assert.assertEquals;
5861
import static org.mockito.ArgumentMatchers.any;
5962
import static org.mockito.ArgumentMatchers.anyBoolean;
6063
import static org.mockito.Mockito.never;
@@ -134,6 +137,82 @@ public void testParseHeartbeatKeepsPendingFlagsWhenProcedureSubmissionFails() th
134137
verify(context.procedureManager, times(2)).pipeHandleMetaChange(true, false);
135138
}
136139

140+
@Test
141+
public void testParseHeartbeatSkipsConsensusWriteWhenCoordinatorProgressCoversAgent()
142+
throws Exception {
143+
CommonDescriptor.getInstance().getConfig().setSeperatedPipeHeartbeatEnabled(false);
144+
145+
final PipeTaskInfo pipeTaskInfo = new PipeTaskInfo();
146+
final PipeMeta coordinatorPipeMeta = createPipeMeta();
147+
final RecoverProgressIndex coordinatorProgressIndex = createRecoverProgressIndex(10, 10);
148+
coordinatorPipeMeta
149+
.getRuntimeMeta()
150+
.getConsensusGroupId2TaskMetaMap()
151+
.get(DATA_NODE_ID)
152+
.updateProgressIndex(coordinatorProgressIndex);
153+
pipeTaskInfo.createPipe(
154+
new CreatePipePlanV2(
155+
coordinatorPipeMeta.getStaticMeta(), coordinatorPipeMeta.getRuntimeMeta()));
156+
157+
final PipeMeta agentPipeMeta = createPipeMeta();
158+
agentPipeMeta
159+
.getRuntimeMeta()
160+
.getConsensusGroupId2TaskMetaMap()
161+
.get(DATA_NODE_ID)
162+
.updateProgressIndex(createRecoverProgressIndex(10, 5));
163+
164+
final ParserTestContext context = createParserTestContext(1, pipeTaskInfo);
165+
context.parser.parseHeartbeat(DATA_NODE_ID, createPipeHeartbeat(agentPipeMeta, false));
166+
167+
assertEquals(
168+
coordinatorProgressIndex,
169+
pipeTaskInfo
170+
.getPipeMetaByPipeName("test_pipe")
171+
.getRuntimeMeta()
172+
.getConsensusGroupId2TaskMetaMap()
173+
.get(DATA_NODE_ID)
174+
.getProgressIndex());
175+
verify(context.procedureManager, never()).pipeHandleMetaChange(anyBoolean(), anyBoolean());
176+
}
177+
178+
@Test
179+
public void testParseHeartbeatWritesConsensusWhenAgentProgressAdvancesCoordinator()
180+
throws Exception {
181+
CommonDescriptor.getInstance().getConfig().setSeperatedPipeHeartbeatEnabled(false);
182+
183+
final PipeTaskInfo pipeTaskInfo = new PipeTaskInfo();
184+
final PipeMeta coordinatorPipeMeta = createPipeMeta();
185+
coordinatorPipeMeta
186+
.getRuntimeMeta()
187+
.getConsensusGroupId2TaskMetaMap()
188+
.get(DATA_NODE_ID)
189+
.updateProgressIndex(createRecoverProgressIndex(10, 10));
190+
pipeTaskInfo.createPipe(
191+
new CreatePipePlanV2(
192+
coordinatorPipeMeta.getStaticMeta(), coordinatorPipeMeta.getRuntimeMeta()));
193+
194+
final PipeMeta agentPipeMeta = createPipeMeta();
195+
final RecoverProgressIndex agentProgressIndex = createRecoverProgressIndex(10, 11);
196+
agentPipeMeta
197+
.getRuntimeMeta()
198+
.getConsensusGroupId2TaskMetaMap()
199+
.get(DATA_NODE_ID)
200+
.updateProgressIndex(agentProgressIndex);
201+
202+
final ParserTestContext context = createParserTestContext(1, pipeTaskInfo);
203+
context.parser.parseHeartbeat(DATA_NODE_ID, createPipeHeartbeat(agentPipeMeta, false));
204+
205+
assertEquals(
206+
agentProgressIndex,
207+
pipeTaskInfo
208+
.getPipeMetaByPipeName("test_pipe")
209+
.getRuntimeMeta()
210+
.getConsensusGroupId2TaskMetaMap()
211+
.get(DATA_NODE_ID)
212+
.getProgressIndex());
213+
verify(context.procedureManager, times(1)).pipeHandleMetaChange(true, false);
214+
}
215+
137216
@Test
138217
public void testParseHeartbeatIgnoresExceptionsBeforeClearTime() throws Exception {
139218
CommonDescriptor.getInstance().getConfig().setSeperatedPipeHeartbeatEnabled(false);
@@ -428,6 +507,30 @@ private PipeHeartbeat createPipeHeartbeat(
428507
Collections.singletonList(recentFailures));
429508
}
430509

510+
private PipeHeartbeat createPipeHeartbeat(final PipeMeta pipeMeta, final boolean ignored)
511+
throws Exception {
512+
return createPipeHeartbeat(pipeMeta, Collections.emptyMap());
513+
}
514+
515+
private PipeMeta createPipeMeta() {
516+
final PipeRuntimeMeta pipeRuntimeMeta = new PipeRuntimeMeta();
517+
pipeRuntimeMeta
518+
.getConsensusGroupId2TaskMetaMap()
519+
.put(DATA_NODE_ID, new PipeTaskMeta(MinimumProgressIndex.INSTANCE, DATA_NODE_ID));
520+
return new PipeMeta(
521+
new PipeStaticMeta(
522+
"test_pipe", 1L, Collections.emptyMap(), new HashMap<>(), new HashMap<>()),
523+
pipeRuntimeMeta);
524+
}
525+
526+
private RecoverProgressIndex createRecoverProgressIndex(
527+
final long firstDataNodeIndex, final long secondDataNodeIndex) {
528+
final Map<Integer, SimpleProgressIndex> dataNodeId2LocalIndex = new HashMap<>();
529+
dataNodeId2LocalIndex.put(1, new SimpleProgressIndex(0, firstDataNodeIndex));
530+
dataNodeId2LocalIndex.put(2, new SimpleProgressIndex(0, secondDataNodeIndex));
531+
return new RecoverProgressIndex(dataNodeId2LocalIndex);
532+
}
533+
431534
private static class ParserTestContext {
432535
private final PipeHeartbeatParser parser;
433536
private final ProcedureManager procedureManager;

0 commit comments

Comments
 (0)