Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test clients for benchmarking. #632

13 changes: 6 additions & 7 deletions java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ is a work in progress and is not yet complete or fully tested. Your contribution
we work towards refining and improving this implementation. Thank you for your interest and understanding as we continue
to develop this Java wrapper.

The Java client contains the following parts:

1. A Java client (lib folder): wrapper to rust client.
2. A benchmark app: A dedicated benchmarking tool designed to evaluate and compare the performance of Babushka and other Java clients.

## Installation and Setup

### Install from Gradle

At the moment, the Java client must be build from source.
At the moment, the Java client must be built from source.

### Build from source

Expand Down Expand Up @@ -118,9 +123,3 @@ The following arguments are accepted:
* `host`: redis server host url
* `port`: redis server port number
* `tls`: redis TLS configured

### Troubleshooting

* Connection Timeout:
* If you're unable to connect to redis, check that you are connecting to the correct host, port, and TLS configuration.
* Only server-side certificates are supported by the TLS configured redis.
11 changes: 0 additions & 11 deletions java/benchmarks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ repositories {
}

dependencies {
// Use JUnit test framework.
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'

// This dependency is used internally, and not exposed to consumers on their own compile classpath.
implementation 'com.google.guava:guava:32.1.1-jre'
implementation 'redis.clients:jedis:4.4.3'
Expand All @@ -34,11 +31,3 @@ application {
// Define the main class for the application.
mainClass = 'babushka.benchmarks.BenchmarkingApp'
}

tasks.withType(Test) {
testLogging {
exceptionFormat "full"
events "started", "skipped", "passed", "failed"
showStandardStreams true
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package babushka.benchmarks;

import static babushka.benchmarks.utils.Benchmarking.testClientSetGet;

import babushka.benchmarks.clients.jedis.JedisClient;
import babushka.benchmarks.clients.lettuce.LettuceAsyncClient;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.Stream;
Expand Down Expand Up @@ -43,10 +47,12 @@ public static void main(String[] args) {
case JEDIS:
// run testClientSetGet on JEDIS sync client
System.out.println("Run JEDIS sync client");
testClientSetGet(JedisClient::new, runConfiguration, false);
break;
case LETTUCE:
// run testClientSetGet on LETTUCE async client
System.out.println("Run LETTUCE async client");
testClientSetGet(LettuceAsyncClient::new, runConfiguration, true);
break;
case BABUSHKA:
System.out.println("Babushka async not yet configured");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package babushka.benchmarks.clients.jedis;

import babushka.benchmarks.clients.SyncClient;
import babushka.benchmarks.utils.ConnectionSettings;
import java.util.Set;
import redis.clients.jedis.DefaultJedisClientConfig;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.commands.JedisCommands;

/** A Jedis client with sync capabilities. See: https://github.com/redis/jedis */
public class JedisClient implements SyncClient {

private JedisCommands jedis;

@Override
public void closeConnection() {
// nothing to do
}

@Override
public String getName() {
return "Jedis";
}

@Override
public void connectToRedis(ConnectionSettings connectionSettings) {
if (connectionSettings.clusterMode) {
jedis =
new JedisCluster(
Set.of(new HostAndPort(connectionSettings.host, connectionSettings.port)),
DefaultJedisClientConfig.builder().ssl(connectionSettings.useSsl).build());
} else {
try (JedisPool pool =
new JedisPool(
connectionSettings.host, connectionSettings.port, connectionSettings.useSsl)) {
jedis = pool.getResource();
}
}
}

@Override
public void set(String key, String value) {
jedis.set(key, value);
}

@Override
public String get(String key) {
return jedis.get(key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package babushka.benchmarks.clients.lettuce;

import babushka.benchmarks.clients.AsyncClient;
import babushka.benchmarks.utils.ConnectionSettings;
import io.lettuce.core.AbstractRedisClient;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisFuture;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.StatefulConnection;
import io.lettuce.core.api.StatefulRedisConnection;
import io.lettuce.core.api.async.RedisStringAsyncCommands;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;
import java.time.Duration;

/** A Lettuce client with async capabilities see: https://lettuce.io/ */
public class LettuceAsyncClient implements AsyncClient<String> {
static final int ASYNC_OPERATION_TIMEOUT_SEC = 1;

private AbstractRedisClient client;
private RedisStringAsyncCommands<String, String> asyncCommands;
private StatefulConnection<String, String> connection;

@Override
public void connectToRedis(ConnectionSettings connectionSettings) {
RedisURI uri =
RedisURI.builder()
.withHost(connectionSettings.host)
.withPort(connectionSettings.port)
.withSsl(connectionSettings.useSsl)
.build();
if (connectionSettings.clusterMode) {
client = RedisClient.create(uri);
connection = ((RedisClient) client).connect();
asyncCommands = ((StatefulRedisConnection<String, String>) connection).async();
} else {
client = RedisClusterClient.create(uri);
connection = ((RedisClusterClient) client).connect();
asyncCommands = ((StatefulRedisClusterConnection<String, String>) connection).async();
}
connection.setTimeout(Duration.ofSeconds(ASYNC_OPERATION_TIMEOUT_SEC));
}

@Override
public RedisFuture<String> asyncSet(String key, String value) {
return asyncCommands.set(key, value);
}

@Override
public RedisFuture<String> asyncGet(String key) {
return asyncCommands.get(key);
}

@Override
public void closeConnection() {
connection.close();
client.shutdown();
}

@Override
public String getName() {
return "Lettuce Async";
}
}
Loading