Skip to content

Commit 9cf826f

Browse files
author
Egor Kuts
committed
IGNITE-28105 reduce contention on HLC
1 parent cbc7ea3 commit 9cf826f

3 files changed

Lines changed: 12 additions & 18 deletions

File tree

modules/core/src/main/java/org/apache/ignite/internal/hlc/HybridClockImpl.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import org.apache.ignite.internal.logger.Loggers;
3232
import org.apache.ignite.internal.tostring.S;
3333
import org.jetbrains.annotations.Nullable;
34-
import org.jetbrains.annotations.TestOnly;
3534

3635
/**
3736
* A Hybrid Logical Clock implementation.
@@ -51,7 +50,6 @@ public class HybridClockImpl implements HybridClock {
5150

5251
private final List<ClockUpdateListener> updateListeners = new CopyOnWriteArrayList<>();
5352

54-
@TestOnly
5553
public HybridClockImpl() {
5654
this.failureProcessor = null;
5755
}

modules/raft/src/integrationTest/java/org/apache/ignite/raft/server/ItNewLeaderClockTest.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.apache.ignite.internal.replicator.TestReplicationGroupId;
3939
import org.apache.ignite.raft.server.counter.CounterListener;
4040
import org.junit.jupiter.api.Test;
41-
import org.junit.jupiter.api.Timeout;
4241

4342
/**
4443
* Integration test for verifying that a new leader's clock doesn't step down after leadership transfer.
@@ -78,7 +77,7 @@ private void startClusterWithSlowClock() throws Exception {
7877
}, opts -> {
7978
opts.setClock(slowClock);
8079
});
81-
// Start second clock with advanced clock. This node is initial leader.
80+
// Start second clock with advanced clock. This node is the initial leader.
8281
startServer(1, raftServer -> {
8382
String localNodeName = raftServer.clusterService().topologyService().localMember().name();
8483

@@ -126,27 +125,22 @@ private void startClusterWithSlowClock() throws Exception {
126125
/**
127126
* Tests that a new leader's clock doesn't step down after leadership transfer.
128127
* Verifies that:
129-
* 1. Writes succeed with node 1 as leader (regular clock)
130-
* 2. After stopping node 1, a new leader is elected (node 0 or 2 with slow clock)
131-
* 3. The new leader's clock is not lower than the last applied command time
128+
* 1. Writes succeed with node 1 as leader (advanced clock).
129+
* 2. After stopping node 1, a new leader is elected (node 0 or 2 with slow clock).
130+
* 3. The new leader's clock is not lower than the last applied command time.
132131
*
133132
* @throws Exception If test fails.
134133
*/
135134
@Test
136-
@Timeout(120)
137135
public void testNewLeaderClockDoesNotStepDown() throws Exception {
138136
startClusterWithSlowClock();
139-
140137
RaftGroupService client = clients.get(0);
141-
142138
client.refreshLeader().get();
143139
assertNotNull(client.leader(), "Initial leader should be elected");
144-
145140
// Force leadership to node 1 (server index 1).
146141
String node1Name = servers.get(1).clusterService().topologyService().localMember().name();
147142
Peer node1Peer = initialMembersConf.peer(node1Name);
148143
client.transferLeadership(node1Peer).get();
149-
150144
assertTrue(
151145
waitForCondition(() -> {
152146
client.refreshLeader().join();
@@ -165,8 +159,7 @@ public void testNewLeaderClockDoesNotStepDown() throws Exception {
165159
// Verify the writes succeeded.
166160
Long valueBeforeUnisolate = client.<Long>run(getValueCommand()).get();
167161
assertEquals(expectedValue, valueBeforeUnisolate, "All writes should have succeeded");
168-
HybridTimestamp latestLeaderTime = advancedClock.update(HybridTimestamp.MIN_VALUE);
169-
162+
HybridTimestamp lastAppliedCmdTsFromAdvancedClockLeader = advancedClock.update(HybridTimestamp.MIN_VALUE);
170163
RaftNodeId node1RaftNodeId = new RaftNodeId(TEST_GROUP, node1Peer);
171164
servers.get(1).blockMessages(node1RaftNodeId, (msg, peerId) -> true);
172165
// Now stop the leader.
@@ -176,13 +169,13 @@ public void testNewLeaderClockDoesNotStepDown() throws Exception {
176169
waitForCondition(() -> {
177170
client.refreshLeader().join();
178171
return !node1Peer.equals(client.leader());
179-
}, 60_000),
172+
}, 30_000),
180173
"Leadership should transfer to a slow node"
181174
);
182175
HybridTimestamp slow = slowClock.update(HybridTimestamp.MIN_VALUE);
183-
log.info("clocks slow: {}, reg: {}", slow, latestLeaderTime);
176+
log.info("clocks slow: {}, reg: {}", slow, lastAppliedCmdTsFromAdvancedClockLeader);
184177
// Verify that new leader's clock is not lower than the last applied command time.
185-
assertTrue(slow.longValue() >= latestLeaderTime.longValue());
178+
assertTrue(slow.compareTo(lastAppliedCmdTsFromAdvancedClockLeader) >= 0);
186179
}
187180

188181
/**

modules/raft/src/main/java/org/apache/ignite/raft/jraft/core/NodeImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ public class NodeImpl implements Node, RaftServerService {
157157

158158
private volatile HybridClock clock;
159159

160+
private final HybridClock lastAppliedOpClock = new HybridClockImpl();
161+
160162
/**
161163
* Internal states
162164
*/
@@ -1588,6 +1590,7 @@ private void becomeLeader() {
15881590

15891591
resetElectionTimeoutToInitial();
15901592
this.stepDownTimer.start();
1593+
this.clock.update(this.lastAppliedOpClock.current());
15911594
}
15921595

15931596
// should be in writeLock
@@ -2639,7 +2642,7 @@ public Message handleAppendEntriesRequest(final AppendEntriesRequest request, fi
26392642
this.currTerm
26402643
);
26412644
if (request.timestamp() != null) {
2642-
clock.update(request.timestamp());
2645+
lastAppliedOpClock.update(request.timestamp());
26432646
}
26442647
this.logManager.appendEntries(entries, closure);
26452648
// update configuration after _log_manager updated its memory status

0 commit comments

Comments
 (0)