A high-performance Redis benchmark tool built with Spring Boot and Lettuce client. RedHammer allows you to run comprehensive performance tests against Redis databases with various configurations and provides detailed latency metrics.
- Multi-threaded architecture with optimized thread pool management
- Configurable number of threads and clients per thread
- Support for TLS connections
- Support for OSS Cluster API mode
- Configurable request rate limiting
- Configurable read/write ratio
- Configurable data sizes (fixed or range)
- Dynamic operation-specific CLI options
- MGET and MSET operations with configurable batch sizes
- Comprehensive latency metrics and percentile analysis
- Automatic retry mechanism with exponential backoff
- Random batch sizes for realistic workload simulation
- Slow operation detection and reporting
- Detailed progress reporting during benchmark execution
- Memory-efficient operation with G1 garbage collector
- Build the Docker image:
docker build -t redhammer .
- Run the benchmark:
docker run redhammer [options]
Example commands:
# Run benchmark against local Redis instance
docker run --network host redhammer
# Run benchmark against a remote Redis instance
docker run redhammer -h redis.example.com -p 6379
# Run benchmark with custom parameters
docker run redhammer -t 4 -c 100 --ratio 80 --data-size 1000
- Build the project:
mvn clean package
- Run the benchmark:
java -jar target/redhammer-1.0.0-SNAPSHOT.jar [options]
-t, --threads
: Number of threads to use (default: 4)-c, --clients
: Number of clients per thread (default: 50)--tls
: Enable TLS connection (default: false)--cluster
: Enable OSS Cluster API mode (default: false)--time
: Test time in seconds, 0 for unlimited (default: 0)--requests
: Requests per client, 0 for unlimited (default: 0)--ratio
: Read/Write ratio, e.g., 80 means 80% reads, 20% writes (default: 50)--rate
: Rate limit in ops/sec, 0 for unlimited (default: 0)--data-size
: Fixed data size for each key in bytes (default: 100)--min-data-size
: Minimum data size for each key in bytes (default: -1)--max-data-size
: Maximum data size for each key in bytes (default: -1)-h, --host
: Redis server host (default: localhost)-p, --port
: Redis server port (default: 6379)--password
: Redis server password (default: empty)--batch-size
: Default batch size for operations (default: 10)
Each operation can define its own CLI options. Currently available:
--mget-min-batch
: Minimum batch size for MGET operations (default: 10)--mget-max-batch
: Maximum batch size for MGET operations (default: 10)
--mset-min-batch
: Minimum batch size for MSET operations (default: 10)--mset-max-batch
: Maximum batch size for MSET operations (default: 10)
Operation-specific configuration can also be set through Spring Boot properties:
# MGET operation configuration
benchmark.operations.mget.min-batch-size=5 # Same as --mget-min-batch
benchmark.operations.mget.max-batch-size=15 # Same as --mget-max-batch
# MSET operation configuration
benchmark.operations.mset.min-batch-size=5 # Same as --mset-min-batch
benchmark.operations.mset.max-batch-size=15 # Same as --mset-max-batch
- Basic benchmark with default settings:
docker run redhammer
- Benchmark with 4 threads, 100 clients per thread, and 80% read ratio:
docker run redhammer -t 4 -c 100 --ratio 80
- Benchmark with rate limiting and variable data size:
docker run redhammer -r 1000 --min-data-size 100 --max-data-size 1000
- Benchmark against a remote Redis server with TLS:
docker run redhammer -h redis.example.com -p 6380 --tls --password mypassword
- Benchmark with operation-specific batch sizes:
docker run redhammer --mget-min-batch 5 --mget-max-batch 15 --mset-min-batch 10 --mset-max-batch 20
RedHammer is designed to be extensible. To add support for new Redis operations:
- Create CLI options for your operation:
@Data
@Component
public class HSetCliOptions implements OperationCliOptions {
@Option(names = {"--hset-fields"},
description = "Number of fields per hash",
defaultValue = "5")
private int fieldsPerHash = 5;
@Override
public CommandLine.Model.CommandSpec getCliSpec() {
return CommandLine.Model.CommandSpec.create()
.addOption(CommandLine.Model.OptionSpec.builder("--hset-fields")
.description("Number of fields per hash")
.type(int.class)
.defaultValue("5")
.build());
}
@Override
public String getOperationName() {
return "HSET";
}
}
- Create a configuration class:
@Data
@Component
@ConfigurationProperties(prefix = "benchmark.operations.hset")
public class HSetConfig implements OperationConfig {
private final HSetCliOptions cliOptions;
public HSetConfig(HSetCliOptions cliOptions) {
this.cliOptions = cliOptions;
}
@Override
public String getOperationName() {
return "HSET";
}
public int getFieldsPerHash() {
return cliOptions.getFieldsPerHash();
}
}
- Create the operation implementation:
@Component
public class HSetWriter extends RedisWriter {
private final HSetConfig config;
public HSetWriter(HSetConfig config) {
super("HSET");
this.config = config;
}
@Override
public CompletableFuture<String> write(StatefulRedisConnection<String, String> connection,
Map<String, String> keyValues) {
// Implementation
}
@Override
public int getBatchSize() {
return config.getFieldsPerHash();
}
}
The new operation will be automatically registered and its CLI options will be available when running the benchmark.
RedHammer includes several optimizations for maximum performance:
- Dedicated thread pools for operation execution
- Efficient memory management with G1 garbage collector
- Automatic batch size adjustment
- Connection pooling and reuse
- Exponential backoff for retries
- Rate limiting for stability
- Slow operation detection and reporting
- Docker (for containerized execution)
- Java 17 or higher (for local development)
- Maven 3.6 or higher (for local development)
- Redis server (local or remote)
Contributions are welcome! Please feel free to submit a Pull Request.