diff --git a/bin/jmh.sh b/bin/jmh.sh index 883d7ef2..cd7adbe8 100755 --- a/bin/jmh.sh +++ b/bin/jmh.sh @@ -1,25 +1,28 @@ #!/bin/bash -BASEDIR=$(dirname $0) -ROOTDIR=$(realpath ${BASEDIR}/..) -LIBS="${ROOTDIR}/target/libs" -CLASSES="${ROOTDIR}/target/classes" -TEST_CLASSES="${ROOTDIR}/target/test-classes" -CONFDIR="${ROOTDIR}/conf" +BASEDIR=$(dirname "$0") function help() { - echo "$@" echo "" - echo "tip: run '$0 -h' for JMH options" + echo "tip: pass '-h' for JMH options" exit 1 } -function check_if_exists_or_exit() { - [ ! -d "$@" ] && help "Missing '$@' directory. Run: 'mvn clean package -DskipTests' before running the JMH benchmark" +function list_benchmarks() { + echo "Available benchmarks:" + printf "\tDataReplicationBenchmark\n" + printf "\tLogJmhBenchmark\n" + printf "\tStorageAppenderBenchmark\n" + help; } -check_if_exists_or_exit ${LIBS} -check_if_exists_or_exit ${CLASSES} -check_if_exists_or_exit ${TEST_CLASSES} +BENCHMARK="$1" +shift; -java -cp "${LIBS}/*":${CLASSES}:${TEST_CLASSES}:${CONFDIR} ${JAVA_OPTIONS} org.openjdk.jmh.Main org.jgroups.perf.LogJmhBenchmark $@ +if [ "$BENCHMARK" = "-list" ]; then + list_benchmarks + exit 0; +fi + +# shellcheck disable=SC2086,SC2048 +"$BASEDIR"/test-run.sh -ea org.openjdk.jmh.Main "$BENCHMARK" $* diff --git a/bin/test-run.sh b/bin/test-run.sh new file mode 100755 index 00000000..ed143de2 --- /dev/null +++ b/bin/test-run.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# Same as `run.sh` but for running classes in the test sources. + +function check_if_exists_or_exit() { + [ ! -d "$@" ] && help "Missing '$@' directory. Run: 'mvn clean package -DskipTests' before running" +} + +MCAST_ADDR=232.5.5.5 +BIN_DIR=$(dirname "$0") + +# Project built with Maven. +LIB=${BIN_DIR}/../target/libs +CLASSES=${BIN_DIR}/../target/classes +TEST_CLASSES=${BIN_DIR}/../target/test-classes +CONF=${BIN_DIR}/../conf + +check_if_exists_or_exit ${LIBS} +check_if_exists_or_exit ${CLASSES} +check_if_exists_or_exit ${TEST_CLASSES} + +CP="$CLASSES:$CONF:$TEST_CLASSES:$LIB/*" +LOG="-Dlog4j.configurationFile=log4j2.xml" + +JG_FLAGS="-Djgroups.udp.mcast_addr=$MCAST_ADDR" +JG_FLAGS="$JG_FLAGS -Djava.net.preferIPv4Stack=true" + +FLAGS="-server -Xmx600M -Xms600M" +FLAGS="$FLAGS -XX:CompileThreshold=10000 -XX:ThreadStackSize=64K -XX:SurvivorRatio=8" +FLAGS="$FLAGS -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15" +FLAGS="$FLAGS -Xshare:off" + +#GC="-XX:+UseParNewGC -XX:+UseConcMarkSweepGC" ## concurrent mark and sweep (CMS) collector + +EXPERIMENTAL="$EXPERIMENTAL -XX:+EliminateLocks" +#DEBUG="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8787" + +# shellcheck disable=SC2086,SC2048 +java -cp $CP $DEBUG $LOG $GC $JG_FLAGS $FLAGS $EXPERIMENTAL $JAVA_OPTIONS $* diff --git a/pom.xml b/pom.xml index f7f84e3e..44e3f074 100644 --- a/pom.xml +++ b/pom.xml @@ -330,9 +330,25 @@ tests/junit-functional + tests/benchmark + + + add-test-configurations + validate + + add-test-resource + + + + + tests/resources + + + + diff --git a/src/org/jgroups/protocols/raft/RAFT.java b/src/org/jgroups/protocols/raft/RAFT.java index da26e038..3dbc1a93 100644 --- a/src/org/jgroups/protocols/raft/RAFT.java +++ b/src/org/jgroups/protocols/raft/RAFT.java @@ -278,6 +278,10 @@ public int processingQueueSize() { public boolean synchronous() {return synchronous;} public RAFT synchronous(boolean b) {synchronous=b; return this;} + public RAFT logDir(String logDir) { + this.log_dir = logDir; + return this; + } public void resetStats() { super.resetStats(); diff --git a/tests/benchmark/README.md b/tests/benchmark/README.md deleted file mode 100644 index d34371ba..00000000 --- a/tests/benchmark/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# JGroups Raft benchmarks - -This subproject includes all the benchmarks created utilizing JMH. - -## How to - -This specific repository uses the latest Java version available. Currently, Java 21. -To compile the project and runs the benchmarks. -First, execute: - -```bash -$ mvn clean verify -``` - -The output is located at `./target/benchmarks.jar`. -Now, to execute a benchmark, check the current implementations and select the name. -For example, for `MyBenchmark`: - -```bash -$ java -jar target/benchmarks.jar "MyBenchmark" -``` - -To pass configuration for `MyBenchmark`, execute: - -```bash -$ java -jar target/benchmarks.jar -pkey1=value1 -pkey2=value2 "MyBenchmark" -``` - -For more options, related to JMH: - -```bash -$ java -jar target/benchmarks.jar -h -``` - -## Current benchmarks - -The current list of benchmarks include: - -1. `DataReplicationBenchmark`: Benchmark the complete data replication utilizing `RaftHandle`; diff --git a/tests/benchmark/src/main/java/org/jgroups/raft/DataReplicationBenchmark.java b/tests/benchmark/org/jgroups/perf/DataReplicationBenchmark.java similarity index 90% rename from tests/benchmark/src/main/java/org/jgroups/raft/DataReplicationBenchmark.java rename to tests/benchmark/org/jgroups/perf/DataReplicationBenchmark.java index 2afa1186..89983387 100644 --- a/tests/benchmark/src/main/java/org/jgroups/raft/DataReplicationBenchmark.java +++ b/tests/benchmark/org/jgroups/perf/DataReplicationBenchmark.java @@ -1,8 +1,10 @@ -package org.jgroups.raft; +package org.jgroups.perf; import org.jgroups.JChannel; import org.jgroups.protocols.raft.FileBasedLog; import org.jgroups.protocols.raft.RAFT; +import org.jgroups.raft.RaftHandle; +import org.jgroups.raft.StateMachine; import org.jgroups.raft.testfwk.RaftTestUtils; import org.jgroups.util.Util; @@ -38,7 +40,7 @@ @BenchmarkMode({Mode.Throughput}) @Warmup(iterations = 10, time = 5) @Measurement(iterations = 5, time = 10) -@Fork(value = 3, jvmArgsPrepend = "-Djava.net.preferIPv4Stack=true -Djgroups.udp.ip_ttl=0") +@Fork(value = 3, jvmArgsPrepend = "-Djava.net.preferIPv4Stack=true -Djgroups.udp.ip_ttl=0 -Djmh.executor=PLATFORM") public class DataReplicationBenchmark { @Benchmark @@ -79,7 +81,7 @@ public void initialize() throws Exception { String name = Character.toString('A' + i); // Utilize the default configuration shipped with jgroups-raft. - JChannel ch = new JChannel("raft.xml"); + JChannel ch = new JChannel("raft-benchmark.xml"); ch.name(name); // A no-op state machine. @@ -91,8 +93,9 @@ public void initialize() throws Exception { raft.members(memberList); // Fine-tune the RAFT protocol below. - raft.logClass(FileBasedLog.class.getCanonicalName()); - raft.logUseFsync(useFsync); + raft.logClass(FileBasedLog.class.getCanonicalName()) + .logDir(String.format("%s/target/benchmark", System.getProperty("user.dir"))) + .logUseFsync(useFsync); members[i] = handler; ch.connect("jmh-replication"); @@ -145,7 +148,8 @@ public EmptyStateMachine(int dataSize) { @Override public byte[] apply(byte[] data, int offset, int length, boolean serialize_response) throws Exception { - if (data.length != dataSize) throw new IllegalArgumentException("Data size does not match"); + if (data.length != dataSize) + throw new IllegalArgumentException(String.format("Data size does not match: %d != %d", data.length, dataSize)); return RESPONSE; } diff --git a/tests/junit-functional/org/jgroups/perf/LogJmhBenchmark.java b/tests/benchmark/org/jgroups/perf/LogJmhBenchmark.java similarity index 100% rename from tests/junit-functional/org/jgroups/perf/LogJmhBenchmark.java rename to tests/benchmark/org/jgroups/perf/LogJmhBenchmark.java diff --git a/tests/junit-functional/org/jgroups/perf/StorageAppenderBenchmark.java b/tests/benchmark/org/jgroups/perf/StorageAppenderBenchmark.java similarity index 100% rename from tests/junit-functional/org/jgroups/perf/StorageAppenderBenchmark.java rename to tests/benchmark/org/jgroups/perf/StorageAppenderBenchmark.java diff --git a/tests/benchmark/pom.xml b/tests/benchmark/pom.xml deleted file mode 100644 index 4d4ded22..00000000 --- a/tests/benchmark/pom.xml +++ /dev/null @@ -1,132 +0,0 @@ - - 4.0.0 - - org.jgroups.raft - benchmark - 1.0.13.Final-SNAPSHOT - jar - - JMH benchmark sample: Java - - - UTF-8 - 21 - 21 - - 1.37 - benchmarks - - - - - org.openjdk.jmh - jmh-core - ${jmh.version} - - - org.openjdk.jmh - jmh-generator-annprocess - ${jmh.version} - provided - - - org.jgroups - jgroups-raft - ${project.version} - compile - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - ${javac.target} - ${javac.target} - ${javac.target} - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.1 - - - package - - shade - - - ${uberjar.name} - - - org.openjdk.jmh.Main - - - - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - - - - - - - - - - - - maven-clean-plugin - 2.5 - - - maven-deploy-plugin - 2.8.1 - - - maven-install-plugin - 2.5.1 - - - maven-jar-plugin - 2.4 - - - maven-javadoc-plugin - 2.9.1 - - - maven-resources-plugin - 2.6 - - - maven-site-plugin - 3.3 - - - maven-source-plugin - 2.2.1 - - - maven-surefire-plugin - 2.17 - - - - - - diff --git a/tests/resources/raft-benchmark.xml b/tests/resources/raft-benchmark.xml new file mode 100644 index 00000000..c009ded6 --- /dev/null +++ b/tests/resources/raft-benchmark.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + +