Set up comprehensive monitoring for your Redis cluster using redis_exporter, Prometheus, and Grafana. Configure custom dashboards and alerting rules to track performance metrics, cluster health, and resource utilization.
Prerequisites
- Redis cluster running
- Prometheus installed
- Grafana installed
- Root access
What this solves
Redis cluster monitoring requires tracking multiple nodes, replication status, memory usage, and performance metrics across your distributed cache infrastructure. This tutorial sets up comprehensive monitoring using redis_exporter to collect metrics, Prometheus to store them, and Grafana to visualize cluster health with custom dashboards and alerting rules.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you have the latest packages available.
sudo apt update && sudo apt upgrade -y
Install required dependencies
Install wget and systemd utilities needed for downloading and managing the monitoring services.
sudo apt install -y wget curl systemd tar
Create monitoring user
Create a dedicated system user for running the redis_exporter service securely.
sudo useradd --no-create-home --shell /bin/false redis_exporter
Download and install redis_exporter
Download the latest redis_exporter binary from the official GitHub releases and install it system-wide.
cd /tmp
wget https://github.com/oliver006/redis_exporter/releases/download/v1.55.0/redis_exporter-v1.55.0.linux-amd64.tar.gz
tar xzf redis_exporter-v1.55.0.linux-amd64.tar.gz
sudo cp redis_exporter-v1.55.0.linux-amd64/redis_exporter /usr/local/bin/
sudo chown redis_exporter:redis_exporter /usr/local/bin/redis_exporter
sudo chmod 755 /usr/local/bin/redis_exporter
Configure redis_exporter service
Create a systemd service file to manage the redis_exporter process with automatic startup and monitoring.
[Unit]
Description=Redis Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=redis_exporter
Group=redis_exporter
Type=simple
ExecStart=/usr/local/bin/redis_exporter \
-redis.addr=redis://localhost:6379 \
-redis.addr=redis://localhost:6380 \
-redis.addr=redis://localhost:6381 \
-web.listen-address=:9121
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Start and enable redis_exporter
Enable the redis_exporter service to start on boot and start it immediately.
sudo systemctl daemon-reload
sudo systemctl enable redis_exporter
sudo systemctl start redis_exporter
sudo systemctl status redis_exporter
Configure Prometheus scraping
Add the redis_exporter endpoints to your Prometheus configuration to collect Redis cluster metrics.
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "redis_cluster_rules.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'redis-cluster'
static_configs:
- targets: ['localhost:9121']
scrape_interval: 10s
metrics_path: /metrics
params:
format: [prometheus]
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
Create Redis cluster alerting rules
Define Prometheus alerting rules to monitor critical Redis cluster conditions and performance thresholds.
groups:
- name: redis_cluster_alerts
rules:
- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis instance is down"
description: "Redis instance {{ $labels.instance }} has been down for more than 1 minute."
- alert: RedisHighMemoryUsage
expr: (redis_memory_used_bytes / redis_memory_max_bytes) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Redis memory usage is high"
description: "Redis instance {{ $labels.instance }} memory usage is {{ $value }}%"
- alert: RedisSlowlog
expr: increase(redis_slowlog_length[5m]) > 0
for: 1m
labels:
severity: warning
annotations:
summary: "Redis slow queries detected"
description: "Redis instance {{ $labels.instance }} has {{ $value }} slow queries in the last 5 minutes"
- alert: RedisClusterNodeFailure
expr: redis_cluster_nodes{role="master",state!="ok"} > 0
for: 2m
labels:
severity: critical
annotations:
summary: "Redis cluster master node failure"
description: "Redis cluster master node {{ $labels.instance }} is in {{ $labels.state }} state"
- alert: RedisHighConnections
expr: redis_connected_clients > redis_config_maxclients * 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "Redis connection count is high"
description: "Redis instance {{ $labels.instance }} has {{ $value }} connections (>80% of max)"
Restart Prometheus to load new configuration
Reload Prometheus configuration to start collecting Redis metrics and enable the new alerting rules.
sudo systemctl restart prometheus
sudo systemctl status prometheus
Import Redis cluster dashboard in Grafana
Create a comprehensive Grafana dashboard configuration for monitoring Redis cluster performance and health metrics.
{
"dashboard": {
"id": null,
"title": "Redis Cluster Monitoring",
"description": "Comprehensive Redis cluster monitoring dashboard",
"tags": ["redis", "cluster", "monitoring"],
"timezone": "browser",
"panels": [
{
"id": 1,
"title": "Redis Instances Status",
"type": "stat",
"targets": [
{
"expr": "redis_up",
"legendFormat": "{{ instance }}"
}
],
"fieldConfig": {
"defaults": {
"mappings": [
{
"options": {
"0": {"text": "DOWN", "color": "red"},
"1": {"text": "UP", "color": "green"}
},
"type": "value"
}
]
}
},
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 0}
},
{
"id": 2,
"title": "Memory Usage",
"type": "timeseries",
"targets": [
{
"expr": "redis_memory_used_bytes",
"legendFormat": "{{ instance }} - Used Memory"
},
{
"expr": "redis_memory_max_bytes",
"legendFormat": "{{ instance }} - Max Memory"
}
],
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 0}
},
{
"id": 3,
"title": "Commands Per Second",
"type": "timeseries",
"targets": [
{
"expr": "rate(redis_commands_processed_total[5m])",
"legendFormat": "{{ instance }} - Commands/sec"
}
],
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 8}
},
{
"id": 4,
"title": "Connected Clients",
"type": "timeseries",
"targets": [
{
"expr": "redis_connected_clients",
"legendFormat": "{{ instance }} - Clients"
}
],
"gridPos": {"h": 8, "w": 12, "x": 12, "y": 8}
},
{
"id": 5,
"title": "Cluster Slots Assignment",
"type": "table",
"targets": [
{
"expr": "redis_cluster_slots_assigned",
"legendFormat": "Assigned Slots",
"format": "table"
}
],
"gridPos": {"h": 8, "w": 24, "x": 0, "y": 16}
}
],
"time": {
"from": "now-1h",
"to": "now"
},
"refresh": "30s"
}
}
Import dashboard via Grafana API
Use curl to import the Redis cluster dashboard into Grafana via the API.
curl -X POST \
http://admin:admin@localhost:3000/api/dashboards/db \
-H 'Content-Type: application/json' \
-d @/tmp/redis-cluster-dashboard.json
Configure Grafana data source
Add Prometheus as a data source in Grafana to connect your Redis metrics for visualization.
curl -X POST \
http://admin:admin@localhost:3000/api/datasources \
-H 'Content-Type: application/json' \
-d '{
"name": "prometheus-redis",
"type": "prometheus",
"url": "http://localhost:9090",
"access": "proxy",
"isDefault": true
}'
Configure dashboard alerts
Set up Grafana alerting rules that complement the Prometheus alerts for Redis cluster monitoring.
{
"alert": {
"name": "Redis High Memory Usage Alert",
"message": "Redis memory usage is above 80%",
"frequency": "10s",
"conditions": [
{
"query": {
"queryType": "prometheus",
"refId": "A",
"expr": "(redis_memory_used_bytes / redis_memory_max_bytes) * 100"
},
"reducer": {
"type": "last",
"params": []
},
"evaluator": {
"params": [80],
"type": "gt"
}
}
],
"executionErrorState": "alerting",
"noDataState": "no_data",
"for": "5m"
},
"notificationChannels": [
{
"name": "email-alerts",
"type": "email",
"settings": {
"addresses": "admin@example.com",
"subject": "Redis Cluster Alert"
}
}
]
}
Enable firewall rules for monitoring ports
Configure firewall rules to allow access to the redis_exporter and monitoring services.
sudo ufw allow 9121/tcp comment "Redis Exporter"
sudo ufw allow 9090/tcp comment "Prometheus"
sudo ufw allow 3000/tcp comment "Grafana"
sudo ufw reload
Verify your setup
Test that all monitoring components are working correctly and collecting Redis cluster metrics.
# Check redis_exporter status and metrics
sudo systemctl status redis_exporter
curl http://localhost:9121/metrics | grep redis_up
Verify Prometheus is scraping Redis metrics
curl http://localhost:9090/api/v1/query?query=redis_up
Check Grafana dashboard access
curl -I http://localhost:3000/dashboards
Test Redis cluster connectivity
redis-cli -c -p 6379 cluster nodes
redis-cli -c -p 6379 cluster info
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| redis_exporter fails to start | Redis connection refused | Check Redis is running: sudo systemctl status redis |
| No metrics in Grafana | Prometheus not scraping | Verify targets in Prometheus: http://localhost:9090/targets |
| Dashboard shows "No data" | Data source misconfigured | Check Grafana data source URL points to Prometheus |
| Alerts not firing | Alertmanager not configured | Configure notification channels in Grafana settings |
| Permission denied on metrics | User permissions issue | Ensure redis_exporter user has access: sudo chmod 755 /usr/local/bin/redis_exporter |
| High memory false alerts | Incorrect memory calculation | Verify Redis maxmemory setting: redis-cli CONFIG GET maxmemory |
Next steps
- Setup MinIO monitoring with Prometheus and Grafana dashboards for object storage observability
- Configure Prometheus Alertmanager with Slack integration for team notifications to enhance your alerting workflow
- Implement Redis backup automation with compression and encryption for data protection
- Configure Redis cluster SSL encryption and authentication for enhanced security
- Setup centralized log aggregation with ELK Stack for comprehensive monitoring
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Redis Cluster Monitoring Setup Script
# Sets up redis_exporter, Prometheus configuration, and Grafana dashboards
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Default values
REDIS_ADDRS="${REDIS_ADDRS:-redis://localhost:6379,redis://localhost:6380,redis://localhost:6381}"
EXPORTER_VERSION="${EXPORTER_VERSION:-v1.55.0}"
PROMETHEUS_CONFIG="${PROMETHEUS_CONFIG:-/etc/prometheus/prometheus.yml}"
usage() {
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -r ADDRS Comma-separated Redis addresses (default: $REDIS_ADDRS)"
echo " -v VERSION Redis exporter version (default: $EXPORTER_VERSION)"
echo " -p CONFIG Prometheus config path (default: $PROMETHEUS_CONFIG)"
echo " -h Show this help"
exit 1
}
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
cleanup() {
log_error "Script failed. Cleaning up..."
systemctl stop redis_exporter 2>/dev/null || true
systemctl disable redis_exporter 2>/dev/null || true
rm -f /etc/systemd/system/redis_exporter.service
userdel redis_exporter 2>/dev/null || true
rm -f /usr/local/bin/redis_exporter
systemctl daemon-reload
}
trap cleanup ERR
# Parse arguments
while getopts "r:v:p:h" opt; do
case $opt in
r) REDIS_ADDRS="$OPTARG" ;;
v) EXPORTER_VERSION="$OPTARG" ;;
p) PROMETHEUS_CONFIG="$OPTARG" ;;
h) usage ;;
*) usage ;;
esac
done
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
echo "[1/8] Detecting distribution..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_info "Detected distribution: $PRETTY_NAME"
else
log_error "Cannot detect distribution - /etc/os-release not found"
exit 1
fi
echo "[2/8] Updating system packages..."
$PKG_UPDATE
echo "[3/8] Installing required dependencies..."
$PKG_INSTALL wget curl systemd tar
echo "[4/8] Creating redis_exporter user..."
if ! id redis_exporter >/dev/null 2>&1; then
useradd --no-create-home --shell /bin/false redis_exporter
log_info "Created redis_exporter user"
else
log_warn "User redis_exporter already exists"
fi
echo "[5/8] Downloading and installing redis_exporter..."
cd /tmp
DOWNLOAD_URL="https://github.com/oliver006/redis_exporter/releases/download/${EXPORTER_VERSION}/redis_exporter-${EXPORTER_VERSION}.linux-amd64.tar.gz"
wget "$DOWNLOAD_URL"
tar xzf "redis_exporter-${EXPORTER_VERSION}.linux-amd64.tar.gz"
cp "redis_exporter-${EXPORTER_VERSION}.linux-amd64/redis_exporter" /usr/local/bin/
chown redis_exporter:redis_exporter /usr/local/bin/redis_exporter
chmod 755 /usr/local/bin/redis_exporter
rm -rf "redis_exporter-${EXPORTER_VERSION}.linux-amd64"*
echo "[6/8] Creating systemd service..."
# Convert comma-separated addresses to multiple -redis.addr flags
REDIS_ARGS=""
IFS=',' read -ra ADDR_ARRAY <<< "$REDIS_ADDRS"
for addr in "${ADDR_ARRAY[@]}"; do
REDIS_ARGS="$REDIS_ARGS -redis.addr=$addr"
done
cat > /etc/systemd/system/redis_exporter.service << EOF
[Unit]
Description=Redis Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=redis_exporter
Group=redis_exporter
Type=simple
ExecStart=/usr/local/bin/redis_exporter$REDIS_ARGS -web.listen-address=:9121
Restart=always
RestartSec=5
NoNewPrivileges=yes
ProtectHome=yes
ProtectSystem=strict
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable redis_exporter
systemctl start redis_exporter
echo "[7/8] Creating Prometheus configuration..."
mkdir -p "$(dirname "$PROMETHEUS_CONFIG")"
cat > "$PROMETHEUS_CONFIG" << EOF
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- "redis_cluster_rules.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'redis-cluster'
static_configs:
- targets: ['localhost:9121']
scrape_interval: 10s
metrics_path: /metrics
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
EOF
# Create alerting rules
cat > "$(dirname "$PROMETHEUS_CONFIG")/redis_cluster_rules.yml" << EOF
groups:
- name: redis_cluster_alerts
rules:
- alert: RedisDown
expr: redis_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Redis instance is down"
description: "Redis instance {{ \$labels.instance }} has been down for more than 1 minute."
- alert: RedisHighMemoryUsage
expr: (redis_memory_used_bytes / redis_memory_max_bytes) * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "Redis memory usage is high"
description: "Redis instance {{ \$labels.instance }} memory usage is {{ \$value }}%"
- alert: RedisSlowlog
expr: increase(redis_slowlog_length[5m]) > 0
for: 1m
labels:
severity: warning
annotations:
summary: "Redis slow queries detected"
description: "Redis instance {{ \$labels.instance }} has {{ \$value }} slow queries"
EOF
chown -R prometheus:prometheus "$(dirname "$PROMETHEUS_CONFIG")" 2>/dev/null || true
echo "[8/8] Verifying installation..."
if systemctl is-active --quiet redis_exporter; then
log_info "redis_exporter service is running"
else
log_error "redis_exporter service failed to start"
systemctl status redis_exporter
exit 1
fi
# Test metrics endpoint
if curl -s http://localhost:9121/metrics >/dev/null; then
log_info "Redis metrics endpoint is accessible"
else
log_warn "Redis metrics endpoint test failed - check Redis connectivity"
fi
log_info "Redis cluster monitoring setup completed successfully!"
echo ""
echo "Next steps:"
echo "1. Restart Prometheus to load new configuration: systemctl restart prometheus"
echo "2. Import Redis dashboards in Grafana"
echo "3. Configure Alertmanager for notifications"
echo ""
echo "Endpoints:"
echo "- Redis Exporter: http://localhost:9121/metrics"
echo "- Prometheus config: $PROMETHEUS_CONFIG"
Review the script before running. Execute with: bash install.sh