Skip to content

Commit e2988eb

Browse files
works
Signed-off-by: Elena Kolevska <elena@kolevska.com>
1 parent dbdbf64 commit e2988eb

File tree

9 files changed

+510
-37
lines changed

9 files changed

+510
-37
lines changed

WORKLOADS.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Redis Test App Workloads
2+
3+
This document describes all available workloads and their specific Redis operations.
4+
5+
## 🎯 Available Workloads
6+
7+
### **1. BasicWorkload (basic_rw)**
8+
**Purpose**: Basic read/write operations for general testing
9+
**Operations**:
10+
- `SET``client.set(key, value)` - Set key-value pairs
11+
- `GET``client.get(key)` - Retrieve values by key
12+
- `DEL``client.delete(key)` - Delete keys
13+
- `INCR``client.incr(key)` - Increment counters
14+
15+
**Use Cases**:
16+
- General Redis performance testing
17+
- Basic functionality validation
18+
- Mixed read/write workloads
19+
20+
### **2. ListWorkload (list_operations)**
21+
**Purpose**: List data structure operations
22+
**Operations**:
23+
- `LPUSH``client.lpush(key, value)` - Push to left of list
24+
- `RPUSH``client.rpush(key, value)` - Push to right of list
25+
- `LPOP``client.lpop(key)` - Pop from left of list
26+
- `RPOP``client.rpop(key)` - Pop from right of list
27+
- `LRANGE``client.lrange(key, start, end)` - Get range of elements
28+
29+
**Use Cases**:
30+
- Queue implementations
31+
- Stack operations
32+
- List processing workloads
33+
34+
### **3. PipelineWorkload (high_throughput)**
35+
**Purpose**: Batch operations using Redis pipelines
36+
**Operations**:
37+
- `SET``pipe.set(key, value)` - Batched sets
38+
- `GET``pipe.get(key)` - Batched gets
39+
- `INCR``pipe.incr(key)` - Batched increments
40+
41+
**Features**:
42+
- Configurable batch size (default: 10)
43+
- Reduced network round trips
44+
- Higher throughput performance
45+
46+
**Use Cases**:
47+
- High-throughput scenarios (your 700K+ ops/sec!)
48+
- Bulk data operations
49+
- Performance optimization testing
50+
51+
### **4. PubSubWorkload (pubsub_test)**
52+
**Purpose**: Publish/Subscribe messaging patterns
53+
**Operations**:
54+
- `PUBLISH``client.publish(channel, message)` - Send messages
55+
- `SUBSCRIBE` → Background subscriber thread - Receive messages
56+
57+
**Features**:
58+
- Multi-channel support
59+
- Background subscriber threads
60+
- Real-time messaging testing
61+
62+
**Use Cases**:
63+
- Real-time messaging systems
64+
- Event-driven architectures
65+
- Notification systems
66+
67+
### **5. TransactionWorkload (transaction_test)**
68+
**Purpose**: Multi-command transactions with ACID properties
69+
**Operations**:
70+
- `MULTI` → Start transaction
71+
- `SET/GET/INCR` → Queued operations
72+
- `EXEC` → Execute transaction
73+
74+
**Use Cases**:
75+
- ACID transaction testing
76+
- Complex multi-step operations
77+
- Data consistency validation
78+
79+
## 🔧 Configuration Examples
80+
81+
### **Basic Read/Write**
82+
```bash
83+
python main.py run --workload-profile basic_rw --target-ops-per-second 1000
84+
```
85+
86+
### **High Throughput Pipeline**
87+
```bash
88+
python main.py run --workload-profile high_throughput --target-ops-per-second 100000
89+
```
90+
91+
### **List Operations**
92+
```bash
93+
python main.py run --workload-profile list_operations --target-ops-per-second 5000
94+
```
95+
96+
### **Pub/Sub Testing**
97+
```bash
98+
python main.py run --workload-profile pubsub_test --target-ops-per-second 1000
99+
```
100+
101+
### **Transaction Testing**
102+
```bash
103+
python main.py run --workload-profile transaction_test --target-ops-per-second 500
104+
```
105+
106+
## 📊 Metrics Per Operation
107+
108+
Each workload now provides **operation-specific metrics**:
109+
110+
### **Prometheus Metrics**
111+
```
112+
redis_operations_total{operation="SET", status="success"} 1234
113+
redis_operations_total{operation="GET", status="success"} 5678
114+
redis_operations_total{operation="LPUSH", status="success"} 910
115+
redis_operations_total{operation="PUBLISH", status="success"} 112
116+
```
117+
118+
### **Latency Histograms**
119+
```
120+
redis_operation_duration_seconds_bucket{operation="SET", le="0.001"} 800
121+
redis_operation_duration_seconds_bucket{operation="GET", le="0.001"} 900
122+
redis_operation_duration_seconds_bucket{operation="LPUSH", le="0.005"} 50
123+
```
124+
125+
## 🎯 Grafana Dashboard Queries
126+
127+
### **Operations Rate by Type**
128+
```promql
129+
rate(redis_operations_total[5m]) by (operation, status)
130+
```
131+
132+
### **Latency Percentiles by Operation**
133+
```promql
134+
histogram_quantile(0.95, rate(redis_operation_duration_seconds_bucket[5m])) by (operation)
135+
```
136+
137+
### **Error Rate by Operation**
138+
```promql
139+
rate(redis_operations_total{status="error"}[5m]) / rate(redis_operations_total[5m]) by (operation)
140+
```
141+
142+
## 🚀 Performance Characteristics
143+
144+
### **BasicWorkload**
145+
- **Throughput**: 10K-50K ops/sec
146+
- **Latency**: P95 < 5ms
147+
- **Use Case**: General testing
148+
149+
### **PipelineWorkload**
150+
- **Throughput**: 100K-1M+ ops/sec (your current 700K+!)
151+
- **Latency**: P95 < 10ms (batched)
152+
- **Use Case**: Maximum performance
153+
154+
### **ListWorkload**
155+
- **Throughput**: 5K-20K ops/sec
156+
- **Latency**: P95 < 8ms
157+
- **Use Case**: Data structure testing
158+
159+
### **PubSubWorkload**
160+
- **Throughput**: 1K-10K msgs/sec
161+
- **Latency**: P95 < 15ms
162+
- **Use Case**: Messaging patterns
163+
164+
### **TransactionWorkload**
165+
- **Throughput**: 500-5K txns/sec
166+
- **Latency**: P95 < 20ms
167+
- **Use Case**: ACID compliance
168+
169+
## 🔍 Operation-Specific Insights
170+
171+
With the new **direct Redis client method calls** (no more `execute_command`), you get:
172+
173+
### **🎯 True Operation-Level Metrics**
174+
- **Direct method calls**: `client.set()`, `client.get()`, `client.lpush()`, etc.
175+
- **Native Redis client**: Using the actual redis-py client methods
176+
- **Proper operation names**: Each operation tracked with its real Redis command name
177+
- **Accurate latencies**: Direct timing of actual Redis operations
178+
179+
### **📊 Benefits**
180+
1. **Track per-operation performance** - See which Redis commands are fastest/slowest
181+
2. **Identify bottlenecks** - Find operations causing latency spikes
182+
3. **Optimize workloads** - Focus on problematic operation types
183+
4. **Compare Redis versions** - See how different versions handle specific operations
184+
5. **Detect memory leaks** - Monitor per-operation memory usage patterns
185+
6. **True Redis testing** - Using the same methods your applications would use
186+
187+
### **🔧 Implementation Details**
188+
- **Helper method**: `_execute_with_metrics()` reduces code duplication
189+
- **Consistent timing**: All operations timed the same way
190+
- **Error handling**: Proper exception propagation with metrics
191+
- **Type safety**: Full type hints for all methods
192+
193+
This gives you **production-grade, operation-specific observability** into your Redis performance testing! 🚀

docker-compose.yml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ version: '3.8'
33
services:
44
# Redis Database
55
redis:
6-
image: redislabs/client-libs-test:8.0.2
6+
image: redis:8.2-m01
77
container_name: redis-test-db
88
ports:
99
- "6379:6379"
@@ -44,8 +44,6 @@ services:
4444
image: otel/opentelemetry-collector-contrib:latest
4545
container_name: otel-collector
4646
command: ["--config=/etc/otel-collector-config.yml"]
47-
env_file:
48-
- .env.docker
4947
volumes:
5048
- ./observability/otel-collector-config.yml:/etc/otel-collector-config.yml
5149
ports:
@@ -65,8 +63,6 @@ services:
6563
container_name: prometheus
6664
ports:
6765
- "9090:9090"
68-
env_file:
69-
- .env.docker
7066
volumes:
7167
- ./observability/prometheus.yml:/etc/prometheus/prometheus.yml
7268
- prometheus_data:/prometheus
@@ -86,8 +82,6 @@ services:
8682
container_name: grafana
8783
ports:
8884
- "3000:3000"
89-
env_file:
90-
- .env.docker
9185
environment:
9286
- GF_SECURITY_ADMIN_PASSWORD=admin
9387
- GF_USERS_ALLOW_SIGN_UP=false

observability/grafana/dashboards/redis-test-dashboard.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@
341341
"to": "now"
342342
},
343343
"timepicker": {},
344-
"refresh": "${GRAFANA_REFRESH_INTERVAL:-5s}",
344+
"refresh": "5s",
345345
"timezone": "",
346346
"title": "Redis Test App Dashboard",
347347
"uid": "redis-test-app",

observability/otel-collector-config.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ receivers:
1212
- job_name: 'redis-test-app'
1313
static_configs:
1414
- targets: ['redis-test-app:8000']
15-
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
15+
scrape_interval: 5s
1616
metrics_path: /metrics
1717

1818
processors:
@@ -37,26 +37,26 @@ exporters:
3737
const_labels:
3838
environment: docker
3939

40-
# Jaeger exporter
41-
jaeger:
42-
endpoint: jaeger:14250
40+
# OTLP exporter for Jaeger (using internal Docker network)
41+
otlp/jaeger:
42+
endpoint: jaeger:4317
4343
tls:
4444
insecure: true
4545

46-
# Logging exporter for debugging
47-
logging:
48-
loglevel: info
46+
# Debug exporter for debugging (replaces deprecated logging exporter)
47+
debug:
48+
verbosity: normal
4949

5050
service:
5151
pipelines:
5252
traces:
5353
receivers: [otlp]
5454
processors: [batch, resource]
55-
exporters: [jaeger, logging]
56-
55+
exporters: [otlp/jaeger, debug]
56+
5757
metrics:
5858
receivers: [otlp, prometheus]
5959
processors: [batch, resource]
60-
exporters: [prometheus, logging]
60+
exporters: [prometheus, debug]
6161

6262
extensions: []

observability/prometheus.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
global:
2-
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
3-
evaluation_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
2+
scrape_interval: 5s
3+
evaluation_interval: 5s
44

55
rule_files:
66
# - "first_rules.yml"
@@ -11,20 +11,20 @@ scrape_configs:
1111
- job_name: 'redis-test-app'
1212
static_configs:
1313
- targets: ['redis-test-app:8000']
14-
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
14+
scrape_interval: 5s
1515
metrics_path: /metrics
1616

1717
# OpenTelemetry Collector metrics
1818
- job_name: 'otel-collector'
1919
static_configs:
2020
- targets: ['otel-collector:8888']
21-
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
21+
scrape_interval: 5s
2222

2323
# Prometheus itself
2424
- job_name: 'prometheus'
2525
static_configs:
2626
- targets: ['localhost:9090']
27-
scrape_interval: ${PROMETHEUS_SCRAPE_INTERVAL:-5s}
27+
scrape_interval: 5s
2828

2929
# Redis exporter (optional - if you want Redis internal metrics)
3030
# - job_name: 'redis'

0 commit comments

Comments
 (0)