Refactor S3 Benchmarks - #7210
Conversation
| LOGGER.info(() -> "Running benchmarks against Standard S3"); | ||
| runBenchmarks(false); | ||
| @SuppressWarnings("unchecked") | ||
| private static String toJson(Object obj) { |
There was a problem hiding this comment.
Can we use Jackson instead to do this? is there a reason we handwrite parsing logic otherwise?
There was a problem hiding this comment.
Good call, updated to use Jackson
RanVaknin
left a comment
There was a problem hiding this comment.
Can we add unit tests around InMemoryMetricPublisher and also the expected JSON output? It's currently hard to see what data actually flows through this
Added InMemoryMetricPublisherTest and S3BenchmarkRunnerTest |
There was a problem hiding this comment.
One more question. I see we added avgDurationMs to average out the per iteration samples. So isntead of rawData being something like [[8.1],[20.1],[13.5]...] it's just one subarray that hold the average of those ie: rawData = [[12.5]] this means we lose fidelity.
For the sake of the dashboarding that this feeds into, we might only care about the avg number, is this loss of fidelity is intentional?
Yes, intentional. The new benchmarks setup publishes one CloudWatch datapoint per metric per run, so we aggregate per-iteration samples into a single average. The per-iteration variance is network jitter noise; the average over 100-200 iterations is the meaningful signal for dashboarding and regression detection. |
Motivation and Context
The S3Express benchmarks (
S3BenchmarkRunner) currently self-publish metrics directly to CloudWatch via the SDK'sCloudWatchMetricPublisherattached to S3 clients. This tightly couples the runner to a specific CloudWatch namespace and account, and the publisher itself interferes with async benchmark measurements by adding CPU/thread contention.This change decouples metric collection from publishing, outputting results as a JSON file for consumption by any CI/CD system.
Modifications
Rewrote
S3BenchmarkRunnerintest/s3-benchmarksto:CloudWatchMetricPublisherwith newInMemoryMetricPublisher— captures the same SDK-internal metrics (API_CALL_DURATIONper operation,READ_THROUGHPUTforGetObject) but stores them in memory instead of publishing to CloudWatchavgDurationMs()andavgReadThroughput()throwIllegalStateExceptionif no metrics were collected (prevents silent 0.0 results on failure)catch (Exception e)that swallowed errors inrun(); failures now propagate to JVM exit codemetricPublisher.reset()called betweenwarmUp()anddoRunBenchmark()ObjectMapperto write results toresults.json(configurable via--output <file>)us-west-2CodeBuild; legacy usedus-east-1BenchmarkSystemSetting, unusedBenchmarkConfigfields,Benchmark.runWithTime/TimedResult,S3BenchmarkTestUtilsdead helpers — all pre-existing from the original S3 Express launch commit, never used by this runnerInMemoryMetricPublisherTest(avg computation, zero-sample throws, reset, operation separation) andS3BenchmarkRunnerTest(verifies JSON output structure)Testing