Skip to content

Commit 1c93a3d

Browse files
chore: update benchmarking script (#3882)
1 parent ca3a67d commit 1c93a3d

File tree

6 files changed

+341
-112
lines changed

6 files changed

+341
-112
lines changed

benchmarks/pom.xml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
3535
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
3636
<junixsocket.version>2.10.1</junixsocket.version>
37-
<opentelemetry.version>1.50.0</opentelemetry.version>
37+
<opentelemetry.version>1.47.0</opentelemetry.version>
3838
</properties>
3939

4040
<dependencies>
@@ -54,7 +54,12 @@
5454
<dependency>
5555
<groupId>com.google.cloud.opentelemetry</groupId>
5656
<artifactId>exporter-metrics</artifactId>
57-
<version>0.34.0</version>
57+
<version>0.33.0</version>
58+
</dependency>
59+
<dependency>
60+
<groupId>com.google.cloud</groupId>
61+
<artifactId>google-cloud-monitoring</artifactId>
62+
<version>3.63.0</version>
5863
</dependency>
5964
<!-- OpenTelemetry test dependencies -->
6065
<dependency>
@@ -85,7 +90,7 @@
8590
<dependency>
8691
<groupId>io.opentelemetry</groupId>
8792
<artifactId>opentelemetry-bom</artifactId>
88-
<version>1.50.0</version>
93+
<version>1.47.0</version>
8994
<type>pom</type>
9095
<scope>import</scope>
9196
</dependency>
@@ -94,11 +99,6 @@
9499
<artifactId>google-cloud-spanner</artifactId>
95100
<version>6.93.0</version>
96101
</dependency>
97-
<dependency>
98-
<groupId>commons-cli</groupId>
99-
<artifactId>commons-cli</artifactId>
100-
<version>1.9.0</version>
101-
</dependency>
102102
<dependency>
103103
<groupId>com.google.auto.value</groupId>
104104
<artifactId>auto-value-annotations</artifactId>
@@ -140,8 +140,9 @@
140140
</configuration>
141141
</plugin>
142142
<plugin>
143-
<groupId>com.coveo</groupId>
143+
<groupId>com.spotify.fmt</groupId>
144144
<artifactId>fmt-maven-plugin</artifactId>
145+
<version>2.27</version>
145146
<executions>
146147
<execution>
147148
<goals>

benchmarks/src/main/java/com/google/cloud/spanner/benchmark/AbstractRunner.java

Lines changed: 73 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,46 +18,80 @@
1818

1919
import java.nio.charset.StandardCharsets;
2020
import java.time.Duration;
21+
import java.time.Instant;
22+
import java.time.temporal.ChronoUnit;
2123
import java.util.ArrayList;
24+
import java.util.HashMap;
25+
import java.util.HashSet;
2226
import java.util.List;
27+
import java.util.Map;
28+
import java.util.Set;
2329
import java.util.concurrent.ExecutorService;
2430
import java.util.concurrent.Future;
2531
import java.util.concurrent.ThreadLocalRandom;
2632
import java.util.concurrent.TimeUnit;
2733
import java.util.concurrent.TimeoutException;
28-
import java.util.concurrent.atomic.AtomicInteger;
2934

3035
abstract class AbstractRunner implements BenchmarkRunner {
31-
static final int TOTAL_RECORDS = 1000000;
32-
static final String SELECT_QUERY = "SELECT ID FROM FOO WHERE ID = @id";
33-
static final String UPDATE_QUERY = "UPDATE FOO SET BAR=1 WHERE ID = @id";
36+
static final int TOTAL_RECORDS = 100000;
37+
static final String TABLE_NAME = "Employees";
38+
static final String SELECT_QUERY = String.format("SELECT ID FROM %s WHERE ID = @id", TABLE_NAME);
39+
static final String UPDATE_QUERY =
40+
String.format("UPDATE %s SET Name=Google WHERE ID = @id", TABLE_NAME);
3441
static final String ID_COLUMN_NAME = "id";
35-
static final String SERVER_URL = "https://staging-wrenchworks.sandbox.googleapis.com";
42+
static final Map<Environment, String> SERVER_URL_MAPPING = new HashMap<>();
3643

37-
private final AtomicInteger operationCounter = new AtomicInteger();
44+
static {
45+
SERVER_URL_MAPPING.put(
46+
Environment.CLOUD_DEVEL, "https://staging-wrenchworks.sandbox.googleapis.com");
47+
SERVER_URL_MAPPING.put(Environment.PROD, "https://spanner.googleapis.com");
48+
}
49+
50+
Map<Integer, TimerConfiguration> timerConfigurations = new HashMap<>();
51+
private final Set<Integer> completedClients = new HashSet<>();
52+
private final Set<Integer> finishedClients = new HashSet<>();
53+
54+
protected void initiateTimer(int clientId, String message, Instant endTime) {
55+
TimerConfiguration timerConfiguration =
56+
timerConfigurations.getOrDefault(clientId, new TimerConfiguration());
57+
timerConfiguration.setMessage(message);
58+
timerConfiguration.setEndTime(endTime);
59+
timerConfigurations.put(clientId, timerConfiguration);
60+
}
3861

39-
protected void incOperations() {
40-
operationCounter.incrementAndGet();
62+
protected void setBenchmarkingCompleted(int clientId) {
63+
this.completedClients.add(clientId);
4164
}
4265

4366
protected List<Duration> collectResults(
4467
ExecutorService service,
4568
List<Future<List<Duration>>> results,
46-
int numClients,
47-
int numOperations)
69+
BenchmarkingConfiguration configuration)
4870
throws Exception {
49-
int totalOperations = numClients * numOperations;
71+
while (!(finishedClients.size() == configuration.getNumOfClients()))
72+
for (int i = 0; i < configuration.getNumOfClients(); i++) {
73+
TimerConfiguration timerConfiguration =
74+
timerConfigurations.getOrDefault(i, new TimerConfiguration());
75+
long totalSeconds =
76+
ChronoUnit.SECONDS.between(Instant.now(), timerConfiguration.getEndTime());
77+
if (completedClients.contains(i)) {
78+
if (!finishedClients.contains(i)) {
79+
System.out.printf("Client %s: Completed", i);
80+
finishedClients.add(i);
81+
}
82+
} else {
83+
System.out.printf(
84+
"Client %s: %s %s Minutes %s Seconds\r",
85+
i + 1, timerConfiguration.getMessage(), totalSeconds / 60, totalSeconds % 60);
86+
}
87+
//noinspection BusyWait
88+
Thread.sleep(1000L);
89+
}
5090
service.shutdown();
51-
while (!service.isTerminated()) {
52-
//noinspection BusyWait
53-
Thread.sleep(1000L);
54-
System.out.printf("\r%d/%d", operationCounter.get(), totalOperations);
55-
}
56-
System.out.println();
5791
if (!service.awaitTermination(60L, TimeUnit.MINUTES)) {
5892
throw new TimeoutException();
5993
}
60-
List<Duration> allResults = new ArrayList<>(numClients * numOperations);
94+
List<Duration> allResults = new ArrayList<>();
6195
for (Future<List<Duration>> result : results) {
6296
allResults.addAll(result.get());
6397
}
@@ -77,4 +111,25 @@ protected String generateRandomString() {
77111
ThreadLocalRandom.current().nextBytes(bytes);
78112
return new String(bytes, StandardCharsets.UTF_8);
79113
}
114+
115+
static class TimerConfiguration {
116+
private Instant endTime = Instant.now();
117+
private String message = "Waiting for benchmarks to start...";
118+
119+
Instant getEndTime() {
120+
return endTime;
121+
}
122+
123+
void setEndTime(Instant endTime) {
124+
this.endTime = endTime;
125+
}
126+
127+
String getMessage() {
128+
return message;
129+
}
130+
131+
void setMessage(String message) {
132+
this.message = message;
133+
}
134+
}
80135
}

benchmarks/src/main/java/com/google/cloud/spanner/benchmark/BenchmarkRunner.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,18 @@
1919
import java.time.Duration;
2020
import java.util.List;
2121

22-
public interface BenchmarkRunner {
22+
interface BenchmarkRunner {
2323
enum TransactionType {
24-
READ_ONLY_SINGLE_USE,
24+
READ_ONLY_SINGLE_USE_READ,
25+
READ_ONLY_SINGLE_USE_QUERY,
2526
READ_ONLY_MULTI_USE,
2627
READ_WRITE
2728
}
2829

29-
List<Duration> execute(
30-
TransactionType transactionType,
31-
int numClients,
32-
int numOperations,
33-
int waitMillis,
34-
boolean useMultiplexedSession);
30+
enum Environment {
31+
PROD,
32+
CLOUD_DEVEL
33+
}
34+
35+
List<Duration> execute(BenchmarkingConfiguration configuration);
3536
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright 2025 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.spanner.benchmark;
18+
19+
import com.google.cloud.spanner.DatabaseId;
20+
import com.google.cloud.spanner.benchmark.BenchmarkRunner.Environment;
21+
import com.google.cloud.spanner.benchmark.BenchmarkRunner.TransactionType;
22+
23+
class BenchmarkingConfiguration {
24+
25+
private DatabaseId databaseId;
26+
private int numOfClients;
27+
private int staleness;
28+
private int warmupTime;
29+
private int executionTime;
30+
private int waitBetweenRequests;
31+
private boolean useMultiplexSession;
32+
private TransactionType transactionType;
33+
private Environment environment;
34+
35+
int getExecutionTime() {
36+
return executionTime;
37+
}
38+
39+
BenchmarkingConfiguration setExecutionTime(int executionTime) {
40+
this.executionTime = executionTime;
41+
return this;
42+
}
43+
44+
DatabaseId getDatabaseId() {
45+
return databaseId;
46+
}
47+
48+
BenchmarkingConfiguration setDatabaseId(DatabaseId databaseId) {
49+
this.databaseId = databaseId;
50+
return this;
51+
}
52+
53+
int getNumOfClients() {
54+
return numOfClients;
55+
}
56+
57+
BenchmarkingConfiguration setNumOfClients(int numOfClients) {
58+
this.numOfClients = numOfClients;
59+
return this;
60+
}
61+
62+
int getStaleness() {
63+
return staleness;
64+
}
65+
66+
BenchmarkingConfiguration setStaleness(int staleness) {
67+
this.staleness = staleness;
68+
return this;
69+
}
70+
71+
int getWarmupTime() {
72+
return warmupTime;
73+
}
74+
75+
BenchmarkingConfiguration setWarmupTime(int warmupTime) {
76+
this.warmupTime = warmupTime;
77+
return this;
78+
}
79+
80+
int getWaitBetweenRequests() {
81+
return waitBetweenRequests;
82+
}
83+
84+
BenchmarkingConfiguration setWaitBetweenRequests(int waitBetweenRequests) {
85+
this.waitBetweenRequests = waitBetweenRequests;
86+
return this;
87+
}
88+
89+
boolean isUseMultiplexSession() {
90+
return useMultiplexSession;
91+
}
92+
93+
BenchmarkingConfiguration setUseMultiplexSession(boolean useMultiplexSession) {
94+
this.useMultiplexSession = useMultiplexSession;
95+
return this;
96+
}
97+
98+
TransactionType getTransactionType() {
99+
return transactionType;
100+
}
101+
102+
BenchmarkingConfiguration setTransactionType(TransactionType transactionType) {
103+
this.transactionType = transactionType;
104+
return this;
105+
}
106+
107+
Environment getEnvironment() {
108+
return environment;
109+
}
110+
111+
BenchmarkingConfiguration setEnvironment(Environment environment) {
112+
this.environment = environment;
113+
return this;
114+
}
115+
}

0 commit comments

Comments
 (0)