Skip to content

Commit 1e693e2

Browse files
committed
Add the benchmark
1 parent c982c6e commit 1e693e2

File tree

7 files changed

+309
-8
lines changed

7 files changed

+309
-8
lines changed

test/s3-benchmarks/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@
102102
<artifactId>netty-nio-client</artifactId>
103103
<version>${awsjavasdk.version}</version>
104104
</dependency>
105+
<dependency>
106+
<artifactId>apache-client</artifactId>
107+
<groupId>software.amazon.awssdk</groupId>
108+
<version>${awsjavasdk.version}</version>
109+
</dependency>
110+
<dependency>
111+
<artifactId>apache5-client</artifactId>
112+
<groupId>software.amazon.awssdk</groupId>
113+
<version>${awsjavasdk.version}</version>
114+
</dependency>
115+
105116
<dependency>
106117
<groupId>software.amazon.awssdk</groupId>
107118
<artifactId>aws-crt-client</artifactId>

test/s3-benchmarks/src/main/java/software/amazon/awssdk/s3benchmarks/s3express/S3BenchmarkRunner.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
2222
import software.amazon.awssdk.core.metrics.CoreMetric;
2323
import software.amazon.awssdk.http.HttpMetric;
24+
import software.amazon.awssdk.http.apache.ApacheHttpClient;
25+
import software.amazon.awssdk.http.apache5.Apache5HttpClient;
2426
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
2527
import software.amazon.awssdk.metrics.MetricLevel;
2628
import software.amazon.awssdk.metrics.MetricPublisher;
@@ -67,12 +69,13 @@ public static void runBenchmarks(boolean useS3Express) {
6769

6870
S3Client s3Client = S3BenchmarkTestUtils.s3ClientBuilder(region)
6971
.credentialsProvider(credentialsProvider)
72+
.httpClient(ApacheHttpClient.create())
7073
.overrideConfiguration(o -> o.addMetricPublisher(
7174
metricPublisher(cloudwatchClient,
7275
namespacePrefix + "/SmallObject/Apache")))
7376
.build();
7477

75-
LOGGER.info(() -> "Running small objects benchmark, 64Kb data, 5 buckets, 200 iterations");
78+
LOGGER.info(() -> "Running small objects benchmark with Apache4 Http Client, 64Kb data, 5 buckets, 200 iterations");
7679
BenchmarkConfig smallObjectSyncConfig = BenchmarkConfig.builder()
7780
.region(region)
7881
.credentialsProvider(credentialsProvider)
@@ -93,7 +96,7 @@ public static void runBenchmarks(boolean useS3Express) {
9396
namespacePrefix + "/MediumObject/Apache")))
9497
.build();
9598

96-
LOGGER.info(() -> "Running medium objects benchmark, 1024Kb data, 5 buckets, 200 iterations");
99+
LOGGER.info(() -> "Running medium objects benchmark with Apache4 Http Client, 1024Kb data, 5 buckets, 200 iterations");
97100
BenchmarkConfig largeObjectSyncConfig = BenchmarkConfig.builder()
98101
.region(region)
99102
.credentialsProvider(credentialsProvider)
@@ -108,6 +111,33 @@ public static void runBenchmarks(boolean useS3Express) {
108111

109112
s3Client.close();
110113

114+
s3Client = S3BenchmarkTestUtils.s3ClientBuilder(region)
115+
.credentialsProvider(credentialsProvider)
116+
.httpClient(Apache5HttpClient.create())
117+
.overrideConfiguration(o -> o.addMetricPublisher(
118+
metricPublisher(cloudwatchClient,
119+
namespacePrefix + "/SmallObject/Apache")))
120+
.build();
121+
122+
LOGGER.info(() -> "Running small objects benchmark with Apache5 Http Client, 64Kb data, 5 buckets, 200 iterations");
123+
syncBenchmark = new S3PutGetDeleteSyncBenchmark(smallObjectSyncConfig, s3Client);
124+
syncBenchmark.run();
125+
s3Client.close();
126+
127+
s3Client = S3BenchmarkTestUtils.s3ClientBuilder(region)
128+
.credentialsProvider(credentialsProvider)
129+
.httpClient(Apache5HttpClient.create())
130+
.overrideConfiguration(o -> o.addMetricPublisher(
131+
metricPublisher(cloudwatchClient,
132+
namespacePrefix + "/MediumObject/Apache5")))
133+
.build();
134+
135+
LOGGER.info(() -> "Running medium objects benchmark with Apache5 Http Client, 1024Kb data, 5 buckets, 200 iterations");
136+
syncBenchmark = new S3PutGetDeleteSyncBenchmark(largeObjectSyncConfig, s3Client);
137+
syncBenchmark.run();
138+
s3Client.close();
139+
140+
111141
S3AsyncClient s3AsyncClient = S3BenchmarkTestUtils.s3AsyncClientBuilder(region)
112142
.credentialsProvider(credentialsProvider)
113143
.overrideConfiguration(o -> o.addMetricPublisher(

test/sdk-benchmarks/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@
163163
<artifactId>apache5-client</artifactId>
164164
<version>${awsjavasdk.version}</version>
165165
</dependency>
166+
<dependency>
167+
<groupId>software.amazon.awssdk</groupId>
168+
<artifactId>apache-client</artifactId>
169+
<version>${awsjavasdk.version}</version>
170+
</dependency>
166171
<dependency>
167172
<groupId>software.amazon.awssdk</groupId>
168173
<artifactId>protocol-tests</artifactId>

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/SdkHttpClientBenchmark.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,39 @@ public interface SdkHttpClientBenchmark {
4040
*/
4141
default void concurrentApiCall(Blackhole blackhole) {
4242
}
43+
44+
45+
/**
46+
* Benchmark for PUT operations with streaming
47+
*
48+
* @param blackhole the blackhole
49+
*/
50+
default void streamingPutOperation(Blackhole blackhole) {
51+
}
52+
53+
/**
54+
* Benchmark for concurrent PUT operations
55+
*
56+
* @param blackhole the blackhole
57+
*/
58+
default void concurrentStreamingPutOperation(Blackhole blackhole) {
59+
}
60+
61+
/**
62+
* Benchmark for GET operations with streaming response
63+
*
64+
* @param blackhole the blackhole
65+
*/
66+
default void streamingOutputOperation(Blackhole blackhole) {
67+
}
68+
69+
/**
70+
* Benchmark for concurrent GET operations with streaming response
71+
*
72+
* @param blackhole the blackhole
73+
*/
74+
default void concurrentStreamingOutputOperation(Blackhole blackhole) {
75+
}
76+
77+
4378
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/httpclient/sync/ApacheHttpClientBenchmark.java

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,35 @@
3333
import org.openjdk.jmh.annotations.Measurement;
3434
import org.openjdk.jmh.annotations.Mode;
3535
import org.openjdk.jmh.annotations.OperationsPerInvocation;
36+
import org.openjdk.jmh.annotations.Param;
3637
import org.openjdk.jmh.annotations.Scope;
3738
import org.openjdk.jmh.annotations.Setup;
3839
import org.openjdk.jmh.annotations.State;
3940
import org.openjdk.jmh.annotations.TearDown;
4041
import org.openjdk.jmh.annotations.Warmup;
4142
import org.openjdk.jmh.infra.Blackhole;
43+
import org.openjdk.jmh.profile.GCProfiler;
4244
import org.openjdk.jmh.profile.StackProfiler;
4345
import org.openjdk.jmh.results.RunResult;
4446
import org.openjdk.jmh.runner.Runner;
4547
import org.openjdk.jmh.runner.options.Options;
4648
import org.openjdk.jmh.runner.options.OptionsBuilder;
4749
import software.amazon.awssdk.benchmark.apicall.httpclient.SdkHttpClientBenchmark;
4850
import software.amazon.awssdk.benchmark.utils.MockServer;
51+
import software.amazon.awssdk.core.ResponseBytes;
52+
import software.amazon.awssdk.core.sync.RequestBody;
53+
import software.amazon.awssdk.core.sync.ResponseTransformer;
4954
import software.amazon.awssdk.http.SdkHttpClient;
5055
import software.amazon.awssdk.http.apache.ApacheHttpClient;
56+
import software.amazon.awssdk.http.apache5.Apache5HttpClient;
5157
import software.amazon.awssdk.regions.Region;
5258
import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient;
59+
import software.amazon.awssdk.services.protocolrestjson.model.StreamingInputOperationRequest;
60+
import software.amazon.awssdk.services.protocolrestjson.model.StreamingOutputOperationRequest;
61+
import software.amazon.awssdk.services.protocolrestjson.model.StreamingOutputOperationResponse;
5362

5463
/**
55-
* Benchmarking for running with different http clients.
64+
* Benchmarking for running with different Apache HTTP clients.
5665
*/
5766
@State(Scope.Benchmark)
5867
@Warmup(iterations = 3, time = 15, timeUnit = TimeUnit.SECONDS)
@@ -61,6 +70,19 @@
6170
@BenchmarkMode(Mode.Throughput)
6271
public class ApacheHttpClientBenchmark implements SdkHttpClientBenchmark {
6372

73+
private static final int STREAM_SIZE = 1024 * 1024; // 1MB
74+
private static final byte[] STREAM_DATA = new byte[STREAM_SIZE];
75+
76+
static {
77+
// Initialize stream data
78+
for (int i = 0; i < STREAM_SIZE; i++) {
79+
STREAM_DATA[i] = (byte) (i % 256);
80+
}
81+
}
82+
83+
@Param( {"apache4", "apache5"})
84+
private String clientType;
85+
6486
private MockServer mockServer;
6587
private SdkHttpClient sdkHttpClient;
6688
private ProtocolRestJsonClient client;
@@ -70,8 +92,21 @@ public class ApacheHttpClientBenchmark implements SdkHttpClientBenchmark {
7092
public void setup() throws Exception {
7193
mockServer = new MockServer();
7294
mockServer.start();
73-
sdkHttpClient = ApacheHttpClient.builder()
74-
.buildWithDefaults(trustAllTlsAttributeMapBuilder().build());
95+
96+
// Create HTTP client based on parameter
97+
switch (clientType) {
98+
case "apache4":
99+
sdkHttpClient = ApacheHttpClient.builder()
100+
.buildWithDefaults(trustAllTlsAttributeMapBuilder().build());
101+
break;
102+
case "apache5":
103+
sdkHttpClient = Apache5HttpClient.builder()
104+
.buildWithDefaults(trustAllTlsAttributeMapBuilder().build());
105+
break;
106+
default:
107+
throw new IllegalArgumentException("Unknown client type: " + clientType);
108+
}
109+
75110
client = ProtocolRestJsonClient.builder()
76111
.endpointOverride(mockServer.getHttpsUri())
77112
.httpClient(sdkHttpClient)
@@ -109,12 +144,78 @@ public void concurrentApiCall(Blackhole blackhole) {
109144
awaitCountdownLatchUninterruptibly(countDownLatch, 10, TimeUnit.SECONDS);
110145
}
111146

112-
public static void main(String... args) throws Exception {
147+
@Benchmark
148+
@Override
149+
public void streamingPutOperation(Blackhole blackhole) {
150+
StreamingInputOperationRequest request = StreamingInputOperationRequest.builder()
151+
.build();
152+
RequestBody requestBody = RequestBody.fromBytes(STREAM_DATA);
153+
154+
blackhole.consume(client.streamingInputOperation(request, requestBody));
155+
}
156+
157+
@Benchmark
158+
@Override
159+
@OperationsPerInvocation(CONCURRENT_CALLS)
160+
public void concurrentStreamingPutOperation(Blackhole blackhole) {
161+
CountDownLatch countDownLatch = new CountDownLatch(CONCURRENT_CALLS);
113162

163+
for (int i = 0; i < CONCURRENT_CALLS; i++) {
164+
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
165+
StreamingInputOperationRequest request = StreamingInputOperationRequest.builder()
166+
.build();
167+
RequestBody requestBody = RequestBody.fromBytes(STREAM_DATA);
168+
client.streamingInputOperation(request, requestBody);
169+
}, executorService);
170+
171+
countDownUponCompletion(blackhole, future, countDownLatch);
172+
}
173+
174+
awaitCountdownLatchUninterruptibly(countDownLatch, 10, TimeUnit.SECONDS);
175+
}
176+
177+
@Benchmark
178+
@Override
179+
public void streamingOutputOperation(Blackhole blackhole) {
180+
StreamingOutputOperationRequest request = StreamingOutputOperationRequest.builder()
181+
.build();
182+
183+
ResponseBytes<StreamingOutputOperationResponse> responseBytes = client.streamingOutputOperation(request,
184+
ResponseTransformer.toBytes());
185+
186+
blackhole.consume(responseBytes.asByteArray());
187+
}
188+
189+
@Benchmark
190+
@Override
191+
@OperationsPerInvocation(CONCURRENT_CALLS)
192+
public void concurrentStreamingOutputOperation(Blackhole blackhole) {
193+
CountDownLatch countDownLatch = new CountDownLatch(CONCURRENT_CALLS);
194+
195+
for (int i = 0; i < CONCURRENT_CALLS; i++) {
196+
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
197+
StreamingOutputOperationRequest request = StreamingOutputOperationRequest.builder()
198+
.build();
199+
200+
ResponseBytes<StreamingOutputOperationResponse> responseBytes = client.streamingOutputOperation(request,
201+
ResponseTransformer.toBytes());
202+
203+
blackhole.consume(responseBytes.asByteArray());
204+
}, executorService);
205+
206+
countDownUponCompletion(blackhole, future, countDownLatch);
207+
}
208+
209+
awaitCountdownLatchUninterruptibly(countDownLatch, 10, TimeUnit.SECONDS);
210+
}
211+
212+
public static void main(String... args) throws Exception {
114213
Options opt = new OptionsBuilder()
115-
.include(ApacheHttpClientBenchmark.class.getSimpleName() + ".concurrentApiCall")
214+
.include(ApacheHttpClientBenchmark.class.getSimpleName())
116215
.addProfiler(StackProfiler.class)
216+
.addProfiler(GCProfiler.class)
117217
.build();
218+
118219
Collection<RunResult> run = new Runner(opt).run();
119220
}
120221
}

test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/utils/MockServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public MockServer() throws IOException {
5959
server.setConnectors(new Connector[] {connector, sslConnector});
6060

6161
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
62-
context.addServlet(new ServletHolder(new AlwaysSuccessServlet()), "/*");
62+
context.addServlet(new ServletHolder(new StreamingMockServlet()), "/*");
6363
server.setHandler(context);
6464
}
6565

0 commit comments

Comments
 (0)