简介:本资源是一份面向Linux运维工程师与监控系统实施人员的Prometheus监控Redis实战指南,聚焦于生产环境中Redis服务的可观测性建设。文档详细讲解了Prometheus 2.35.0与redis_exporter(v1.24.0)的集成部署、静态配置与服务发现两种目标管理方式、Alertmanager报警链路搭建,以及Redis关键参数(如bind、requirepass、maxmemory等)对监控连通性的影响和调优建议。资源为单个4.37MB的Word文档(.docx格式),内容结构完整,涵盖Redis单机部署、redis_exporter二进制安装与systemd托管、Prometheus配置片段、典型指标解读及报警规则设计思路,实操性强且步骤可复现。目前已有1306人学习下载,适合具备基础Linux和Redis使用经验的中高级运维人员快速掌握Prometheus监控Redis的端到端落地方法。
1. Prometheus 监控 Redis 不是“加个 exporter 就完事”:密码、端口、指标采集链路全断点排查
很多运维同学在第一次用 Prometheus 监控 Redis 时,会卡在同一个地方:redis_exporter启动了,/metrics页面能打开,但 Prometheus 的 Targets 页面里状态始终是DOWN,日志里反复出现context deadline exceeded或dial tcp: i/o timeout。这不是配置写错了,而是整个采集链路中至少一个环节被默认行为“静默拦截”——比如 Redis 开启了protected-mode yes却没放开bind,或者redis_exporter用-redis.password参数传参时漏了双横线,又或者 Docker 部署的 Redis 因网络命名空间隔离导致127.0.0.1:6379在 exporter 进程内根本不可达。本文基于真实生产环境(CentOS 7 + Redis 6.x + redis_exporter v1.24.0 + Prometheus 2.35.0)完整复现从单机 Redis 部署、exporter 接入、Prometheus 抓取、Alertmanager 告警到 Grafana 可视化的全路径,重点标注所有非文档默认值但必须显式设置的关键参数,并给出每个环节的验证命令和失败日志特征。适合已掌握 Linux 基础服务管理、正要落地 Redis 可观测性的中级运维与 SRE 工程师。
2. Redis 服务层配置:为什么bind 0.0.0.0和requirepass必须成对出现
Prometheus 本身不直连 Redis,而是通过redis_exporter作为中间代理拉取指标。因此,Redis 的网络可达性与认证配置,直接决定 exporter 能否建立初始连接。很多团队在测试阶段用redis-cli -h 127.0.0.1 -p 6379 ping成功,就误以为 Redis 配置无问题,却忽略了 exporter 进程运行时的网络上下文。
2.1 关键配置项解析与实操验证
Redis 默认开启protected-mode yes,该模式下仅允许本地回环地址(127.0.0.1)连接,任何来自其他 IP 的请求(包括本机上另一个进程如redis_exporter通过192.168.10.89:6379发起的连接)都会被拒绝。必须同时满足两个条件才能解除限制:
bind指令显式绑定监听地址(不能留空或注释)protected-mode显式设为no,或确保bind包含实际网卡 IP
注意:
bind 127.0.0.1仍会阻止redis_exporter通过主机 IP 连接;bind 0.0.0.0是最简方案,但需配合防火墙策略(如firewall-cmd --permanent --add-port=6379/tcp)控制外部访问。
以下为/etc/redis.conf中必须确认的最小化安全配置段(已去除无关注释):
bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile /var/log/redis/redis.log databases 16 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /var/lib/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 requirepass 123456 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes maxclients 4064 maxmemory 128mb2.2 验证 Redis 网络与认证连通性
在redis_exporter所在机器(即192.168.10.89)上执行以下三步验证,缺一不可:
步骤 1:确认端口监听范围
# 查看 redis-server 进程绑定的地址 ss -tlnp | grep ':6379' # 正确输出应包含 *:6379(表示 0.0.0.0:6379),而非 127.0.0.1:6379 # 示例: # LISTEN 0 511 *:6379 *:* users:(("redis-server",pid=2915,fd=6))步骤 2:使用redis-cli模拟 exporter 连接行为
# 使用 redis_exporter 将使用的相同凭据和地址进行连接测试 redis-cli -h 192.168.10.89 -p 6379 -a "123456" ping # 成功返回 "PONG" 表示网络+认证均通 # 若返回 "(error) NOAUTH Authentication required",说明密码错误或 requirepass 未生效 # 若返回 "Could not connect to Redis at 192.168.10.89:6379: Connection refused",说明 redis 未监听该 IP 或端口被防火墙拦截步骤 3:检查 Redis 日志中的连接拒绝记录
# 实时跟踪 redis 日志,观察是否有 client 连接被拒 tail -f /var/log/redis/redis.log | grep -i "refused\|denied\|auth" # 若出现 "Client closed connection before auth" 或 "Connection with client lost",大概率是 protected-mode 或 bind 配置问题提示:Docker 部署的 Redis(如
docker run -p 6379:6379 redis)默认只绑定容器内127.0.0.1,即使宿主机netstat显示0.0.0.0:6379,其内部仍是127.0.0.1。此时redis_exporter必须用--redis.addr redis://host.docker.internal:6379(Mac/Win)或--redis.addr redis://172.17.0.1:6379(Linux 宿主机网关)连接,且需在redis.conf中显式配置bind 127.0.0.1 172.17.0.1并重启容器。
3. redis_exporter 部署与 systemd 服务化:参数传递、密码处理与端口冲突规避
redis_exporter是轻量级 Go 二进制,无需安装依赖,但其启动参数格式、密码传递方式及 systemd 服务定义极易出错。常见问题包括:-redis.password被误写为--redis.password(v1.24.0 仅支持单横线)、--redis.addr地址中遗漏redis://协议头、systemd 服务未设置RestartSec导致频繁崩溃后无法自愈。
3.1 二进制部署与启动参数详解
以redis_exporter-v1.24.0.linux-amd64.tar.gz为例,解压后目录结构如下:
/data/redis_exporter/ ├── LICENSE ├── README.md └── redis_exporter ← 主二进制文件redis_exporter支持两种 Redis 连接方式,对应不同参数组合:
| 场景 | 启动命令 | 说明 |
|---|---|---|
| Redis 无密码 | /data/redis_exporter/redis_exporter --redis.addr 192.168.10.89:6379 | --redis.addr值可省略redis://,但必须是IP:PORT格式 |
| Redis 有密码 | /data/redis_exporter/redis_exporter --redis.addr 192.168.10.89:6379 -redis.password 123456 | 关键:-redis.password是单横线,且必须紧跟在--redis.addr之后,顺序不可颠倒 |
| Redis 启用 TLS | /data/redis_exporter/redis_exporter --redis.addr redis://192.168.10.89:6380 --redis.tls-ca-cert-file /path/to/ca.crt --redis.tls-cert-file /path/to/client.crt --redis.tls-key-file /path/to/client.key | 生产环境建议启用 TLS,避免密码明文传输 |
注意:
redis_exporter默认监听:9121,若该端口被占用(如其他 exporter 或旧进程),需显式指定--web.listen-address=:9122。可通过lsof -i :9121快速检查端口占用。
3.2 systemd 服务文件编写与调试技巧
将redis_exporter交由 systemd 管理是生产环境强制要求。以下为经过验证的/usr/lib/systemd/system/redis_exporter.service文件内容:
[Unit] Description=Redis Exporter for Prometheus Documentation=https://github.com/oliver006/redis_exporter Wants=network-online.target After=network-online.target [Service] Type=simple User=root Group=root EnvironmentFile=-/etc/sysconfig/redis_exporter ExecStart=/data/redis_exporter/redis_exporter \ --redis.addr redis://192.168.10.89:6379 \ -redis.password 123456 \ --web.listen-address=:9121 \ --web.telemetry-path=/metrics \ --redis.set-client-name=true \ --redis.incl-system-metrics=true \ --redis.max-connections=10 \ --log.format=logger:stderr?json=true Restart=on-failure RestartSec=10 TimeoutStartSec=30 LimitNOFILE=65536 LimitNPROC=65536 [Install] WantedBy=multi-user.target关键参数说明:
EnvironmentFile=-/etc/sysconfig/redis_exporter:支持外部环境变量注入(如密码),-表示文件不存在时不报错--redis.set-client-name=true:在 RedisCLIENT LIST中显示 exporter 连接名为redis_exporter,便于审计--redis.incl-system-metrics=true:启用redis_system_*类系统指标(如 CPU、内存),需 Redis 6.2+ 且 exporter v1.22+--redis.max-connections=10:限制 exporter 到 Redis 的最大并发连接数,防止单点打爆 Redis--log.format=logger:stderr?json=true:输出 JSON 格式日志,方便 ELK 收集
启动与日志调试命令:
# 重载 systemd 配置 systemctl daemon-reload # 启动服务 systemctl start redis_exporter # 检查服务状态(重点关注 Active: active (running)) systemctl status redis_exporter # 实时查看 exporter 日志(过滤 ERROR 和 WARN) journalctl -u redis_exporter -f -o cat | grep -E "(ERROR|WARN|failed|timeout)" # 验证 metrics 端点是否可访问(应返回大量 redis_* 指标) curl -s http://192.168.10.89:9121/metrics | head -20 # 输出应包含类似: # # HELP redis_connected_clients Client connections # # TYPE redis_connected_clients gauge # redis_connected_clients 1提示:若
curl返回空或connection refused,先执行ss -tlnp | grep ':9121'确认 exporter 进程是否真正在监听;若进程存在但无法访问,检查systemctl show redis_exporter | grep ExecStart是否因参数错误导致启动失败(systemd 会静默忽略错误参数)。
4. Prometheus 静态配置与告警规则实战:redis_up、内存水位、连接数阈值的精确表达
Prometheus 通过scrape_configs定义抓取目标,而 Redis 监控的核心在于:redis_exporter提供的指标必须被正确识别、聚合,并转化为业务可理解的告警逻辑。本节聚焦prometheus.yml中redis_monitorjob 的配置细节,以及redis.yml告警规则中三个高频场景的 PromQL 写法与陷阱。
4.1 scrape_configs 配置要点与 Target 状态诊断
prometheus.yml中 Redis 监控 job 的标准配置如下:
scrape_configs: - job_name: "redis_monitor" static_configs: - targets: ["192.168.10.89:9121"] metrics_path: "/metrics" scheme: "http" # 可选:添加标签用于多实例区分 labels: instance: "redis-node3" env: "prod" # 可选:调整抓取超时(默认10s,高延迟网络建议调大) scrape_timeout: 15s # 可选:设置抓取间隔(默认global.scrape_interval,此处覆盖为30s) scrape_interval: 30sTarget 状态诊断四步法:
- 访问
http://192.168.10.92:9090/targets,找到redis_monitorjob 下的 target - 观察 State 列:
UP表示成功;DOWN需点击右侧Logs查看具体错误(如server returned HTTP status 503 Service Unavailable表示 exporter 进程崩溃) - 点击
Endpoint链接,确认能否直接访问http://192.168.10.89:9121/metrics(排除网络层问题) - 在 Prometheus 表达式浏览器中输入
redis_up{instance="192.168.10.89:9121"},若返回1表示 exporter 自身健康,0表示 exporter 无法连接 Redis
4.2 redis.yml 告警规则深度解析与参数调优
/data/prometheus/rules/redis.yml中定义的四条规则,覆盖了 Redis 最关键的稳定性维度。每条规则的expr必须精准匹配业务 SLA,for时长需平衡灵敏度与误报率。
规则 1:Redis 服务宕机检测(redisServiceDown)
- alert: redisServiceDown expr: redis_up == 0 for: 1m labels: severity: critical annotations: summary: "Redis 服务不可达" description: "实例 {{ $labels.instance }} 的 Redis 服务已离线超过 1 分钟,请立即检查 redis_exporter 连接状态及 Redis 进程"- 原理:
redis_up是 exporter 自带的健康探针指标,值为1表示 exporter 成功连接并获取 Redis INFO,0表示连接失败(网络不通、密码错误、Redis 进程挂掉) - 调优建议:
for: 1m适用于核心 Redis;若为缓存集群,可缩短至30s;若网络抖动频繁,延长至2m避免毛刺告警
规则 2:内存使用率超阈值(RedisOutOfMemory)
- alert: RedisOutOfMemory expr: (redis_memory_used_bytes / redis_memory_max_bytes) * 100 > 60 for: 2m labels: severity: warning annotations: summary: "Redis 内存使用率过高" description: "实例 {{ $labels.instance }} 的 Redis 内存使用率达 {{ $value | printf \"%.2f\" }}%,超过 60% 阈值。当前已用 {{ $value | printf \"%.0f\" }} MB,总限制 {{ $labels.redis_memory_max_bytes | printf \"%.0f\" }} MB"- 原理:
redis_memory_used_bytes是 Redis 实际使用的内存字节数,redis_memory_max_bytes是maxmemory配置值(单位字节)。二者相除得使用率。 - 陷阱:若 Redis 未配置
maxmemory(即redis_memory_max_bytes为 0),此表达式会因除零返回NaN,导致告警永不触发。必须确保maxmemory在redis.conf中显式设置(如maxmemory 128mb)
规则 3:连接数突增(RedisTooManyConnetions)
- alert: RedisTooManyConnetions expr: redis_connected_clients > 2000 for: 1m labels: severity: warning annotations: summary: "Redis 当前连接数过高" description: "实例 {{ $labels.instance }} 的 Redis 当前连接数为 {{ $value }},超过 2000 阈值。请检查客户端连接泄漏或突发流量"- 原理:
redis_connected_clients是 Redis INFO 中的实时连接数,无聚合函数,直接比较即可 - 调优建议:阈值
2000需根据maxclients配置按比例设定(如maxclients 4064,则阈值可设为3000),避免过早触发
规则 4:拒绝连接数异常(RedisRejectConnetions)
- alert: RedisRejectConnetions expr: increase(redis_rejected_connections_total[1m]) > 0 for: 1m labels: severity: warning annotations: summary: "Redis 1 分钟内发生连接拒绝" description: "实例 {{ $labels.instance }} 的 Redis 在过去 1 分钟内拒绝了 {{ $value }} 个连接请求,可能因 maxclients 达限或资源不足"- 原理:
redis_rejected_connections_total是累计计数器,increase()函数计算 1 分钟内的增量。原文档中increase(...)<0是笔误,应为>0(拒绝数不可能为负) - 关键点:
increase()的时间窗口[1m]必须与for: 1m对齐,否则会出现“刚触发就恢复”的瞬时告警
4.3 告警规则语法校验与热加载
# 检查 prometheus.yml 语法(必须在 prometheus 根目录执行) /data/prometheus/promtool check config /data/prometheus/prometheus.yml # 检查 redis.yml 规则语法 /data/prometheus/promtool check rules /data/prometheus/rules/redis.yml # 热加载新规则(无需重启 Prometheus) curl -X POST http://192.168.10.92:9090/-/reload # 返回 200 OK 表示成功;若返回 404,需在 prometheus.yml 中开启 --web.enable-admin-api5. Alertmanager 邮件模板定制与 Grafana Redis 仪表盘导入:从告警到可视化的最后一公里
Alertmanager 的默认邮件通知信息简陋,缺乏时间戳、恢复详情和业务上下文;Grafana 若未导入适配的 Redis 仪表盘,则 Prometheus 中的原始指标难以转化为运维可读的图表。本节提供 QQ 邮箱模板的完整实现与 Grafana 官方推荐仪表盘的快速导入方法。
5.1 Alertmanager 自定义 HTML 邮件模板详解
Alertmanager v0.24.0 支持 Go template 语法,通过templates和email_configs.html字段注入自定义模板。以下为/data/alertmanager/templates/email.template.tmpl的生产可用版本,已修复原稿中{{ range.Alerts }}缺少空格的语法错误,并增强时间格式与字段完整性:
{{ define "email.template.tmpl" }} {{- if gt (len .Alerts.Firing) 0 -}} <h3>🚨 告警触发({{ len .Alerts.Firing }} 条)</h3> {{- range .Alerts.Firing }} <p><strong>告警名称:</strong>{{ .Labels.alertname }}</p> <p><strong>实例:</strong>{{ .Labels.instance }}({{ .Labels.env | default "unknown" }})</p> <p><strong>级别:</strong>{{ .Labels.severity | default "unknown" }}</p> <p><strong>摘要:</strong>{{ .Annotations.summary }}</p> <p><strong>详情:</strong>{{ .Annotations.description }}</p> <p><strong>开始时间:</strong>{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}(UTC+8)</p> <p><strong>告警链接:</strong><a href="http://192.168.10.92:9090/alerts?search={{ .Labels.alertname }}">Prometheus Alerts</a></p> <hr> {{ end }} {{ end -}} {{- if gt (len .Alerts.Resolved) 0 -}} <h3>✅ 告警恢复({{ len .Alerts.Resolved }} 条)</h3> {{- range .Alerts.Resolved }} <p><strong>告警名称:</strong>{{ .Labels.alertname }}</p> <p><strong>实例:</strong>{{ .Labels.instance }}({{ .Labels.env | default "unknown" }})</p> <p><strong>级别:</strong>{{ .Labels.severity | default "unknown" }}</p> <p><strong>摘要:</strong>{{ .Annotations.summary }}</p> <p><strong>详情:</strong>{{ .Annotations.description }}</p> <p><strong>开始时间:</strong>{{ (.StartsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}(UTC+8)</p> <p><strong>恢复时间:</strong>{{ (.EndsAt.Add 28800e9).Format "2006-01-02 15:04:05" }}(UTC+8)</p> <p><strong>告警链接:</strong><a href="http://192.168.10.92:9090/alerts?search={{ .Labels.alertname }}">Prometheus Alerts</a></p> <hr> {{ end }} {{ end -}} {{ end }}配套alertmanager.yml修改:
global: resolve_timeout: 1m smtp_smarthost: 'smtp.qq.com:587' # 改用 587 端口(更稳定) smtp_from: '1036981484@qq.com' smtp_auth_username: '1036981484@qq.com' smtp_auth_password: 'fwbxnmbfnrpvbedi' # QQ 邮箱 SMTP 授权码,非登录密码 smtp_require_tls: true # 必须为 true,587 端口需 TLS templates: - '/data/alertmanager/templates/*.tmpl' route: group_by: ['alertname', 'env'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'email' receivers: - name: 'email' email_configs: - to: '1441107787@qq.com' send_resolved: true html: '{{ template "email.template.tmpl" . }}'注意:QQ 邮箱 SMTP 必须使用授权码(在 QQ 邮箱网页版 → 设置 → 账户 → “POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务” → 生成授权码),且
smtp_smarthost端口推荐587(25端口常被云厂商屏蔽)。
5.2 Grafana Redis 仪表盘导入与数据源配置
Grafana v8.4.5 默认数据源类型为 Prometheus,导入仪表盘前需先完成数据源配置:
步骤 1:添加 Prometheus 数据源
- 访问
http://192.168.10.92:3000,使用admin/admin登录 - 左侧菜单 → ⚙️ Configuration → Data Sources → Add data source
- 选择
Prometheus - Name:
Prometheus-Redis - URL:
http://192.168.10.92:9090(Prometheus 服务地址) - Scrape interval:
30s(与scrape_configs中一致) - Save & test → 应显示
Data source is working
步骤 2:导入 Redis 专用仪表盘
官方推荐仪表盘 ID763(Redis Dashboard by Percona),导入步骤:
- 左侧菜单 → ➕ Create → Import
- 输入
763→ Load - 选择数据源
Prometheus-Redis→ Import
导入后,仪表盘自动展示以下核心视图:
- Overview:Redis 实例状态、内存使用率、连接数、命中率(
redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)) - Commands:各命令执行耗时 P95、QPS(
rate(redis_commands_total[5m])) - Memory:内存碎片率(
redis_mem_fragmentation_ratio)、内存分配(redis_memory_used_rss_bytes) - Persistence:RDB/AOF 持久化状态、最后保存时间
提示:若仪表盘中部分图表为空,检查 Prometheus 中对应指标是否存在(如
redis_keyspace_hits_total),若无数据,说明redis_exporter未正确采集(可curl http://192.168.10.89:9121/metrics | grep keyspace验证)。
6. 故障排查速查表:Targets DOWN、告警不触发、邮件收不到的 7 个关键检查点
当监控链路某处中断,按以下顺序逐项验证,可 90% 定位问题根源。每个检查点均附带验证命令与典型错误输出。
| 序号 | 检查点 | 验证命令 | 正确输出特征 | 常见错误输出与对策 |
|---|---|---|---|---|
| 1 | Redis 网络监听 | ss -tlnp | grep ':6379' | *:6379或192.168.10.89:6379 | 127.0.0.1:6379→ 修改redis.conf中bind并重启 Redis |
| 2 | Redis 认证连通 | redis-cli -h 192.168.10.89 -p 6379 -a "123456" ping | PONG | NOAUTH→ 检查requirepass值;Connection refused→ 检查 Redis 进程与防火墙 |
| 3 | redis_exporter 进程 | ps aux | grep redis_exporter | 显示完整启动命令 | 无输出 →systemctl start redis_exporter;若有但端口未监听 →journalctl -u redis_exporter -n 50 |
| 4 | exporter metrics 端点 | curl -s http://192.168.10.89:9121/metrics | head -5 | 多行# HELP redis_* | curl: (7) Failed to connect→ 检查 exporter 是否监听9121;Empty reply→journalctl查 exporter 连接 Redis 错误 |
| 5 | Prometheus Target 状态 | curl -s http://192.168.10.92:9090/api/v1/targets | jq '.data.activeTargets[] | select(.discoveredLabels.instance=="192.168.10.89:9121")' | "health": "up" | "health": "down"→ 查lastError字段,如server returned HTTP status 503表示 exporter 崩溃 |
| 6 | 告警规则语法 | /data/prometheus/promtool check rules /data/prometheus/rules/redis.yml | SUCCESS | ERROR行 → 根据提示修正 PromQL(如redis_memory_max_bytes为 0 时除零) |
| 7 | Alertmanager 邮件发送 | echo "test" | mail -s "alertmanager-test" 1441107787@qq.com | QQ 邮箱收到测试邮件 | 无邮件 → 检查alertmanager.yml中smtp_auth_password是否为授权码;journalctl -u alertmanager -n 20查 SMTP 连接错误 |
终极技巧:当所有检查点均正常但告警仍不触发,进入 Prometheus 表达式浏览器,手动执行告警
expr(如redis_up == 0),观察返回值是否为1;若为0,说明当前无告警条件满足,需人为制造故障(如systemctl stop redis)再验证。
本文还有配套的精品资源,点击获取