Skip to content

Commit

Permalink
Create clustered replication benchmark
Browse files Browse the repository at this point in the history
* Create a harness to develop benchmarks based on the CounterPerf;
* Created a replication benchmark to verify the performance for
  replication an arbitrary byte array in a cluster.
* Created the script for running the new benchmark.
  • Loading branch information
jabolina committed Jun 9, 2024
1 parent d531a60 commit 6386f8b
Show file tree
Hide file tree
Showing 9 changed files with 1,049 additions and 1 deletion.
6 changes: 6 additions & 0 deletions bin/replication-perf.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

BASEDIR=$(dirname "$0")

# shellcheck disable=SC2086,SC2048
"$BASEDIR"/test-run.sh -ea org.jgroups.perf.Main org.jgroups.perf.replication.ReplicationPerf -props raft-benchmark.xml $*
94 changes: 94 additions & 0 deletions tests/benchmark/org/jgroups/perf/CommandLineOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.jgroups.perf;

/**
* Base command line arguments for Raft benchmarks.
* <p>
* The first argument <b>must</b> be the FQN of the benchmark class. The remaining arguments can be provided in any order:
* <ul>
* <li><code>-props</code>: The XML file to configure the protocol stack;</li>
* <li><code>-name</code>: The raft-id of the current node;</li>
* <li><code>-nohup</code>: Disable the event loop;</li>
* <li><code>-histogram</code>: Path to write the HdrHistogram file with the collected metrics for this node.</li>
* </ul>
* </p>
*/
public final class CommandLineOptions {

private final String benchmark;
private final String name;
private final String props;
private final String histogramPath;
private final boolean runEventLoop;

private CommandLineOptions(String benchmark, String name, String props, String histogramPath, boolean runEventLoop) {
this.benchmark = benchmark;
this.name = name;
this.props = props;
this.histogramPath = histogramPath;
this.runEventLoop = runEventLoop;
}

public String getBenchmark() {
return benchmark;
}

public String getName() {
return name;
}

public String getProps() {
return props;
}

public String getHistogramPath() {
return histogramPath;
}

public boolean shouldRunEventLoop() {
return runEventLoop;
}

public static CommandLineOptions parse(String[] args) {
String props = null;
String name = null;
String histogramPath = null;
boolean runEventLoop = true;

if (args.length == 0)
throw new IllegalArgumentException("Arguments not provided");

// The first position contains the benchmark class to run.
String benchmark = args[0];

for (int i = 1; i < args.length; i++) {
switch (args[i]) {
case "-props":
props = args[++i];
break;

case "-name":
name = args[++i];
break;

case "-nohup":
runEventLoop = false;
break;

case "-histogram":
histogramPath = args[++i];
break;

default:
System.out.printf("Unknown option: %s%n", args[i]);
help(benchmark);
break;
}
}

return new CommandLineOptions(benchmark, name, props, histogramPath, runEventLoop);
}

private static void help(String benchmark) {
System.out.printf("%s [-props <props>] [-name <name>] [-nohup] [-histogram /path/to/write]", benchmark);
}
}
48 changes: 48 additions & 0 deletions tests/benchmark/org/jgroups/perf/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.jgroups.perf;

import org.jgroups.perf.harness.AbstractRaftBenchmark;
import org.jgroups.util.Util;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
* Entry-point class to run Raft benchmarks.
* <p>
* The command line arguments are parsed and the benchmark class is instantiated. The arguments must be provided in the
* correct order. The very first argument is the benchmark class to run, followed by the arguments.
* </p>
*/
public class Main {

public static void main(String[] args) throws Throwable {
CommandLineOptions cmd = CommandLineOptions.parse(args);
AbstractRaftBenchmark benchmark = instantiate(cmd);

// Initializes the benchmark.
// Causes the nodes to retrieve the benchmark configuration from the coordinator.
benchmark.init();

if (cmd.shouldRunEventLoop()) {
benchmark.eventLoop();
} else {
for (;;) Util.sleep(60_000);
}

benchmark.stop();
}

@SuppressWarnings("unchecked")
private static AbstractRaftBenchmark instantiate(CommandLineOptions cmd)
throws InvocationTargetException, InstantiationException, IllegalAccessException, ClassNotFoundException {

Class<? extends AbstractRaftBenchmark> clazz = (Class<? extends AbstractRaftBenchmark>) Class.forName(cmd.getBenchmark());
Constructor<?>[] constructors = clazz.getConstructors();

if (constructors.length > 1)
throw new IllegalStateException("Multiple constructors declared!");

Constructor<? extends AbstractRaftBenchmark> c = (Constructor<? extends AbstractRaftBenchmark>) constructors[0];
return c.newInstance(cmd);
}
}
Loading

0 comments on commit 6386f8b

Please sign in to comment.