Skip to content

Commit c60c8b4

Browse files
committed
Caching performance testing program on Postgres.
The postgres test table contains 11 columns containing different data types. The example program populates the table with 400K records, each record has > 1KB of data, for a total of ~520MB of data in the table. It then performs SELECT queries continuously across all 400K rows. postgres=# CREATE TABLE test (id SERIAL PRIMARY KEY, int_col INTEGER, varchar_col varchar(50) NOT NULL, text_col TEXT, num_col DOUBLE PRECISION, date_col date, time_col TIME WITHOUT TIME ZONE, time_tz TIME WITH TIME ZONE, ts_col TIMESTAMP WITHOUT TIME ZONE, ts_tz TIMESTAMP WITH TIME ZONE), description TEXT; CREATE TABLE postgres=# select * from test; id | int_col | varchar_col | text_col | num_col | date_col | time_col | time_tz | ts_col | ts_tz | description ----+---------+-------------+----------+---------+----------+----------+---------+--------+-------+-------------- (0 rows) Suppress debug logs and only log at INFO level and above for example program.
1 parent 758b829 commit c60c8b4

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

benchmarks/build.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ dependencies {
2525
implementation("org.mariadb.jdbc:mariadb-java-client:3.5.6")
2626
implementation("com.zaxxer:HikariCP:4.0.3")
2727
implementation("org.checkerframework:checker-qual:3.49.5")
28+
implementation("io.lettuce:lettuce-core:6.6.0.RELEASE")
29+
implementation("org.apache.commons:commons-pool2:2.11.1")
30+
annotationProcessor("org.openjdk.jmh:jmh-core:1.36")
31+
jmhAnnotationProcessor ("org.openjdk.jmh:jmh-generator-annprocess:1.36")
2832

2933
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
3034
testImplementation("org.mockito:mockito-inline:4.11.0") // 4.11.0 is the last version compatible with Java 8
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package software.amazon.jdbc.benchmarks;
2+
3+
import org.openjdk.jmh.annotations.*;
4+
import java.sql.*;
5+
import java.util.*;
6+
import java.util.concurrent.TimeUnit;
7+
8+
import org.openjdk.jmh.profile.GCProfiler;
9+
import org.openjdk.jmh.runner.Runner;
10+
import org.openjdk.jmh.runner.RunnerException;
11+
import org.openjdk.jmh.runner.options.Options;
12+
import org.openjdk.jmh.runner.options.OptionsBuilder;
13+
14+
/**
15+
* Performance benchmark program against PG.
16+
*
17+
* This test program runs JMH benchmark tests the performance of the remote cache plugin against a
18+
* a remote PG database and a remote cache server for both indexed queries and non-indexed queries.
19+
*
20+
* The database table schema is as follows:
21+
*
22+
* postgres=# CREATE TABLE test (id SERIAL PRIMARY KEY, int_col INTEGER, varchar_col varchar(50) NOT NULL, text_col TEXT,
23+
* num_col DOUBLE PRECISION, date_col date, time_col TIME WITHOUT TIME ZONE, time_tz TIME WITH TIME ZONE,
24+
* ts_col TIMESTAMP WITHOUT TIME ZONE, ts_tz TIMESTAMP WITH TIME ZONE, description TEXT);
25+
* CREATE TABLE
26+
* postgres=# select * from test;
27+
* id | int_col | varchar_col | text_col | num_col | date_col | time_col | time_tz | ts_col | ts_tz | description
28+
* ----+---------+-------------+----------+---------+----------+----------+---------+--------+-------+--------------
29+
* (0 rows)
30+
*
31+
*/
32+
@State(Scope.Thread)
33+
@Fork(1)
34+
@Warmup(iterations = 1)
35+
@Measurement(iterations = 60, time = 1)
36+
@BenchmarkMode(Mode.AverageTime)
37+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
38+
public class PgCacheBenchmarks {
39+
private static final String DB_CONNECTION_STRING = "jdbc:aws-wrapper:postgresql://db-0.XYZ.us-east-2.rds.amazonaws.com:5432/postgres";
40+
private static final String CACHE_RW_SERVER_ADDR = "cache-0.XYZ.us-east-2.rds.amazonaws.com:6379";
41+
private static final String CACHE_RO_SERVER_ADDR = "cache-0.XYZ.us-east-2.rds.amazonaws.com:6380";
42+
43+
private Connection connection;
44+
private int counter;
45+
long startTime;
46+
47+
public static void main(String[] args) throws RunnerException {
48+
Options opt = new OptionsBuilder()
49+
.include(PgCacheBenchmarks.class.getSimpleName())
50+
.addProfiler(GCProfiler.class)
51+
.detectJvmArgs()
52+
.build();
53+
54+
new Runner(opt).run();
55+
}
56+
57+
@Setup(Level.Trial)
58+
public void setup() throws SQLException {
59+
try {
60+
software.amazon.jdbc.Driver.register();
61+
} catch (IllegalStateException e) {
62+
System.out.println("exception during register() is " + e.getMessage());
63+
}
64+
Properties properties = new Properties();
65+
properties.setProperty("wrapperPlugins", "dataRemoteCache");
66+
properties.setProperty("cacheEndpointAddrRw", CACHE_RW_SERVER_ADDR);
67+
properties.setProperty("cacheEndpointAddrRo", CACHE_RO_SERVER_ADDR);
68+
properties.setProperty("wrapperLogUnclosedConnections", "true");
69+
counter = 0;
70+
connection = DriverManager.getConnection(DB_CONNECTION_STRING, properties);
71+
startTime = System.currentTimeMillis();
72+
}
73+
74+
@TearDown(Level.Trial)
75+
public void tearDown() throws SQLException {
76+
connection.close();
77+
}
78+
79+
// Code to warm up the data in the table
80+
public void warmUpDataSet() throws SQLException {
81+
String desc_1KB = "mP48pHrR5vreBo3N6ecmlDgvfEAz0kQEOUQ89U3Rh05BTG9LhB8R0HBFBp5RIqc8vVcrphu89kW1OE2c2xApwpczFMdDAuk2SxOl9OrLvfk9zGYrdfzedcepT8LVeE6NTtYDeP3yo6UFC6AiOeqRBY5NEaNcZ8fuoXVpqOrqAhz910v5XrFxeXUyPDFxuaKFLaHfEFq7BRasUc9nfhP8gblKAGfEEmgYBpUKio27Rfo0xnavfVJQkAA2kME2PT4qZRSqeDkLmn7VBAzT9ghHqe9D4kQLQKjIyIPKqYoS8kW3ShW44VqYENwPSRAXw7UqOJqlKJ4pnmx4sPZO2kI4NYOl1JZXNlbGaSzJR0cOloKiY0z2OmUNvmD0Wju1DC9TT4OY6a6DOfFvk265BfDVxT6ufN68YG9sZuVsl7jq8SZSJg3x2cqlJuAtdSTIoKmJT1a6cEXxVusmdO27kRRp1BfWR4gz4w9HawYf9nBQOq76ObctlNvj0fYUUG3I49s3iP33CL8qZjj9RnyNUus6ieiZgta6L3mZuMRYOgCLyJrAKUYEL9KND7qirCPzVgmJHWIOnVewu8mldYFhroL89yvV3bZx4MGeyPU4KvbCsRgdORCTN0XhuLYUdiehHXnDBfuZ5yyR0saWLh8gjkLV5GkxTeKpOhpoK1o1cMiCDPYqTa64g5JundlW707c9zxc3Xnf2pW7E74YJl5oBu5vWEyPqXtYOtZOjOIRxxDY8QpoW8mpbQXxgB8DjkZZMiUCe0qHZYxvktVZJmHoaYBwpYpXVTZCfq9WajmkIOdIad1VnH5HpaECLRs6loa259yH8qesak2feDiKjfb8p3uj3s7WZUvPJwAWX9PIW1p7x6OiszXQCntOFRC3bQFNz1c98wlCBJnBSxbbYhU057TDNnoaib1h9bH7LAcqD1caE5KwLMAc5HqugkkRzT5NszkdJcpF0SxakdrAQLOKS6sNwDUzBJA76F775vmaqe3XIYecPmGtfoAKMychfEI4vfNr";
82+
for (int i = 0; i < 400000; i++) {
83+
Statement stmt = connection.createStatement();
84+
String description = "description " + i;
85+
String text = "here is my text data " + i;
86+
String query = "insert into test values (" + i + ", " + i * 10 + ", '" + description + "', '" + text + "', " + i * 100 + 0.1234 + ", '2024-01-10', '10:00:00', '10:00:00-07', '2025-07-15 10:00:00', '2025-07-15 10:00:00-07'" + ", '" + desc_1KB + "');";
87+
int rs = stmt.executeUpdate(query);
88+
assert rs == 1;
89+
}
90+
}
91+
92+
private void validateResultSet(ResultSet rs) throws SQLException {
93+
while (rs.next()) {
94+
assert rs.getInt(1) >= 0;
95+
assert rs.getInt(2) >= 0;
96+
assert rs.getString(3) != null;
97+
assert rs.getString(4) != null;
98+
assert rs.getDouble(5) >= 0.0;
99+
assert rs.getDate(6) != null;
100+
assert rs.getTime(7) != null;
101+
assert rs.getTime(8) != null;
102+
assert rs.getTimestamp(9) != null;
103+
assert rs.getTimestamp(10) != null;
104+
assert !rs.wasNull();
105+
}
106+
}
107+
108+
@Benchmark
109+
public void runBenchmarkPrimaryKeyLookup() throws SQLException {
110+
try (Statement stmt = connection.createStatement();
111+
ResultSet rs = stmt.executeQuery("/*+ CACHE_PARAM(ttl=172800s) */ SELECT * FROM test where id = " + counter)) {
112+
validateResultSet(rs);
113+
}
114+
counter++;
115+
}
116+
117+
@Benchmark
118+
public void runBenchmarkNonIndexedLookup() throws SQLException {
119+
try (Statement stmt = connection.createStatement();
120+
ResultSet rs = stmt.executeQuery("/*+ CACHE_PARAM(ttl=172800s) */ SELECT * FROM test where int_col = " + counter*10)) {
121+
validateResultSet(rs);
122+
}
123+
counter++;
124+
}
125+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<configuration>
3+
<!-- Root logger defines the default logging level and appenders -->
4+
<root level="info">
5+
</root>
6+
</configuration>

0 commit comments

Comments
 (0)