From 7f0f9baa00cdd6d747398e41603c80f3be7e68b6 Mon Sep 17 00:00:00 2001 From: huangli Date: Sat, 11 Jan 2025 11:36:09 +0800 Subject: [PATCH] demo: add simple 3 node demo --- .../dongting/bench/raft/RaftBenchmark.java | 2 +- .../github/dtprj/dongting/dtkv/KvClient.java | 10 +-- demos/pom.xml | 52 +++++++++++++++ .../dongting/demos/cluster/DemoClient.java | 56 ++++++++++++++++ .../dtprj/dongting/demos/cluster/Server.java | 66 +++++++++++++++++++ .../dtprj/dongting/demos/cluster/Server1.java | 30 +++++++++ .../dtprj/dongting/demos/cluster/Server2.java | 30 +++++++++ .../dtprj/dongting/demos/cluster/Server3.java | 30 +++++++++ demos/src/main/resources/logback.xml | 15 +++++ pom.xml | 1 + .../dongting/raft/server/DtKVServerTest.java | 2 +- 11 files changed, 288 insertions(+), 6 deletions(-) create mode 100644 demos/pom.xml create mode 100644 demos/src/main/java/com/github/dtprj/dongting/demos/cluster/DemoClient.java create mode 100644 demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server.java create mode 100644 demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server1.java create mode 100644 demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server2.java create mode 100644 demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server3.java create mode 100644 demos/src/main/resources/logback.xml diff --git a/benchmark/src/main/java/com/github/dtprj/dongting/bench/raft/RaftBenchmark.java b/benchmark/src/main/java/com/github/dtprj/dongting/bench/raft/RaftBenchmark.java index 50cb91f1..c4885143 100644 --- a/benchmark/src/main/java/com/github/dtprj/dongting/bench/raft/RaftBenchmark.java +++ b/benchmark/src/main/java/com/github/dtprj/dongting/bench/raft/RaftBenchmark.java @@ -71,7 +71,7 @@ public class RaftBenchmark extends BenchBase { private KvClient[] clients; public static void main(String[] args) throws Exception { - RaftBenchmark benchmark = new RaftBenchmark(CLIENT_COUNT, 100, 100); + RaftBenchmark benchmark = new RaftBenchmark(CLIENT_COUNT, 5000, 100); benchmark.setLogRt(true); benchmark.start(); } diff --git a/client/src/main/java/com/github/dtprj/dongting/dtkv/KvClient.java b/client/src/main/java/com/github/dtprj/dongting/dtkv/KvClient.java index 411c7b9c..b18cee08 100644 --- a/client/src/main/java/com/github/dtprj/dongting/dtkv/KvClient.java +++ b/client/src/main/java/com/github/dtprj/dongting/dtkv/KvClient.java @@ -38,15 +38,15 @@ public class KvClient extends AbstractLifeCircle { private final RaftClient raftClient; private List initServers; - private int initGroupId; + private int[] initGroupIds; public KvClient() { NioClientConfig nioClientConfig = new NioClientConfig(); this.raftClient = new RaftClient(nioClientConfig); } - public KvClient(int initGroupId, String initServers) { - this.initGroupId = initGroupId; + public KvClient(String initServers, int... initGroupIds) { + this.initGroupIds = initGroupIds; NioClientConfig nioClientConfig = new NioClientConfig(); this.raftClient = new RaftClient(nioClientConfig); this.initServers = RaftNode.parseServers(initServers); @@ -144,7 +144,9 @@ public CompletableFuture mkdir(int groupId, String key, DtTime timeout) { protected void doStart() { raftClient.start(); if (initServers != null) { - raftClient.addOrUpdateGroup(initGroupId, initServers); + for (int initGroupId : initGroupIds) { + raftClient.addOrUpdateGroup(initGroupId, initServers); + } } } diff --git a/demos/pom.xml b/demos/pom.xml new file mode 100644 index 00000000..ef691c2e --- /dev/null +++ b/demos/pom.xml @@ -0,0 +1,52 @@ + + + + 4.0.0 + + dongting + com.github.dtprj.dongting + 0.2-SNAPSHOT + + dongting-demos + + + true + true + + + + com.github.dtprj.dongting + dongting-server + 0.2-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 17 + 17 + 17 + + + + + \ No newline at end of file diff --git a/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/DemoClient.java b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/DemoClient.java new file mode 100644 index 00000000..32a9629d --- /dev/null +++ b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/DemoClient.java @@ -0,0 +1,56 @@ +/* + * Copyright The Dongting Project + * + * The Dongting Project 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: + * + * https://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 com.github.dtprj.dongting.demos.cluster; + +import com.github.dtprj.dongting.common.DtTime; +import com.github.dtprj.dongting.dtkv.KvClient; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author huangli + */ +public class DemoClient { + + public static void main(String[] args) throws Exception { + String servers = "1,127.0.0.1:5001;2,127.0.0.1:5002;3,127.0.0.1:5003"; + int groupId = 0; + KvClient client = new KvClient(servers, groupId); + client.start(); + + long startTime = System.currentTimeMillis(); + int loop = 3_000; + CountDownLatch latch = new CountDownLatch(loop); + for (int i = 0; i < loop; i++) { + String key = "key" + (i % 10_000); + DtTime timeout = new DtTime(3, TimeUnit.SECONDS); + CompletableFuture f = client.put(groupId, key, "value".getBytes(), timeout); + f.whenComplete((v, e) -> { + if (e == null) { + latch.countDown(); + } else { + e.printStackTrace(); + } + }); + } + latch.await(); + System.out.println("put " + loop + " keys cost " + (System.currentTimeMillis() - startTime) + "ms"); + + client.stop(new DtTime(3, TimeUnit.SECONDS)); + } +} diff --git a/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server.java b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server.java new file mode 100644 index 00000000..3f53700d --- /dev/null +++ b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server.java @@ -0,0 +1,66 @@ +/* + * Copyright The Dongting Project + * + * The Dongting Project 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: + * + * https://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 com.github.dtprj.dongting.demos.cluster; + +import com.github.dtprj.dongting.dtkv.server.DtKV; +import com.github.dtprj.dongting.dtkv.server.KvConfig; +import com.github.dtprj.dongting.dtkv.server.KvServerUtil; +import com.github.dtprj.dongting.raft.server.DefaultRaftFactory; +import com.github.dtprj.dongting.raft.server.RaftGroupConfig; +import com.github.dtprj.dongting.raft.server.RaftGroupConfigEx; +import com.github.dtprj.dongting.raft.server.RaftServer; +import com.github.dtprj.dongting.raft.server.RaftServerConfig; +import com.github.dtprj.dongting.raft.sm.StateMachine; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author huangli + */ +public class Server { + + protected static RaftServer startServer(int nodeId, String servers, String members, + String observers, int[] groupIds) { + RaftServerConfig serverConfig = new RaftServerConfig(); + serverConfig.setServers(servers); + serverConfig.setNodeId(nodeId); + serverConfig.setReplicatePort(4000 + nodeId); + serverConfig.setServicePort(5000 + nodeId); + serverConfig.setElectTimeout(3000); + serverConfig.setHeartbeatInterval(1000); + + List groupConfigs = new ArrayList<>(); + for (int groupId : groupIds) { + RaftGroupConfig groupConfig = RaftGroupConfig.newInstance(groupId, members, observers); + groupConfig.setDataDir("target/raft_data_" + groupId + "_node" + nodeId); + groupConfigs.add(groupConfig); + } + + DefaultRaftFactory raftFactory = new DefaultRaftFactory() { + @Override + public StateMachine createStateMachine(RaftGroupConfigEx groupConfig) { + return new DtKV(groupConfig, new KvConfig()); + } + }; + + RaftServer raftServer = new RaftServer(serverConfig, groupConfigs, raftFactory); + KvServerUtil.initKvServer(raftServer); + + raftServer.start(); + return raftServer; + } +} diff --git a/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server1.java b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server1.java new file mode 100644 index 00000000..906c369c --- /dev/null +++ b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server1.java @@ -0,0 +1,30 @@ +/* + * Copyright The Dongting Project + * + * The Dongting Project 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: + * + * https://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 com.github.dtprj.dongting.demos.cluster; + +/** + * @author huangli + */ +public class Server1 extends Server { + public static void main(String[] args) { + int nodeId = 1; + String servers = "1,127.0.0.1:4001;2,127.0.0.1:4002;3,127.0.0.1:4003"; + String members = "1,2,3"; + String observers = ""; + int groupId = 0; + startServer(nodeId, servers, members, observers, new int[]{groupId}); + } +} diff --git a/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server2.java b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server2.java new file mode 100644 index 00000000..35d3b9e7 --- /dev/null +++ b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server2.java @@ -0,0 +1,30 @@ +/* + * Copyright The Dongting Project + * + * The Dongting Project 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: + * + * https://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 com.github.dtprj.dongting.demos.cluster; + +/** + * @author huangli + */ +public class Server2 extends Server { + public static void main(String[] args) { + int nodeId = 2; + String servers = "1,127.0.0.1:4001;2,127.0.0.1:4002;3,127.0.0.1:4003"; + String members = "1,2,3"; + String observers = ""; + int groupId = 0; + startServer(nodeId, servers, members, observers, new int[]{groupId}); + } +} diff --git a/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server3.java b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server3.java new file mode 100644 index 00000000..f675da45 --- /dev/null +++ b/demos/src/main/java/com/github/dtprj/dongting/demos/cluster/Server3.java @@ -0,0 +1,30 @@ +/* + * Copyright The Dongting Project + * + * The Dongting Project 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: + * + * https://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 com.github.dtprj.dongting.demos.cluster; + +/** + * @author huangli + */ +public class Server3 extends Server { + public static void main(String[] args) { + int nodeId = 3; + String servers = "1,127.0.0.1:4001;2,127.0.0.1:4002;3,127.0.0.1:4003"; + String members = "1,2,3"; + String observers = ""; + int groupId = 0; + startServer(nodeId, servers, members, observers, new int[]{groupId}); + } +} diff --git a/demos/src/main/resources/logback.xml b/demos/src/main/resources/logback.xml new file mode 100644 index 00000000..299e636d --- /dev/null +++ b/demos/src/main/resources/logback.xml @@ -0,0 +1,15 @@ + + + + %d{mm:ss.SSS} [%thread] %-5level %logger{0} : %msg%n + + + TRACE + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7486a80f..b72be24a 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ server report benchmark + demos diff --git a/server/src/test/java/com/github/dtprj/dongting/raft/server/DtKVServerTest.java b/server/src/test/java/com/github/dtprj/dongting/raft/server/DtKVServerTest.java index aca0f584..d8a7dea7 100644 --- a/server/src/test/java/com/github/dtprj/dongting/raft/server/DtKVServerTest.java +++ b/server/src/test/java/com/github/dtprj/dongting/raft/server/DtKVServerTest.java @@ -40,7 +40,7 @@ void test() throws Exception { waitStart(s1); DtTime timeout = new DtTime(5, TimeUnit.SECONDS); - KvClient client = new KvClient(1, "1, 127.0.0.1:5001"); + KvClient client = new KvClient("1, 127.0.0.1:5001", 1); client.start(); client.mkdir(1, "dir1", timeout).get(); client.put(1, "dir1.k1", "v1".getBytes(), timeout).get(1, TimeUnit.SECONDS);