-
Notifications
You must be signed in to change notification settings - Fork 70
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
Changes from 7 commits
ddc71b4
07cfd8b
07e98db
fb41f7a
8e6c565
ec04c28
f6fbbb7
6635229
fb755af
af3df15
3e0f70b
874a4de
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
[env] | ||
BABUSHKA_NAME = { value = "javababushka", force = true } | ||
BABUSHKA_VERSION = "0.1.0" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,11 +6,11 @@ language api to enhance performance and limit cpu cycles at scale. | |
|
||
## Organization | ||
|
||
The Java client (javababushka) contains the following parts: | ||
The Java client contains the following parts: | ||
|
||
1. A Java client (lib folder): wrapper to rust-client. | ||
2. An examples script: to sanity test javababushka and similar java-clients against a redis host. | ||
3. A benchmark app: to performance benchmark test javababushka and similar java-clients against a redis host. | ||
2. An examples script: to sanity test babushka and similar java-clients against a redis host. | ||
3. A benchmark app: to performance benchmark test babushka and similar java-clients against a redis host. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A benchmark app: A dedicated benchmarking tool designed to evaluate and compare the performance of Babushka and other Java clients. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Updated in 3e0f70b |
||
|
||
## Building | ||
|
||
|
@@ -47,4 +47,3 @@ The following arguments are accepted: | |
* 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. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package javababushka.benchmarks; | ||
package babushka.benchmarks; | ||
|
||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
|
@@ -30,7 +30,7 @@ public static void main(String[] args) { | |
// generate the help statement | ||
if (line.hasOption("help")) { | ||
HelpFormatter formatter = new HelpFormatter(); | ||
formatter.printHelp("javababushka", options); | ||
formatter.printHelp("babushka", options); | ||
return; | ||
} | ||
|
||
|
@@ -46,10 +46,6 @@ public static void main(String[] args) { | |
// run testClientSetGet on JEDIS sync client | ||
System.out.println("Run JEDIS sync client"); | ||
break; | ||
case JEDIS_ASYNC: | ||
// run testClientSetGet on JEDIS pseudo-async client | ||
System.out.println("Run JEDIS pseudo-async client"); | ||
break; | ||
case LETTUCE: | ||
// run testClientSetGet on LETTUCE sync client | ||
System.out.println("Run LETTUCE sync client"); | ||
|
@@ -97,7 +93,7 @@ private static Options getOptions() { | |
.hasArg(true) | ||
.desc( | ||
"one of:" | ||
+ " all|jedis|jedis_async|lettuce|lettuce_async|babushka_async|all_async|all_sync" | ||
+ " all|jedis|lettuce|lettuce_async|babushka_async|all_async|all_sync" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commented on prev PR - make sure to rebase over the changes commited there |
||
+ " [all]") | ||
.build()); | ||
options.addOption(Option.builder("host").hasArg(true).desc("Hostname [localhost]").build()); | ||
|
@@ -150,13 +146,11 @@ private static RunConfiguration verifyOptions(CommandLine line) throws ParseExce | |
case ALL: | ||
return Stream.of( | ||
ClientName.JEDIS, | ||
ClientName.JEDIS_ASYNC, | ||
// ClientName.BABUSHKA_ASYNC, | ||
ClientName.LETTUCE, | ||
ClientName.LETTUCE_ASYNC); | ||
case ALL_ASYNC: | ||
return Stream.of( | ||
ClientName.JEDIS_ASYNC, | ||
// ClientName.BABUSHKA_ASYNC, | ||
ClientName.LETTUCE_ASYNC); | ||
case ALL_SYNC: | ||
|
@@ -205,7 +199,6 @@ private static int[] parseIntListOption(String line) throws ParseException { | |
|
||
public enum ClientName { | ||
JEDIS("Jedis"), | ||
JEDIS_ASYNC("Jedis async"), | ||
LETTUCE("Lettuce"), | ||
LETTUCE_ASYNC("Lettuce async"), | ||
BABUSHKA_ASYNC("Babushka async"), | ||
|
@@ -249,7 +242,7 @@ public RunConfiguration() { | |
clients = | ||
new ClientName[] { | ||
// ClientName.BABUSHKA_ASYNC, | ||
ClientName.JEDIS, ClientName.JEDIS_ASYNC, ClientName.LETTUCE, ClientName.LETTUCE_ASYNC | ||
ClientName.JEDIS, ClientName.LETTUCE, ClientName.LETTUCE_ASYNC | ||
}; | ||
host = "localhost"; | ||
port = 6379; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package babushka.benchmarks.clients; | ||
|
||
import java.util.concurrent.Future; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** A Redis client with async capabilities */ | ||
public interface AsyncClient<T> extends Client { | ||
|
||
long DEFAULT_TIMEOUT_MILLISECOND = 1000; | ||
|
||
Future<T> asyncSet(String key, String value); | ||
|
||
Future<String> asyncGet(String key); | ||
|
||
default <T> T waitForResult(Future<T> future) { | ||
return waitForResult(future, DEFAULT_TIMEOUT_MILLISECOND); | ||
} | ||
|
||
default <T> T waitForResult(Future<T> future, long timeout) { | ||
try { | ||
return future.get(timeout, TimeUnit.MILLISECONDS); | ||
} catch (Exception ignored) { | ||
return null; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package babushka.benchmarks.clients; | ||
|
||
import babushka.benchmarks.utils.ConnectionSettings; | ||
|
||
/** A Redis client interface */ | ||
public interface Client { | ||
void connectToRedis(ConnectionSettings connectionSettings); | ||
|
||
default void closeConnection() {} | ||
|
||
String getName(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package babushka.benchmarks.clients; | ||
|
||
/** A Redis client with sync capabilities */ | ||
public interface SyncClient extends Client { | ||
void set(String key, String value); | ||
|
||
String get(String key); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package babushka.benchmarks.clients.babushka; | ||
|
||
/* | ||
|
||
public class JniNettyClient implements SyncClient, AsyncClient<Response> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please remove it from this PR and add it when the java-babushka will be added There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed in 3e0f70b. |
||
|
||
private final Client testClient; | ||
private String name = "JNI Netty"; | ||
|
||
public JniNettyClient(boolean async) { | ||
name += async ? " async" : " sync"; | ||
testClient = new Client(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return name; | ||
} | ||
|
||
@Override | ||
public void closeConnection() { | ||
testClient.closeConnection(); | ||
} | ||
|
||
@Override | ||
public void connectToRedis(ConnectionSettings connectionSettings) { | ||
waitForResult(asyncConnectToRedis(connectionSettings)); | ||
} | ||
|
||
@Override | ||
public Future<Response> asyncSet(String key, String value) { | ||
return testClient.asyncSet(key, value); | ||
} | ||
|
||
@Override | ||
public Future<String> asyncGet(String key) { | ||
return testClient.asyncGet(key); | ||
} | ||
|
||
@Override | ||
public void set(String key, String value) { | ||
testClient.set(key, value); | ||
} | ||
|
||
@Override | ||
public String get(String key) { | ||
return testClient.get(key); | ||
} | ||
} | ||
*/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package babushka.benchmarks.clients.jedis; | ||
|
||
import babushka.benchmarks.clients.SyncClient; | ||
import babushka.benchmarks.utils.ConnectionSettings; | ||
import redis.clients.jedis.Jedis; | ||
import redis.clients.jedis.JedisPool; | ||
|
||
/** A Jedis client with sync capabilities. See: https://github.com/redis/jedis */ | ||
public class JedisClient implements SyncClient { | ||
|
||
protected JedisPool pool; | ||
|
||
@Override | ||
public void closeConnection() { | ||
// nothing to do | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "Jedis"; | ||
} | ||
|
||
@Override | ||
public void connectToRedis(ConnectionSettings connectionSettings) { | ||
pool = | ||
new JedisPool(connectionSettings.host, connectionSettings.port, connectionSettings.useSsl); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like you're not testing Jedis in a cluster mode at all, redis cluster should be used with JedisCluster There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 3e0f70b. |
||
|
||
// check if the pool is properly connected | ||
try (Jedis jedis = pool.getResource()) { | ||
assert jedis.isConnected() : "failed to connect to jedis"; | ||
} | ||
} | ||
|
||
public String info() { | ||
try (Jedis jedis = pool.getResource()) { | ||
return jedis.info(); | ||
} | ||
} | ||
|
||
public String info(String section) { | ||
try (Jedis jedis = pool.getResource()) { | ||
return jedis.info(section); | ||
} | ||
} | ||
|
||
@Override | ||
public void set(String key, String value) { | ||
try (Jedis jedis = pool.getResource()) { | ||
jedis.set(key, value); | ||
} | ||
} | ||
|
||
@Override | ||
public String get(String key) { | ||
try (Jedis jedis = pool.getResource()) { | ||
return jedis.get(key); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package babushka.benchmarks.clients.lettuce; | ||
|
||
import babushka.benchmarks.clients.AsyncClient; | ||
import babushka.benchmarks.utils.ConnectionSettings; | ||
import io.lettuce.core.RedisClient; | ||
import io.lettuce.core.RedisFuture; | ||
import io.lettuce.core.api.StatefulRedisConnection; | ||
import io.lettuce.core.api.async.RedisAsyncCommands; | ||
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 RedisClient client; | ||
private RedisAsyncCommands asyncCommands; | ||
private StatefulRedisConnection<String, String> connection; | ||
|
||
@Override | ||
public void connectToRedis(ConnectionSettings connectionSettings) { | ||
client = | ||
RedisClient.create( | ||
String.format( | ||
"%s://%s:%d", | ||
connectionSettings.useSsl ? "rediss" : "redis", | ||
connectionSettings.host, | ||
connectionSettings.port)); | ||
connection = client.connect(); | ||
connection.setTimeout(Duration.ofSeconds(ASYNC_OPERATION_TIMEOUT_SEC)); | ||
asyncCommands = connection.async(); | ||
} | ||
|
||
@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"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* This Java source file was generated by the Gradle 'init' task. | ||
*/ | ||
package babushka.benchmarks.clients.lettuce; | ||
|
||
import babushka.benchmarks.utils.ConnectionSettings; | ||
import io.lettuce.core.RedisFuture; | ||
import io.lettuce.core.RedisURI; | ||
import io.lettuce.core.cluster.RedisClusterClient; | ||
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; | ||
import io.lettuce.core.cluster.api.async.RedisAdvancedClusterAsyncCommands; | ||
import java.time.Duration; | ||
|
||
public class LettuceAsyncClusterClient extends LettuceAsyncClient { | ||
|
||
private RedisClusterClient clusterClient; | ||
private RedisAdvancedClusterAsyncCommands clusterAsyncCommands; | ||
private StatefulRedisClusterConnection<String, String> clusterConnection; | ||
|
||
@Override | ||
public void connectToRedis(ConnectionSettings connectionSettings) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Yury-Fridlyand I think that the same as you did for Jedis, no need to have a separate file for LettuceClusterClient, you can use LettuceAsyncClient both for standalone and cluster |
||
RedisURI uri = | ||
RedisURI.builder() | ||
.withHost(connectionSettings.host) | ||
.withPort(connectionSettings.port) | ||
.withSsl(connectionSettings.useSsl) | ||
.build(); | ||
clusterClient = RedisClusterClient.create(uri); | ||
clusterConnection = clusterClient.connect(); | ||
clusterConnection.setTimeout(Duration.ofSeconds(ASYNC_OPERATION_TIMEOUT_SEC)); | ||
clusterAsyncCommands = clusterConnection.async(); | ||
} | ||
|
||
@Override | ||
public RedisFuture<String> asyncSet(String key, String value) { | ||
return clusterAsyncCommands.set(key, value); | ||
} | ||
|
||
@Override | ||
public RedisFuture<String> asyncGet(String key) { | ||
return clusterAsyncCommands.get(key); | ||
} | ||
|
||
@Override | ||
public void closeConnection() { | ||
clusterConnection.close(); | ||
clusterClient.shutdown(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "Lettuce Cluster Async"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package babushka.benchmarks.utils; | ||
|
||
/** Redis-client settings */ | ||
public class ConnectionSettings { | ||
public final String host; | ||
public final int port; | ||
public final boolean useSsl; | ||
public final boolean clusterMode; | ||
|
||
public ConnectionSettings(String host, int port, boolean useSsl, boolean clusterMode) { | ||
this.host = host; | ||
this.port = port; | ||
this.useSsl = useSsl; | ||
this.clusterMode = clusterMode; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't find this script?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And we don't want the examples folder to contain examples of other clients, only babushka
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does not exist yet (as well as the client itself)
Updated in 3e0f70b.