This is an automated email from the ASF dual-hosted git repository.
korlov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new 5376caa9e6 IGNITE-19575 Extend jmh benchmarks to compare thin clients
against its embedded counterparts (#2108)
5376caa9e6 is described below
commit 5376caa9e6ddf0f82e462818c51feca3a6db4216
Author: korlov42 <[email protected]>
AuthorDate: Wed May 31 13:37:13 2023 +0300
IGNITE-19575 Extend jmh benchmarks to compare thin clients against its
embedded counterparts (#2108)
---
.../internal/jdbc/JdbcPreparedStatement.java | 2 -
.../benchmark/AbstractOneNodeBenchmark.java | 7 +-
.../ignite/internal/benchmark/InsertBenchmark.java | 142 +++++++++++++++++---
.../ignite/internal/benchmark/SelectBenchmark.java | 148 +++++++++++++++------
4 files changed, 243 insertions(+), 56 deletions(-)
diff --git
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcPreparedStatement.java
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcPreparedStatement.java
index e303e3335a..a95c6946a0 100644
---
a/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcPreparedStatement.java
+++
b/modules/jdbc/src/main/java/org/apache/ignite/internal/jdbc/JdbcPreparedStatement.java
@@ -762,8 +762,6 @@ public class JdbcPreparedStatement extends JdbcStatement
implements PreparedStat
currentArgs.stream().map(this::convertJdbcTypeToInternal).toArray();
execute0(statementType, sql, args);
-
- currentArgs = null;
}
private static void checkType(int sqlType) throws SQLException {
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/AbstractOneNodeBenchmark.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/AbstractOneNodeBenchmark.java
index ed1e063889..f578776261 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/AbstractOneNodeBenchmark.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/AbstractOneNodeBenchmark.java
@@ -36,6 +36,7 @@ import org.apache.ignite.internal.sql.engine.SqlQueryType;
import org.apache.ignite.internal.sql.engine.session.SessionId;
import org.apache.ignite.internal.testframework.TestIgnitionManager;
import org.intellij.lang.annotations.Language;
+import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
@@ -57,6 +58,9 @@ public class AbstractOneNodeBenchmark {
protected static IgniteImpl clusterNode;
+ @Param({"true", "false"})
+ private boolean fsync;
+
/**
* Starts ignite node and creates table {@link #TABLE_NAME}.
*/
@@ -69,7 +73,8 @@ public class AbstractOneNodeBenchmark {
+ " nodeFinder:{\n"
+ " netClusterNodes: [ \"localhost:" + PORT + "\"]
\n"
+ " }\n"
- + "}";
+ + "},"
+ + "raft.fsync = " + fsync;
var fut = TestIgnitionManager.start(NODE_NAME, config,
workDir.resolve(NODE_NAME));
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/InsertBenchmark.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/InsertBenchmark.java
index 46b87e8ad5..efa519508d 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/InsertBenchmark.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/InsertBenchmark.java
@@ -18,6 +18,7 @@
package org.apache.ignite.internal.benchmark;
import static java.util.stream.Collectors.joining;
+import static org.apache.ignite.lang.IgniteStringFormatter.format;
import java.sql.Connection;
import java.sql.DriverManager;
@@ -25,6 +26,7 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
+import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.sql.IgniteSql;
import org.apache.ignite.sql.Session;
@@ -49,10 +51,10 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
* Benchmark for insertion operation, comparing KV, JDBC and SQL APIs.
*/
@State(Scope.Benchmark)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
public class InsertBenchmark extends AbstractOneNodeBenchmark {
/**
- * Benchmark for SQL insert.
+ * Benchmark for SQL insert via embedded client.
*/
@Benchmark
@Warmup(iterations = 1, time = 10)
@@ -62,7 +64,7 @@ public class InsertBenchmark extends AbstractOneNodeBenchmark
{
}
/**
- * Benchmark for KV insert.
+ * Benchmark for KV insert via embedded client.
*/
@Benchmark
@Warmup(iterations = 1, time = 10)
@@ -81,22 +83,44 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
state.executeQuery();
}
+ /**
+ * Benchmark for SQL insert via thin client.
+ */
+ @Benchmark
+ @Warmup(iterations = 1, time = 10)
+ @Measurement(iterations = 1, time = 20)
+ public void sqlThinInsert(SqlThinState state) {
+ state.executeQuery();
+ }
+
+ /**
+ * Benchmark for KV insert via thin client.
+ */
+ @Benchmark
+ @Warmup(iterations = 1, time = 10)
+ @Measurement(iterations = 1, time = 20)
+ public void kvThinInsert(KvThinState state) {
+ state.executeQuery();
+ }
+
/**
* Benchmark's entry point.
*/
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + InsertBenchmark.class.getSimpleName() + ".*")
- .forks(0)
+ .forks(1)
.threads(1)
- .mode(Mode.SampleTime)
+ .mode(Mode.AverageTime)
.build();
new Runner(opt).run();
}
/**
- * Benchmark state for {@link #sqlInsert(SqlState)}. Holds {@link Session}
and {@link Statement}.
+ * Benchmark state for {@link #sqlInsert(SqlState)}.
+ *
+ * <p>Holds {@link Session} and {@link Statement}.
*/
@State(Scope.Benchmark)
public static class SqlState {
@@ -108,10 +132,7 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
*/
@Setup
public void setUp() {
- String fieldsQ = IntStream.range(1, 11).mapToObj(i -> "field" +
i).collect(joining(","));
- String valQ = IntStream.range(1, 11).mapToObj(i -> "'" + FIELD_VAL
+ "'").collect(joining(","));
-
- String queryStr = String.format("insert into %s(%s, %s) values(?,
%s);", TABLE_NAME, "ycsb_key", fieldsQ, valQ);
+ String queryStr = createInsertStatement();
IgniteSql sql = clusterNode.sql();
@@ -136,7 +157,51 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
}
/**
- * Benchmark state for {@link #jdbcInsert(JdbcState)}. Holds {@link
Connection} and {@link PreparedStatement}.
+ * Benchmark state for {@link #sqlThinInsert(SqlThinState)}.
+ *
+ * <p>Holds {@link Session}, {@link IgniteClient}, and {@link Statement}.
+ */
+ @State(Scope.Benchmark)
+ public static class SqlThinState {
+ private IgniteClient client;
+ private Statement statement;
+ private Session session;
+
+ /**
+ * Initializes session and statement.
+ */
+ @Setup
+ public void setUp() {
+ String queryStr = createInsertStatement();
+
+ client =
IgniteClient.builder().addresses("127.0.0.1:10800").build();
+
+ IgniteSql sql = client.sql();
+
+ statement = sql.createStatement(queryStr);
+ session = sql.createSession();
+ }
+
+ /**
+ * Closes resources.
+ */
+ @TearDown
+ public void tearDown() throws Exception {
+ // statement.close() throws `UnsupportedOperationException("Not
implemented yet.")`, that's why it's commented.
+ IgniteUtils.closeAll(session/*, statement*/, client);
+ }
+
+ private int id = 0;
+
+ void executeQuery() {
+ session.execute(null, statement, id++);
+ }
+ }
+
+ /**
+ * Benchmark state for {@link #jdbcInsert(JdbcState)}.
+ *
+ * <p>Holds {@link Connection} and {@link PreparedStatement}.
*/
@State(Scope.Benchmark)
public static class JdbcState {
@@ -151,10 +216,7 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
*/
@Setup
public void setUp() throws SQLException {
- String fieldsQ = IntStream.range(1, 11).mapToObj(i -> "field" +
i).collect(joining(","));
- String valQ = IntStream.range(1, 11).mapToObj(i -> "'" + FIELD_VAL
+ "'").collect(joining(","));
-
- String queryStr = String.format("insert into %s(%s, %s) values(?,
%s);", TABLE_NAME, "ycsb_key", fieldsQ, valQ);
+ String queryStr = createInsertStatement();
//noinspection CallToDriverManagerGetConnection
conn =
DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:10800/");
@@ -177,7 +239,9 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
}
/**
- * Benchmark state for {@link #kvInsert(KvState)}. Holds {@link Tuple} and
{@link KeyValueView} for the table.
+ * Benchmark state for {@link #kvInsert(KvState)}.
+ *
+ * <p>Holds {@link Tuple} and {@link KeyValueView} for the table.
*/
@State(Scope.Benchmark)
public static class KvState {
@@ -201,4 +265,50 @@ public class InsertBenchmark extends
AbstractOneNodeBenchmark {
kvView.put(null, Tuple.create().set("ycsb_key", id++), tuple);
}
}
+
+ /**
+ * Benchmark state for {@link #kvThinInsert(KvThinState)}.
+ *
+ * <p>Holds {@link Tuple}, {@link IgniteClient}, and {@link KeyValueView}
for the table.
+ */
+ @State(Scope.Benchmark)
+ public static class KvThinState {
+ private final Tuple tuple = Tuple.create();
+
+ private IgniteClient client;
+ private KeyValueView<Tuple, Tuple> kvView;
+
+ private int id = 0;
+
+ /**
+ * Initializes the tuple.
+ */
+ @Setup
+ public void setUp() {
+ for (int i = 1; i < 11; i++) {
+ tuple.set("field" + i, FIELD_VAL);
+ }
+
+ client =
IgniteClient.builder().addresses("127.0.0.1:10800").build();
+ kvView = client.tables().table(TABLE_NAME).keyValueView();
+ }
+
+ @TearDown
+ public void tearDown() throws Exception {
+ IgniteUtils.closeAll(client);
+ }
+
+ void executeQuery() {
+ kvView.put(null, Tuple.create().set("ycsb_key", id++), tuple);
+ }
+ }
+
+ private static String createInsertStatement() {
+ String insertQueryTemplate = "insert into {}({}, {}) values(?, {})";
+
+ String fieldsQ = IntStream.range(1, 11).mapToObj(i -> "field" +
i).collect(joining(","));
+ String valQ = IntStream.range(1, 11).mapToObj(i -> "'" + FIELD_VAL +
"'").collect(joining(","));
+
+ return format(insertQueryTemplate, TABLE_NAME, "ycsb_key", fieldsQ,
valQ);
+ }
}
diff --git
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SelectBenchmark.java
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SelectBenchmark.java
index 44f05b64dc..0a9fbdd462 100644
---
a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SelectBenchmark.java
+++
b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SelectBenchmark.java
@@ -17,25 +17,19 @@
package org.apache.ignite.internal.benchmark;
-import static
org.apache.ignite.internal.sql.engine.property.PropertiesHelper.newBuilder;
-import static
org.apache.ignite.internal.sql.engine.util.CursorUtils.getAllFromCursor;
-import static org.apache.ignite.internal.testframework.IgniteTestUtils.await;
-
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
-import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;
-import org.apache.ignite.internal.sql.engine.QueryContext;
-import org.apache.ignite.internal.sql.engine.QueryProcessor;
-import org.apache.ignite.internal.sql.engine.QueryProperty;
-import org.apache.ignite.internal.sql.engine.SqlQueryType;
-import org.apache.ignite.internal.sql.engine.session.SessionId;
+import org.apache.ignite.client.IgniteClient;
import org.apache.ignite.internal.util.IgniteUtils;
+import org.apache.ignite.sql.IgniteSql;
+import org.apache.ignite.sql.Session;
+import org.apache.ignite.sql.SqlRow;
import org.apache.ignite.table.KeyValueView;
import org.apache.ignite.table.Tuple;
import org.openjdk.jmh.annotations.Benchmark;
@@ -57,7 +51,11 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
*/
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@SuppressWarnings({"WeakerAccess", "unused"})
public class SelectBenchmark extends AbstractOneNodeBenchmark {
+ private static final int TABLE_SIZE = 30_000;
+ private static final String SELECT_ALL_FROM_USERTABLE = "select * from
usertable where ycsb_key = ?";
+
private final Random random = new Random();
private KeyValueView<Tuple, Tuple> keyValueView;
@@ -71,7 +69,7 @@ public class SelectBenchmark extends AbstractOneNodeBenchmark
{
keyValueView = clusterNode.tables().table(TABLE_NAME).keyValueView();
- for (int i = 0; i < 1000; i++) {
+ for (int i = 0; i < TABLE_SIZE; i++) {
Tuple t = Tuple.create();
for (int j = 1; j <= 10; j++) {
t.set("field" + j, FIELD_VAL);
@@ -82,13 +80,27 @@ public class SelectBenchmark extends
AbstractOneNodeBenchmark {
}
/**
- * Benchmark for SQL select.
+ * Benchmark for SQL select via embedded client.
*/
@Benchmark
@Warmup(iterations = 1, time = 10)
@Measurement(iterations = 1, time = 20)
public void sqlGet(SqlState sqlState) {
- sqlState.sql("select * from usertable where ycsb_key = " +
random.nextInt(1000));
+ try (var rs = sqlState.sql(SELECT_ALL_FROM_USERTABLE,
random.nextInt(TABLE_SIZE))) {
+ rs.next();
+ }
+ }
+
+ /**
+ * Benchmark for SQL select via thin client.
+ */
+ @Benchmark
+ @Warmup(iterations = 1, time = 10)
+ @Measurement(iterations = 1, time = 20)
+ public void sqlThinGet(SqlThinState sqlState) {
+ try (var rs = sqlState.sql(SELECT_ALL_FROM_USERTABLE,
random.nextInt(TABLE_SIZE))) {
+ rs.next();
+ }
}
/**
@@ -98,20 +110,30 @@ public class SelectBenchmark extends
AbstractOneNodeBenchmark {
@Warmup(iterations = 1, time = 10)
@Measurement(iterations = 1, time = 20)
public void jdbcGet(JdbcState state) throws SQLException {
- state.stmt.setInt(1, random.nextInt(1000));
+ state.stmt.setInt(1, random.nextInt(TABLE_SIZE));
try (ResultSet r = state.stmt.executeQuery()) {
r.next();
}
}
/**
- * Benchmark for KV get.
+ * Benchmark for KV get via embedded client.
*/
@Benchmark
@Warmup(iterations = 1, time = 10)
@Measurement(iterations = 1, time = 20)
public void kvGet() {
- keyValueView.get(null, Tuple.create().set("ycsb_key",
random.nextInt(1000)));
+ keyValueView.get(null, Tuple.create().set("ycsb_key",
random.nextInt(TABLE_SIZE)));
+ }
+
+ /**
+ * Benchmark for KV get via thin client.
+ */
+ @Benchmark
+ @Warmup(iterations = 1, time = 10)
+ @Measurement(iterations = 1, time = 20)
+ public void kvThinGet(KvThinState kvState) {
+ kvState.kvView().get(null, Tuple.create().set("ycsb_key",
random.nextInt(TABLE_SIZE)));
}
/**
@@ -120,52 +142,75 @@ public class SelectBenchmark extends
AbstractOneNodeBenchmark {
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(".*" + SelectBenchmark.class.getSimpleName() + ".*")
- .forks(0)
+ .forks(1)
.threads(1)
- .mode(Mode.SampleTime)
+ .mode(Mode.AverageTime)
.build();
new Runner(opt).run();
}
/**
- * Benchmark state for {@link #sqlGet(SqlState)}. Holds {@link
QueryProcessor} and {@link SessionId}.
+ * Benchmark state for {@link #sqlGet(SqlState)}.
+ *
+ * <p>Holds {@link Session}.
*/
@State(Scope.Benchmark)
public static class SqlState {
- QueryProcessor queryProcessor = clusterNode.queryEngine();
+ private final Session session = clusterNode.sql().createSession();
+
+ /**
+ * Closes resources.
+ */
+ @TearDown
+ public void tearDown() throws Exception {
+ IgniteUtils.closeAll(session);
+ }
- SessionId sessionId;
+ private org.apache.ignite.sql.ResultSet<SqlRow> sql(String sql,
Object... args) {
+ return session.execute(null, sql, args);
+ }
+ }
+
+ /**
+ * Benchmark state for {@link #sqlThinGet(SqlThinState)}.
+ *
+ * <p>Holds {@link IgniteClient} and {@link Session}.
+ */
+ @State(Scope.Benchmark)
+ public static class SqlThinState {
+ private IgniteClient client;
+ private Session session;
/**
- * Initializes session.
+ * Initializes session and statement.
*/
@Setup
public void setUp() {
- sessionId = queryProcessor.createSession(newBuilder()
- .set(QueryProperty.DEFAULT_SCHEMA, "PUBLIC")
- .set(QueryProperty.QUERY_TIMEOUT,
TimeUnit.SECONDS.toMillis(20))
- .build()
- );
+ client =
IgniteClient.builder().addresses("127.0.0.1:10800").build();
+
+ IgniteSql sql = client.sql();
+
+ session = sql.createSession();
}
/**
* Closes resources.
*/
@TearDown
- public void tearDown() {
- queryProcessor.closeSession(sessionId);
+ public void tearDown() throws Exception {
+ IgniteUtils.closeAll(session, client);
}
- private List<List<Object>> sql(String sql, Object... args) {
- var context = QueryContext.create(SqlQueryType.ALL);
-
- return
getAllFromCursor(await(queryProcessor.querySingleAsync(sessionId, context, sql,
args)));
+ org.apache.ignite.sql.ResultSet<SqlRow> sql(String query, Object...
args) {
+ return session.execute(null, query, args);
}
}
/**
- * Benchmark state for {@link #jdbcGet(JdbcState)}. Holds {@link
Connection} and {@link PreparedStatement}.
+ * Benchmark state for {@link #jdbcGet(JdbcState)}.
+ *
+ * <p>Holds {@link Connection} and {@link PreparedStatement}.
*/
@State(Scope.Benchmark)
public static class JdbcState {
@@ -178,13 +223,11 @@ public class SelectBenchmark extends
AbstractOneNodeBenchmark {
*/
@Setup
public void setUp() {
- String queryStr = "select * from " + TABLE_NAME + " where ycsb_key
= ?";
-
try {
//noinspection CallToDriverManagerGetConnection
conn =
DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1:10800/");
- stmt = conn.prepareStatement(queryStr);
+ stmt = conn.prepareStatement(SELECT_ALL_FROM_USERTABLE);
} catch (SQLException e) {
throw new RuntimeException(e);
}
@@ -195,4 +238,35 @@ public class SelectBenchmark extends
AbstractOneNodeBenchmark {
IgniteUtils.closeAll(stmt, conn);
}
}
+
+ /**
+ * Benchmark state for {@link #kvThinGet(KvThinState)}.
+ *
+ * <p>Holds {@link IgniteClient} and {@link KeyValueView} for the table.
+ */
+ @State(Scope.Benchmark)
+ public static class KvThinState {
+ private IgniteClient client;
+ private KeyValueView<Tuple, Tuple> kvView;
+
+ /**
+ * Creates the client.
+ */
+ @Setup
+ public void setUp() {
+ client =
IgniteClient.builder().addresses("127.0.0.1:10800").build();
+ kvView = client.tables().table(TABLE_NAME).keyValueView();
+ }
+
+ @TearDown
+ public void tearDown() throws Exception {
+ IgniteUtils.closeAll(client);
+ }
+
+ KeyValueView<Tuple, Tuple> kvView() {
+ return kvView;
+ }
+ }
}
+
+