A high-performance, configurable benchmark tool for evaluating gRPC-based Key-Value stores backed by SPDK or kernel block devices.
- High Performance: Concurrent worker architecture with connection pooling
- Configurable Workloads: Tunable operation mix (Get/Put/Delete ratios)
- Comprehensive Metrics: Latency percentiles, throughput, error rates
- Multiple Output Formats: Console reporting, CSV export, detailed logging
- Warm-up Support: Pre-benchmark warm-up phase for accurate measurements
- Health Checks: Connection validation before benchmark starts
- Go 1.21 or later
- Protocol Buffers compiler (
protoc
) - gRPC Go plugins
-
Install Protocol Buffers compiler:
# Ubuntu/Debian sudo apt install protobuf-compiler # macOS brew install protobuf
-
Install gRPC Go plugins:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
-
Build the benchmarker:
go mod tidy go build -o benchmarker cmd/benchmarker/main.go
./benchmarker --target=localhost:50051 --workers=100 --duration=30s
./benchmarker \
--target=127.0.0.1:50051 \
--connections=8 \
--workers=100 \
--duration=30s \
--warmup=5s \
--keyspace=50000 \
--valuesize=1024 \
--read=70 --write=25 --delete=5 \
--log-requests \
--log-errors \
--csv=results/benchmark_$(date +%Y%m%d_%H%M%S).csv
Option | Default | Description |
---|---|---|
--target |
localhost:50051 |
gRPC server address |
--connections |
8 |
Number of gRPC connections |
--workers |
100 |
Number of concurrent workers |
--duration |
30s |
Benchmark duration |
--warmup |
5s |
Warm-up duration |
--keyspace |
50000 |
Number of unique keys |
--valuesize |
1024 |
Size of values in bytes |
--read |
70 |
Percentage of read operations |
--write |
25 |
Percentage of write operations |
--delete |
5 |
Percentage of delete operations |
--report-interval |
5s |
Progress report interval |
--csv |
`` | Output CSV file path |
--log-requests |
false |
Log all requests |
--log-errors |
false |
Log error requests |
2024/01/15 10:30:00 Benchmark Configuration:
Target: localhost:50051
Connections: 8
Workers: 100
Duration: 30s
Warm-up: 5s
Key Space: 50000
Value Size: 1024 bytes
Operation Mix: Read=70%, Write=25%, Delete=5%
2024/01/15 10:30:01 Starting warm-up phase for 5s
2024/01/15 10:30:06 Warm-up phase completed
2024/01/15 10:30:06 Starting benchmark phase for 30s
[10:30:11] Total: 15000 | RPS: 3000 | Avg Latency: 2.5ms | P95: 4.3ms | Errors: 0
[10:30:16] Total: 30200 | RPS: 3020 | Avg Latency: 2.6ms | P95: 4.2ms | Errors: 3
=== FINAL RESULTS ===
Get:
Count: 21000
Errors: 0 (0.00%)
Avg Latency: 2.1ms
P50 Latency: 1.8ms
P95 Latency: 3.2ms
P99 Latency: 4.8ms
Min Latency: 0.5ms
Max Latency: 12.3ms
Put:
Count: 7500
Errors: 2 (0.03%)
Avg Latency: 3.2ms
P50 Latency: 2.9ms
P95 Latency: 5.1ms
P99 Latency: 7.2ms
Min Latency: 1.2ms
Max Latency: 15.6ms
Delete:
Count: 1500
Errors: 1 (0.07%)
Avg Latency: 2.8ms
P50 Latency: 2.5ms
P95 Latency: 4.5ms
P99 Latency: 6.1ms
Min Latency: 0.8ms
Max Latency: 11.2ms
TOTAL:
Total Operations: 30000
Total Errors: 3 (0.01%)
Overall Avg Latency: 2.4ms
If --csv
is specified, detailed per-request data is written to a CSV file:
timestamp,method,latency_ms,error
2024-01-15T10:30:06.123456789Z,Get,2.1,
2024-01-15T10:30:06.124567890Z,Put,3.2,
2024-01-15T10:30:06.125678901Z,Delete,2.8,
2024-01-15T10:30:06.126789012Z,Get,1.9,connection refused
+------------------+
| CLI / Config |
+--------+---------+
|
v
+--------+--------+
| BenchmarkRunner |
+--------+--------+
|
+-----------------+------------------+
| | |
v v v
+----+----+ +----+----+ +----+----+
| Worker 1 | ... | Worker N | ... | Collector|
+----+----+ +----+----+ +----+----+
| | ^
v v |
[gRPC Client] [gRPC Client] <-- Results Channel
- CLI/Config: Command-line interface and configuration management
- BenchmarkRunner: Orchestrates the entire benchmark execution
- Worker Pool: Concurrent goroutines performing operations
- Connection Pool: Manages multiple gRPC connections
- Collector: Aggregates results and generates reports
- Key Generator: Generates random keys and values
kvstore-benchmarker/
βββ cmd/
β βββ benchmarker/
β βββ main.go # CLI entrypoint
βββ pkg/
β βββ runner/
β β βββ runner.go # Main benchmark runner
β β βββ keygen.go # Key/value generation
β βββ kvclient/
β β βββ client.go # gRPC client wrapper
β βββ collector/
β β βββ collector.go # Result aggregation
β βββ config/
β βββ config.go # Configuration management
βββ internal/
β βββ proto/
β βββ kvstore.proto # Protocol buffer definition
β βββ kvstore.pb.go # Generated Go code
β βββ kvstore_grpc.pb.go # Generated gRPC code
βββ go.mod
βββ go.sum
βββ README.md
βββ benchmark_tool_design.md
# Generate protobuf code
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
internal/proto/kvstore.proto
# Build the tool
go build -o benchmarker cmd/benchmarker/main.go
# Run tests
go test ./...
# Run with race detection
go test -race ./...
- CPU Affinity: Pin workers to specific CPU cores
- Preload Data: Always preload keys before benchmark
- Warm-up: Use 5-10 second warm-up phase
- Compare Backends: Test SPDK vs kernel with same parameters
- Disable Logging: Reduce server console logging during tests
- Multiple Runs: Run benchmarks multiple times
- Steady State: Ensure system is in steady state
- Resource Monitoring: Monitor CPU, memory, and I/O
- Network Isolation: Use dedicated network for testing
- Baseline Comparison: Always compare against baseline
- Connection Pooling: Use multiple gRPC connections
- Key Distribution: Use random key selection for realistic workloads
- Value Sizes: Test with various value sizes (1KB, 4KB, 16KB)
- Concurrency: Scale workers based on target system capacity
- Duration: Use longer durations for stable measurements
- Connection Refused: Check if gRPC server is running
- High Latency: Verify network connectivity and server performance
- Low Throughput: Increase worker count or check server capacity
- Memory Issues: Reduce key space or worker count
Enable detailed logging:
./benchmarker --target=localhost:50051 --log-requests --log-errors
This project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request