From c0ed5084ac5f7c7f94c295c1077c0fae1e791cae Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Sun, 19 Oct 2025 18:14:21 -0300 Subject: [PATCH 1/7] Add resource limits for containers --- engineering/bitonic-scala3/docker-compose.yml | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/engineering/bitonic-scala3/docker-compose.yml b/engineering/bitonic-scala3/docker-compose.yml index 72319f6..6a20249 100644 --- a/engineering/bitonic-scala3/docker-compose.yml +++ b/engineering/bitonic-scala3/docker-compose.yml @@ -11,6 +11,11 @@ services: interval: 5s timeout: 3s retries: 5 + deploy: + resources: + limits: + cpus: '0.25' + memory: 256M memcached: image: memcached:alpine3.22 container_name: memcached @@ -28,6 +33,11 @@ services: - --conn-limit=1024 - --memory-limit=64 - --threads=4 + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M app: container_name: bitonic-app @@ -67,9 +77,14 @@ services: # Add stdin/tty for interactive logging stdin_open: true tty: true + deploy: + resources: + limits: + cpus: '1.0' + memory: 1024M influxdb: - image: influxdb:1.8 + image: influxdb:1.12.2 environment: INFLUXDB_DB: k6 INFLUXDB_ADMIN_USER: admin @@ -81,6 +96,11 @@ services: - influxdb-data:/var/lib/influxdb networks: - bitonic + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M grafana: image: grafana/grafana @@ -91,13 +111,20 @@ services: environment: GF_SECURITY_ADMIN_USER: admin GF_SECURITY_ADMIN_PASSWORD: admin + GF_SECURITY_FORCE_DEFAULT_ADMIN_PASSWORD_CHANGE: "false" SSL_CERT_FILE: /etc/ssl/certs/custom-cert.pem volumes: - ./grafana/provisioning:/etc/grafana/provisioning - ./grafana/dashboards:/var/lib/grafana/dashboards + - ./grafana/config/custom.ini:/etc/grafana/custom.ini restart: always networks: - bitonic + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M k6: image: grafana/k6:latest @@ -108,7 +135,10 @@ services: condition: service_started volumes: - ./benchmark/payloads.json:/benchmark/payloads.json + - ./benchmark/payloads_realistic.json:/benchmark/payloads_realistic.json + - ./benchmark/payloads_random.json:/benchmark/payloads_random.json - ./benchmark/benchmark.js:/benchmark/benchmark.js + - ./benchmark/benchmark_cache_comparison.js:/benchmark/benchmark_cache_comparison.js networks: - bitonic entrypoint: ["k6"] @@ -117,8 +147,13 @@ services: "run", "--out", "influxdb=http://influxdb:8086/k6?consistency=one", - "/benchmark/benchmark.js", + "/benchmark/benchmark_cache_comparison.js", ] + deploy: + resources: + limits: + cpus: '0.5' + memory: 256M networks: bitonic: From 42c549b6a6b245608aeb4a3ed50947185baf4b84 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 07:29:44 -0300 Subject: [PATCH 2/7] Add resource limits for containers --- engineering/bitonic-scala3/docker-compose.yml | 53 ++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/engineering/bitonic-scala3/docker-compose.yml b/engineering/bitonic-scala3/docker-compose.yml index 6a20249..e09d729 100644 --- a/engineering/bitonic-scala3/docker-compose.yml +++ b/engineering/bitonic-scala3/docker-compose.yml @@ -39,6 +39,40 @@ services: cpus: '0.25' memory: 128M + redis-exporter: + image: oliver006/redis_exporter:latest + container_name: redis-exporter + ports: + - "9121:9121" + environment: + REDIS_ADDR: redis:6379 + networks: + - bitonic + depends_on: + - redis + deploy: + resources: + limits: + cpus: '0.1' + memory: 64M + + memcached-exporter: + image: prom/memcached-exporter:latest + container_name: memcached-exporter + ports: + - "9150:9150" + command: + - --memcached.address=memcached:11211 + networks: + - bitonic + depends_on: + - memcached + deploy: + resources: + limits: + cpus: '0.1' + memory: 64M + app: container_name: bitonic-app build: . @@ -102,6 +136,23 @@ services: cpus: '0.5' memory: 512M + telegraf: + image: telegraf:latest + container_name: telegraf + volumes: + - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro + networks: + - bitonic + depends_on: + - influxdb + - redis-exporter + - memcached-exporter + deploy: + resources: + limits: + cpus: '0.25' + memory: 256M + grafana: image: grafana/grafana depends_on: @@ -147,7 +198,7 @@ services: "run", "--out", "influxdb=http://influxdb:8086/k6?consistency=one", - "/benchmark/benchmark_cache_comparison.js", + "/benchmark/benchmark.js", ] deploy: resources: From d351d82797c0faca5a69d3efd70c393f21184f98 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 08:28:50 -0300 Subject: [PATCH 3/7] Modify doc to explain benchmark tests --- .../bitonic-scala3/benchmark/README.md | 145 ++++++++++++++---- 1 file changed, 115 insertions(+), 30 deletions(-) diff --git a/engineering/bitonic-scala3/benchmark/README.md b/engineering/bitonic-scala3/benchmark/README.md index b3c1fe0..ed212a2 100644 --- a/engineering/bitonic-scala3/benchmark/README.md +++ b/engineering/bitonic-scala3/benchmark/README.md @@ -1,48 +1,133 @@ -# Bitonic Benchmark Runner +# Bitonic Benchmark Suite -This script benchmarks the two endpoints: +This directory contains benchmarking tools for testing three endpoints: -- `POST /bitonic?n=...&l=...&r=...` -- `POST /bitonic-memcached?n=...&l=...&r=...` - -It measures latency statistics across different `n` sizes, with configurable concurrency and request counts, and writes a CSV report. +- `POST /bitonic?n=...&l=...&r=...` β€” Direct calculation (no cache) +- `POST /bitonic-redis?n=...&l=...&r=...` β€” Redis cache +- `POST /bitonic-memcached?n=...&l=...&r=...` β€” Memcached cache ## Requirements -- Python 3.9+ -- `aiohttp` +- Docker and Docker Compose +- (Optional) Python 3.9+ for standalone scripts -Install dependencies: +## Running Benchmarks -1. **Install Python 3.11.13 using pyenv:** - ```bash - pyenv install 3.11.13 - pyenv local 3.11.13 # Set for current project - ``` +### Quick Start -2. **Install uv package manager:** +1. **Start all services (app, cache, monitoring, and benchmark):** ```bash - pip install uv==0.7.11 + docker compose up ``` -3. **Create and activate virtual environment:** - ```bash - uv venv - source .venv/bin/activate - ``` +2. **View results in Grafana:** + - URL: http://localhost:3000 + - Username: `admin` + - Password: `admin` + - Dashboard: "Bitonic Service Performance Comparison" - ```bash - pip install aiohttp - ``` +### What Gets Measured -## Usage +The Grafana dashboard shows: -```bash -python benchmark_bitonic.py --base-url http://localhost:8080 --endpoints bitonic bitonic-memcached --sizes 16 32 64 128 256 512 1024 --l 1 --r 100000 --requests 200 --concurrency 50 --warmup 20 --out results.csv +**Performance Metrics:** +- Response Time Comparison (Standard vs Redis vs Memcached) +- Throughput (Requests/Second) +- 95th Percentile Response Time (P95) +- 99th Percentile Response Time (P99) +- Error Rate Comparison + +**Cache Metrics:** +- Redis Cache Hit/Miss Rate +- Memcached Cache Hit/Miss Rate +- Cache performance over time + +**Visual Indicators:** +- Color-coded thresholds for response times: + - 🟒 Green (0-50ms): Excellent + - 🟑 Yellow (50-100ms): Good + - 🟠 Orange (100-150ms): Attention needed + - πŸ”΄ Red (>150ms): Problematic + +## Benchmark Payloads + +The benchmark uses `payloads.json` containing 50,000 test cases with: +- **Array sizes**: 0-1,000 (random distribution) +- **Range types**: Random l and r values +- **Purpose**: Comprehensive stress testing of all three endpoints + +## Understanding Percentiles (P95, P99) + +**What are percentiles?** +- **P95 (95th Percentile)**: 95% of requests were faster than this value (only 5% were slower) +- **P99 (99th Percentile)**: 99% of requests were faster than this value (only 1% were slower) + +**Why they matter:** +- The **mean** (average) can hide performance problems +- Percentiles show the **worst-case experience** for your users +- High P99 values indicate some users are experiencing poor performance + +**Example:** +``` +If Redis P99 = 50ms, it means: +- 99% of requests completed in ≀ 50ms (excellent!) +- Only 1% took longer (outliers) ``` -## Output +## Architecture -- A `results.csv` with columns: - - `endpoint, n, l, r, requests, concurrency, success_rate, latency_mean_s, latency_stdev_s, latency_p50_s, latency_p90_s, latency_p95_s, latency_p99_s, resp_size_mean_bytes` +The benchmark infrastructure consists of: + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ K6 Load β”‚ ──── Sends HTTP requests ───▢ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Generator β”‚ β”‚ Bitonic App β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ (3 endpoints)β”‚ + β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ β”‚ + β”‚ Sends metrics Uses cache + β–Ό β–Ό +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ InfluxDB β”‚ ◀──── Scraped by ──────── β”‚ Redis/Memcached β”‚ +β”‚ (Time-seriesβ”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +β”‚ Database) β”‚ β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”‚ + β”‚ β”‚Telegraf β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ Queries β”‚(Scraper)β”‚ Exports metrics + β–Ό β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Grafana β”‚ ──── Visualizes ────▢ Dashboard +β”‚ (Dashboard) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +## Resource Limits + +All containers have CPU and memory limits configured: +- **App**: 1 CPU, 1GB RAM +- **Redis**: 0.25 CPU, 256MB RAM +- **Memcached**: 0.25 CPU, 128MB RAM +- **InfluxDB**: 0.5 CPU, 512MB RAM +- **Grafana**: 0.5 CPU, 512MB RAM +- **K6**: 0.5 CPU, 256MB RAM + +This ensures consistent and fair performance comparison. + +## Troubleshooting + +### Dashboard shows no data +- Wait for K6 to start sending requests (starts automatically with `docker compose up`) +- Check if InfluxDB is running: `docker ps | grep influx` +- Verify K6 is running: `docker logs bitonic-scala3-k6-1` + +### K6 finished but want to run again +```bash +docker compose restart k6 +``` + +### Clear all metrics and start fresh +```bash +docker compose down -v # Removes volumes (InfluxDB data) +docker compose up +``` From 880e8dd2849094c2d9b95a432e291fa30236c776 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 08:29:25 -0300 Subject: [PATCH 4/7] Remove files --- engineering/bitonic-scala3/docker-compose.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/engineering/bitonic-scala3/docker-compose.yml b/engineering/bitonic-scala3/docker-compose.yml index e09d729..3b06034 100644 --- a/engineering/bitonic-scala3/docker-compose.yml +++ b/engineering/bitonic-scala3/docker-compose.yml @@ -186,10 +186,7 @@ services: condition: service_started volumes: - ./benchmark/payloads.json:/benchmark/payloads.json - - ./benchmark/payloads_realistic.json:/benchmark/payloads_realistic.json - - ./benchmark/payloads_random.json:/benchmark/payloads_random.json - ./benchmark/benchmark.js:/benchmark/benchmark.js - - ./benchmark/benchmark_cache_comparison.js:/benchmark/benchmark_cache_comparison.js networks: - bitonic entrypoint: ["k6"] From 4d684735593a93eff8b3b0af0831505ea3369674 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 08:29:57 -0300 Subject: [PATCH 5/7] Add telegraf configuration --- .../bitonic-scala3/telegraf/telegraf.conf | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 engineering/bitonic-scala3/telegraf/telegraf.conf diff --git a/engineering/bitonic-scala3/telegraf/telegraf.conf b/engineering/bitonic-scala3/telegraf/telegraf.conf new file mode 100644 index 0000000..dba09a9 --- /dev/null +++ b/engineering/bitonic-scala3/telegraf/telegraf.conf @@ -0,0 +1,54 @@ +# Telegraf Configuration + +# Global tags can be specified here in key="value" format. +[global_tags] + environment = "development" + +# Configuration for telegraf agent +[agent] + interval = "10s" + round_interval = true + metric_batch_size = 1000 + metric_buffer_limit = 10000 + collection_jitter = "0s" + flush_interval = "10s" + flush_jitter = "0s" + precision = "" + hostname = "" + omit_hostname = false + +############################################################################### +# OUTPUT PLUGINS # +############################################################################### + +# Configuration for sending metrics to InfluxDB +[[outputs.influxdb]] + urls = ["http://influxdb:8086"] + database = "k6" + username = "admin" + password = "admin" + retention_policy = "" + write_consistency = "any" + timeout = "5s" + +############################################################################### +# INPUT PLUGINS # +############################################################################### + +# Read metrics from Redis Exporter +[[inputs.prometheus]] + urls = ["http://redis-exporter:9121/metrics"] + metric_version = 2 + + # Add custom tags + [inputs.prometheus.tags] + cache_type = "redis" + +# Read metrics from Memcached Exporter +[[inputs.prometheus]] + urls = ["http://memcached-exporter:9150/metrics"] + metric_version = 2 + + # Add custom tags + [inputs.prometheus.tags] + cache_type = "memcached" From 4ad6f2edada598c27736c854c5e230cea8c53ba2 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 08:39:00 -0300 Subject: [PATCH 6/7] Update documentation --- .../bitonic-scala3/benchmark/README.md | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/engineering/bitonic-scala3/benchmark/README.md b/engineering/bitonic-scala3/benchmark/README.md index ed212a2..95e5391 100644 --- a/engineering/bitonic-scala3/benchmark/README.md +++ b/engineering/bitonic-scala3/benchmark/README.md @@ -93,14 +93,30 @@ The benchmark infrastructure consists of: β”‚ Database) β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”˜ β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β” β”‚ β”‚ β”‚Telegraf β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ Queries β”‚(Scraper)β”‚ Exports metrics - β–Ό β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Queries β”‚(Scraper)β”‚ Exports metrics via: + β–Ό β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - Redis Exporter (port 9121) +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - Memcached Exporter (port 9150) β”‚ Grafana β”‚ ──── Visualizes ────▢ Dashboard β”‚ (Dashboard) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` +### Cache Metrics Collection + +**Redis Metrics:** +- Collected via [Redis Exporter](https://github.com/oliver006/redis_exporter) (port 9121) +- Key metrics: `redis_keyspace_hits_total`, `redis_keyspace_misses_total` + +**Memcached Metrics:** +- Collected via [Memcached Exporter](https://github.com/prometheus/memcached_exporter) (port 9150) +- Key metrics: `memcached_commands_total{command="get",status="hit/miss"}` + +**Collection Flow:** +1. Exporters scrape cache statistics from Redis/Memcached +2. Telegraf collects Prometheus-formatted metrics from exporters (every 10s) +3. Telegraf sends metrics to InfluxDB (database: `k6`, measurement: `prometheus`) +4. Grafana queries InfluxDB and visualizes cache hit/miss rates + ## Resource Limits All containers have CPU and memory limits configured: @@ -120,6 +136,31 @@ This ensures consistent and fair performance comparison. - Check if InfluxDB is running: `docker ps | grep influx` - Verify K6 is running: `docker logs bitonic-scala3-k6-1` +### Cache metrics not showing +1. **Verify exporters are running:** + ```bash + docker ps | grep exporter + ``` + +2. **Test exporters directly:** + ```bash + # Redis Exporter + curl http://localhost:9121/metrics | grep keyspace + + # Memcached Exporter + curl http://localhost:9150/metrics | grep commands + ``` + +3. **Check Telegraf logs:** + ```bash + docker logs telegraf + ``` + +4. **Query InfluxDB directly:** + ```bash + docker exec bitonic-scala3-influxdb-1 influx -database 'k6' -execute 'SELECT * FROM prometheus WHERE cache_type = '\''redis'\'' LIMIT 5' + ``` + ### K6 finished but want to run again ```bash docker compose restart k6 From cea3b1b1de33413b3e5c3acfdd410f053cf5e895 Mon Sep 17 00:00:00 2001 From: Rodrigo de Lima Silva Date: Mon, 20 Oct 2025 08:39:25 -0300 Subject: [PATCH 7/7] Enhance Bitonic comparison dashboard with additional metrics and thresholds for cache hit/miss rates --- .../bitonic-comparison-dashboard.json | 406 +++++++++++++++++- 1 file changed, 401 insertions(+), 5 deletions(-) diff --git a/engineering/bitonic-scala3/grafana/dashboards/bitonic-comparison-dashboard.json b/engineering/bitonic-scala3/grafana/dashboards/bitonic-comparison-dashboard.json index 7797f9e..5621ac3 100644 --- a/engineering/bitonic-scala3/grafana/dashboards/bitonic-comparison-dashboard.json +++ b/engineering/bitonic-scala3/grafana/dashboards/bitonic-comparison-dashboard.json @@ -687,6 +687,8 @@ } }, "mappings": [], + "max": 1, + "min": 0, "thresholds": { "mode": "absolute", "steps": [ @@ -696,7 +698,7 @@ }, { "color": "red", - "value": 80 + "value": 0.8 } ] }, @@ -776,7 +778,7 @@ "mode": "none" }, "thresholdsStyle": { - "mode": "off" + "mode": "line" } }, "mappings": [], @@ -787,9 +789,17 @@ "color": "green", "value": null }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "orange", + "value": 100 + }, { "color": "red", - "value": 80 + "value": 150 } ] }, @@ -869,7 +879,7 @@ "mode": "none" }, "thresholdsStyle": { - "mode": "off" + "mode": "line" } }, "mappings": [], @@ -880,9 +890,17 @@ "color": "green", "value": null }, + { + "color": "yellow", + "value": 50 + }, + { + "color": "orange", + "value": 100 + }, { "color": "red", - "value": 80 + "value": 150 } ] }, @@ -929,6 +947,384 @@ ], "title": "99th Percentile Response Time", "type": "timeseries" + }, + { + "datasource": "k6_influx", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "vis": false + }, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [ + { + "matcher": { + "id": "byRegexp", + "options": ".*Hit.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "green" + } + } + ] + }, + { + "matcher": { + "id": "byRegexp", + "options": ".*Miss.*" + }, + "properties": [ + { + "id": "color", + "value": { + "mode": "fixed", + "fixedColor": "red" + } + } + ] + } + ] + }, + "gridPos": { + "h": 8, + "w": 24, + "x": 0, + "y": 32 + }, + "id": 12, + "options": { + "legend": { + "calcs": ["mean", "last"], + "displayMode": "table", + "placement": "bottom" + }, + "tooltip": { + "mode": "multi" + } + }, + "targets": [ + { + "query": "SELECT derivative(mean(\"redis_keyspace_hits_total\"), 1s) / (derivative(mean(\"redis_keyspace_hits_total\"), 1s) + derivative(mean(\"redis_keyspace_misses_total\"), 1s)) FROM \"prometheus\" WHERE \"cache_type\" = 'redis' AND $timeFilter GROUP BY time(10s) fill(null)", + "rawQuery": true, + "refId": "A", + "alias": "Redis Cache Hit Rate" + }, + { + "query": "SELECT derivative(mean(\"redis_keyspace_misses_total\"), 1s) / (derivative(mean(\"redis_keyspace_hits_total\"), 1s) + derivative(mean(\"redis_keyspace_misses_total\"), 1s)) FROM \"prometheus\" WHERE \"cache_type\" = 'redis' AND $timeFilter GROUP BY time(10s) fill(null)", + "rawQuery": true, + "refId": "B", + "alias": "Redis Cache Miss Rate" + }, + { + "query": "SELECT hits / (hits + misses) FROM (SELECT derivative(mean(\"memcached_commands_total\"), 1s) AS hits FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'hit' AND $timeFilter GROUP BY time(10s) fill(null)), (SELECT derivative(mean(\"memcached_commands_total\"), 1s) AS misses FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'miss' AND $timeFilter GROUP BY time(10s) fill(null))", + "rawQuery": true, + "refId": "C", + "alias": "Memcached Cache Hit Rate" + }, + { + "query": "SELECT misses / (hits + misses) FROM (SELECT derivative(mean(\"memcached_commands_total\"), 1s) AS hits FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'hit' AND $timeFilter GROUP BY time(10s) fill(null)), (SELECT derivative(mean(\"memcached_commands_total\"), 1s) AS misses FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'miss' AND $timeFilter GROUP BY time(10s) fill(null))", + "rawQuery": true, + "refId": "D", + "alias": "Memcached Cache Miss Rate" + } + ], + "title": "Cache Hit/Miss Rate Over Time", + "type": "timeseries" + }, + { + "datasource": "k6_influx", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 0.5 + }, + { + "color": "green", + "value": 0.8 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 0, + "y": 40 + }, + "id": 13, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "query": "SELECT (last(\"redis_keyspace_hits_total\") - first(\"redis_keyspace_hits_total\")) / ((last(\"redis_keyspace_hits_total\") - first(\"redis_keyspace_hits_total\")) + (last(\"redis_keyspace_misses_total\") - first(\"redis_keyspace_misses_total\"))) FROM \"prometheus\" WHERE \"cache_type\" = 'redis' AND $timeFilter", + "rawQuery": true, + "refId": "A" + } + ], + "title": "Redis Cache Hit Rate", + "type": "stat" + }, + { + "datasource": "k6_influx", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.2 + }, + { + "color": "red", + "value": 0.5 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 6, + "y": 40 + }, + "id": 14, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "query": "SELECT (last(\"redis_keyspace_misses_total\") - first(\"redis_keyspace_misses_total\")) / ((last(\"redis_keyspace_hits_total\") - first(\"redis_keyspace_hits_total\")) + (last(\"redis_keyspace_misses_total\") - first(\"redis_keyspace_misses_total\"))) FROM \"prometheus\" WHERE \"cache_type\" = 'redis' AND $timeFilter", + "rawQuery": true, + "refId": "A" + } + ], + "title": "Redis Cache Miss Rate", + "type": "stat" + }, + { + "datasource": "k6_influx", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "yellow", + "value": 0.5 + }, + { + "color": "green", + "value": 0.8 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 12, + "y": 40 + }, + "id": 15, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "query": "SELECT last(hit) / (last(hit) + last(miss)) FROM (SELECT last(\"memcached_commands_total\") AS hit FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'hit' AND $timeFilter), (SELECT last(\"memcached_commands_total\") AS miss FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'miss' AND $timeFilter)", + "rawQuery": true, + "refId": "A" + } + ], + "title": "Memcached Cache Hit Rate", + "type": "stat" + }, + { + "datasource": "k6_influx", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "max": 1, + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "yellow", + "value": 0.2 + }, + { + "color": "red", + "value": 0.5 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 6, + "x": 18, + "y": 40 + }, + "id": 16, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": ["lastNotNull"], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "8.0.6", + "targets": [ + { + "query": "SELECT last(miss) / (last(hit) + last(miss)) FROM (SELECT last(\"memcached_commands_total\") AS hit FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'hit' AND $timeFilter), (SELECT last(\"memcached_commands_total\") AS miss FROM \"prometheus\" WHERE \"cache_type\" = 'memcached' AND \"command\" = 'get' AND \"status\" = 'miss' AND $timeFilter)", + "rawQuery": true, + "refId": "A" + } + ], + "title": "Memcached Cache Miss Rate", + "type": "stat" } ], "refresh": "5s",