From d2d815034303e91ba130e2979c94f433d1b9c626 Mon Sep 17 00:00:00 2001 From: szywilliam Date: Mon, 25 Mar 2024 11:29:55 +0800 Subject: [PATCH 1/4] add creationgap to client request param --- .../ratis/client/api/SnapshotManagementApi.java | 6 +++++- .../ratis/client/impl/ClientProtoUtils.java | 5 +++-- .../ratis/client/impl/SnapshotManagementImpl.java | 5 +++-- .../ratis/protocol/SnapshotManagementRequest.java | 15 ++++++++++++++- ratis-proto/src/main/proto/Raft.proto | 2 +- .../apache/ratis/server/impl/RaftServerImpl.java | 5 +++-- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java index edd0475442..ec29233e73 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java @@ -28,5 +28,9 @@ public interface SnapshotManagementApi { /** trigger create snapshot file. */ - RaftClientReply create(long timeoutMs) throws IOException; + default RaftClientReply create(long timeoutMs) throws IOException { + return create(0, timeoutMs); + } + + RaftClientReply create(long creationGap, long timeoutMs) throws IOException; } diff --git a/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java b/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java index 003f202bd9..cab9606a0e 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/impl/ClientProtoUtils.java @@ -659,7 +659,8 @@ static SnapshotManagementRequest toSnapshotManagementRequest(SnapshotManagementR switch(p.getOpCase()) { case CREATE: return SnapshotManagementRequest.newCreate(clientId, serverId, - ProtoUtils.toRaftGroupId(m.getRaftGroupId()), m.getCallId(), m.getTimeoutMs()); + ProtoUtils.toRaftGroupId(m.getRaftGroupId()), m.getCallId(), m.getTimeoutMs(), + p.getCreate().getCreationGap()); default: throw new IllegalArgumentException("Unexpected op " + p.getOpCase() + " in " + p); } @@ -671,7 +672,7 @@ static SnapshotManagementRequestProto toSnapshotManagementRequestProto( .setRpcRequest(toRaftRpcRequestProtoBuilder(request)); final SnapshotManagementRequest.Create create = request.getCreate(); if (create != null) { - b.setCreate(SnapshotCreateRequestProto.newBuilder().build()); + b.setCreate(SnapshotCreateRequestProto.newBuilder().setCreationGap(create.getCreationGap()).build()); } return b.build(); } diff --git a/ratis-client/src/main/java/org/apache/ratis/client/impl/SnapshotManagementImpl.java b/ratis-client/src/main/java/org/apache/ratis/client/impl/SnapshotManagementImpl.java index 1762dc0e49..65c54d0f21 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/impl/SnapshotManagementImpl.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/impl/SnapshotManagementImpl.java @@ -37,9 +37,10 @@ class SnapshotManagementImpl implements SnapshotManagementApi { } @Override - public RaftClientReply create(long timeoutMs) throws IOException { + public RaftClientReply create(long creationGap, long timeoutMs) throws IOException { final long callId = CallId.getAndIncrement(); return client.io().sendRequestWithRetry(() -> SnapshotManagementRequest.newCreate(client.getId(), - Optional.ofNullable(server).orElseGet(client::getLeaderId), client.getGroupId(), callId, timeoutMs)); + Optional.ofNullable(server).orElseGet(client::getLeaderId), + client.getGroupId(), callId, timeoutMs, creationGap)); } } diff --git a/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java b/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java index 2ea2059b51..d2cb58d41c 100644 --- a/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java +++ b/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java @@ -25,6 +25,14 @@ public abstract static class Op { } public static class Create extends Op { + private final long creationGap; + private Create(long creationGap) { + this.creationGap = creationGap; + } + + public long getCreationGap() { + return creationGap; + } @Override public String toString() { @@ -35,8 +43,13 @@ public String toString() { public static SnapshotManagementRequest newCreate(ClientId clientId, RaftPeerId serverId, RaftGroupId groupId, long callId, long timeoutMs) { + return newCreate(clientId, serverId, groupId, callId, timeoutMs, 0); + } + + public static SnapshotManagementRequest newCreate(ClientId clientId, + RaftPeerId serverId, RaftGroupId groupId, long callId, long timeoutMs, long creationGap) { return new SnapshotManagementRequest(clientId, - serverId, groupId, callId, timeoutMs,new SnapshotManagementRequest.Create()); + serverId, groupId, callId, timeoutMs, new SnapshotManagementRequest.Create(creationGap)); } private final Op op; diff --git a/ratis-proto/src/main/proto/Raft.proto b/ratis-proto/src/main/proto/Raft.proto index edc57ec65e..b2e96e283e 100644 --- a/ratis-proto/src/main/proto/Raft.proto +++ b/ratis-proto/src/main/proto/Raft.proto @@ -470,7 +470,7 @@ message SnapshotManagementRequestProto { } message SnapshotCreateRequestProto { - + uint64 creationGap = 1; } message StartLeaderElectionRequestProto { diff --git a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java index 0ea3746293..2cec095785 100644 --- a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java +++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java @@ -1223,9 +1223,10 @@ CompletableFuture takeSnapshotAsync(SnapshotManagementRequest r LOG.info("{}: takeSnapshotAsync {}", getMemberId(), request); assertLifeCycleState(LifeCycle.States.RUNNING); assertGroup(getMemberId(), request); + Preconditions.assertNotNull(request.getCreate(), "create"); - //TODO(liuyaolong): get the gap value from shell command - long minGapValue = RaftServerConfigKeys.Snapshot.creationGap(proxy.getProperties()); + final long creationGap = request.getCreate().getCreationGap(); + long minGapValue = creationGap > 0? creationGap : RaftServerConfigKeys.Snapshot.creationGap(proxy.getProperties()); final long lastSnapshotIndex = Optional.ofNullable(stateMachine.getLatestSnapshot()) .map(SnapshotInfo::getIndex) .orElse(0L); From d422557ce975933c8b5ed1aec5d736ef2132b82c Mon Sep 17 00:00:00 2001 From: szywilliam Date: Mon, 25 Mar 2024 11:37:12 +0800 Subject: [PATCH 2/4] make checkstyle happy --- .../org/apache/ratis/protocol/SnapshotManagementRequest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java b/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java index d2cb58d41c..269fdfc591 100644 --- a/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java +++ b/ratis-common/src/main/java/org/apache/ratis/protocol/SnapshotManagementRequest.java @@ -24,7 +24,8 @@ public final class SnapshotManagementRequest extends RaftClientRequest { public abstract static class Op { } - public static class Create extends Op { + + public static final class Create extends Op { private final long creationGap; private Create(long creationGap) { this.creationGap = creationGap; From eeacd3862786f596d4e4a469781b38644761bdbf Mon Sep 17 00:00:00 2001 From: szywilliam Date: Mon, 25 Mar 2024 12:29:13 +0800 Subject: [PATCH 3/4] add explicit interface about force --- .../org/apache/ratis/client/api/SnapshotManagementApi.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java index ec29233e73..26fc7a5637 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java @@ -32,5 +32,11 @@ default RaftClientReply create(long timeoutMs) throws IOException { return create(0, timeoutMs); } + /** trigger create snapshot file. If forced, ignore the creation gap. */ + default RaftClientReply create(boolean force, long timeoutMs) throws IOException { + return create(1, timeoutMs); + } + + /** trigger create snapshot file if the number of newly applied logs since last snapshot exceeds creationGap. */ RaftClientReply create(long creationGap, long timeoutMs) throws IOException; } From f4ca209ff0c783bed31f9ba1febb5fd807690886 Mon Sep 17 00:00:00 2001 From: szywilliam Date: Tue, 26 Mar 2024 13:41:33 +0800 Subject: [PATCH 4/4] update the javadoc --- .../ratis/client/api/SnapshotManagementApi.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java index 26fc7a5637..f83d976040 100644 --- a/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java +++ b/ratis-client/src/main/java/org/apache/ratis/client/api/SnapshotManagementApi.java @@ -27,16 +27,24 @@ */ public interface SnapshotManagementApi { - /** trigger create snapshot file. */ + /** The same as create(0, timeoutMs). */ default RaftClientReply create(long timeoutMs) throws IOException { return create(0, timeoutMs); } - /** trigger create snapshot file. If forced, ignore the creation gap. */ + /** The same as create(force? 1 : 0, timeoutMs). */ default RaftClientReply create(boolean force, long timeoutMs) throws IOException { - return create(1, timeoutMs); + return create(force? 1 : 0, timeoutMs); } - /** trigger create snapshot file if the number of newly applied logs since last snapshot exceeds creationGap. */ + /** + * Trigger to create a snapshot. + * + * @param creationGap When (creationGap > 0) and (astAppliedIndex - lastSnapshotIndex < creationGap), + * return lastSnapshotIndex; otherwise, take a new snapshot and then return its index. + * When creationGap == 0, use the server configured value as the creationGap. + * @return a reply. When {@link RaftClientReply#isSuccess()} is true, + * {@link RaftClientReply#getLogIndex()} is the snapshot index fulfilling the operation. + */ RaftClientReply create(long creationGap, long timeoutMs) throws IOException; }