Redis 内存和连接异常怎么排查?用 redis_exporter 搭一套可远程抓取的监控链路

Redis 内存和连接异常怎么排查?用 redis_exporter 搭一套可远程抓取的监控链路

前言

Redis 出问题时,最让人难受的往往不是进程彻底停了,而是业务还在运行,缓存命中率却开始下降,连接数慢慢逼近上限,内存持续上涨,直到接口响应变慢才有人发现。临时登录服务器查看状态,能回答"现在怎么样",却很难追溯异常从什么时候开始、此前有哪些变化。我更愿意让监控从日常运行时就开始:先把 Redis 的统计信息转成连续指标,再交给 Prometheus 抓取、保存和查询,等到需要时再接告警规则,而不是故障发生后才拼凑现场。

这套实践使用 Linux 上的 redis_exporter v0.21.2 和 Prometheus 3.5.0。我会先验证 Redis 连接与 9121/metrics,再配置 systemd、Prometheus 抓取目标和 Redis 告警规则;如果 Prometheus 位于另一处网络,再用 cpolar 将 Exporter 的 HTTP 指标入口映射出去,先测试随机公网地址,最后改成固定二级子域名 redis。每一步都按"能启动、能采集、能抓取、能判断告警、能跨网络访问"的顺序展开,尤其分清 Exporter 进程在运行与 Redis 指标可用、Prometheus 发现目标与告警真正送达之间的区别。这样出现异常时,可以知道应该从哪一层查起。对经常管理缓存服务的人来说,先确定是 Redis 本身、采集进程、抓取配置还是远端网络出了问题,比看到一张漂亮的监控页面更有用。

一、先弄清 Redis 监控各组件的职责

Redis 常被用于缓存、热点数据、限流和分布式锁。遇到内存、连接、命令执行或复制状态异常时,我希望看到的不只是一张当前状态截图,而是一段时间里的连续变化。redis_exporter 正是 Redis 与 Prometheus 之间的指标适配器:它读取 Redis 的运行统计,再通过 HTTP /metrics 输出 Prometheus 可以抓取的数据。

关注的指标可以按问题归类:内存占用和碎片率、客户端连接与拒绝连接、Key 与过期情况、GET/SET/DEL 等命令统计、RDB/AOF 状态、网络流量,以及有相应部署形态时的主从或集群状态。Grafana 可在后续接入可视化;Prometheus 的规则可用于识别异常。指标采集、Prometheus 规则文件与跨网络抓取是这里的核心;Grafana 看板和 Alertmanager 通知链路需要另外配置。

一个容易混淆的地方是:Exporter 的进程存活、/metrics 能访问,以及其中确实存在 Redis 的有效数据,是三个不同层次。后续验证需要依次看。

二、部署 redis_exporter:先拿到指标,再考虑服务托管

如果 Redis 尚未安装,可以先参考 Redis 完整安装部署教程。本次以已经运行的 Redis 实例为前提,Exporter 放在自选的 /app/redis_exporter 目录,下载版本为 v0.21.2。

1. 下载并解压

shell 复制代码
wget https://github.com/oliver006/redis_exporter/releases/download/v0.21.2/redis_exporter-v0.21.2.linux-amd64.tar.gz
shell 复制代码
tar -zxvf redis_exporter-v0.21.2.linux-amd64.tar.gz

2. 按 Redis 的连接条件选择启动方式

Redis 设置了密码时,使用带密码的启动示例:

shell 复制代码
nohup ./redis_exporter -redis.addr 你的redis的ip:6379  -redis.password 密码  -web.listen-address :9121 &

没有密码的实例使用:

shell 复制代码
nohup ./redis_exporter -redis.addr 你的redis的ip:6379  -web.listen-address :9121 &

如果 Redis 和 Exporter 在同一台服务器,主机地址还可以写成 localhost:6379:

shell 复制代码
nohup ./redis_exporter -redis.addr localhost:6379  -web.listen-address :9121 &

这三条是不同场景下的选择,不需要连续启动三个 Exporter。示例中的 Redis 地址、密码应与实际实例对应;同机地址也以 Redis 确实监听的位置为准。

3. 验证进程和指标接口

先检查进程:

shell 复制代码
ps -ef|grep redis_exporter

再在浏览器打开指标地址:

bash 复制代码
http://服务器ip:9121/metrics

这里的 9121 是 Exporter 的 HTTP 端口,6379 是被监控 Redis 的连接端口。能够打开 /metrics 是第一步,还应确认实际 Redis 指标存在、采集未报错,不能只凭 HTTP 页面出现就认定数据库连接无误。

4. 需要常驻运行时再配置 systemd

创建服务文件:

shell 复制代码
vim /usr/lib/systemd/system/redis_exporter.service

服务内容如下:

shell 复制代码
[Unit]
Description=Redis Exporter for Prometheus
Documentation=https://github.com/oliver006/redis_exporter
After=network.target

[Service]
Type=simple
User=redis-exporter
Group=redis-exporter
ExecStart=/app/redis_exporter/redis_exporter \
    --redis.addr=redis://localhost:6379 \
    --web.listen-address=:9121 \
    --web.telemetry-path=/metrics
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=redis_exporter

[Install]
WantedBy=multi-user.target

服务使用 User=redis-exporter 和 Group=redis-exporter,二进制路径写成 /app/redis_exporter/redis_exporter,并通过 redis://localhost:6379 连接数据库。这里没有创建 Linux 用户或组的命令,也没有展示将压缩包中的二进制放入 /app/redis_exporter 的过程;真正启用前,需要确认这些对象和路径存在、具备运行权限。如果实际 Redis 带密码,systemd 连接配置也要与前面手动启动的认证条件一致。

服务文件下面给出的命令是:

shell 复制代码
systemctl enable prometheus 
systemctl start prometheus
systemctl status prometheus

它们操作的是 prometheus,而不是 redis_exporter。这组命令继续保留供对照;配置 Exporter 服务时应先核对实际服务名及进程状态,避免出现"写好了 Exporter 文件,却只启动了 Prometheus"的情况。

三、安装 Prometheus,保存并抓取时序数据

Exporter 负责暴露指标,Prometheus 才负责周期性抓取与保存。先准备安装目录:

shell 复制代码
mkdir /app
shell 复制代码
cd /app

到 Prometheus 下载页面 选择 Linux 安装包,示例使用 prometheus-3.5.0.linux-amd64.tar.gz。图形终端使用 MobaXterm Personal,将安装包上传到 /app。

检查上传结果:

shell 复制代码
ls

解压:

shell 复制代码
tar -xzvf prometheus-3.5.0.linux-amd64.tar.gz

重命名解压目录;删除压缩包是示例中的可选清理动作:

shell 复制代码
mv prometheus-3.5.0.linux-amd64 prometheus
rm -rf prometheus-3.5.0.linux-amd64.tar.gz

进入目录查看版本:

shell 复制代码
cd /app/prometheus
./prometheus --version

1. 创建数据目录和服务文件

时序数据目录:

shell 复制代码
mkdir -p /var/lib/prometheus

创建 systemd 服务文件:

shell 复制代码
vim /usr/lib/systemd/system/prometheus.service

写入:

shell 复制代码
[Unit]
Description=Prometheus
Documentation=https://prometheus.io/
After=network.target

[Service]
# Type设置为notify时,服务会不断重启
Type=simple
User=root
# --storage.tsdb.path是可选项,默认数据目录在运行目录的./dada目录中
ExecStart=/app/prometheus/prometheus --config.file=/app/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus --web.enable-lifecycle
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure

[Install]
WantedBy=multi-user.target

配置将可执行文件指向 /app/prometheus/prometheus,配置文件指向 /app/prometheus/prometheus.yml,数据目录指向 /var/lib/prometheus。文件里的注释和命令均按示例保留;User=root 是进程运行身份,不代表监控 Redis 时必须使用数据库超级权限。

启动并查看服务:

shell 复制代码
systemctl enable prometheus 
systemctl start prometheus
systemctl status prometheus

接下来给出的访问示例为:

shell 复制代码
ip:9200

这一行写成了 ip:9200,但后面实际验证 Prometheus 时使用的是 IP:9090,而 cpolar 的 Web 管理端口同样是 9200。访问时应核对自己运行的服务和实际监听端口,避免打开了另一个管理页面却以为进入了 Prometheus。

四、把 redis_exporter 添加到 Prometheus 抓取列表

编辑正在使用的配置文件:

shell 复制代码
vi prometheus.yml

增加 Redis Exporter 目标:

shell 复制代码
      - targets: ["localhost:9121"]
        labels:
          app: "redis_exporter"

localhost:9121 只适合 Prometheus 与 Exporter 位于同一台机器的情况。这里展示的是 target 和标签片段,需要放进实际 scrape_configs 对应的 job 中;app: "redis_exporter" 是自定义标签,并不等于 Prometheus 的 job 标签名称。

重启 Prometheus:

shell 复制代码
systemctl restart prometheus

通过 IP:9090 进入页面:

查看目标状态,确认 redis_exporter 被检测到并且抓取正常。

这时形成的链路是 Redis 6379 → Exporter 9121 → Prometheus。若抓取状态正常但 Redis 指标为空,还要返回 Exporter 的 Redis 连接配置检查。

五、添加 Redis 告警规则:规则生效与通知送达分开看

已有的 Alertmanager 部署可参考 服务器监控告警系统教程。下面先增加 Redis 规则文件,包含 Exporter 不响应、内存使用率、连接数及主从链路状态这四类场景。

shell 复制代码
groups:
  - name: redis-alerts
    rules:
      # Redis 实例宕机(Exporter 无响应)
      - alert: RedisDown
        expr: up{job="redis"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Redis instance down"
          description: "Redis instance {{ $labels.instance }} is down for more than 1 minute."

      # Redis 内存使用率过高(>85%)
      - alert: RedisMemoryHigh
        expr: redis_memory_used_bytes{job="redis"} / redis_memory_max_bytes{job="redis"} > 0.85
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Redis memory usage high"
          description: "Redis instance {{ $labels.instance }} memory usage is above 85% (current value: {{ $value | humanizePercentage }})."

      # Redis 连接数接近上限(>90%)
      - alert: RedisTooManyConnections
        expr: redis_connected_clients{job="redis"} / redis_config_maxclients{job="redis"} > 0.9
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Redis too many connections"
          description: "Redis instance {{ $labels.instance }} has too many clients ({{ $value | humanizePercentage }} of max)."

      # Redis 主从复制延迟(仅适用于主从架构)
      - alert: RedisReplicationLag
        expr: redis_slave_info{master_link_status="down", job="redis"} == 1
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Redis replication broken"
          description: "Redis slave {{ $labels.instance }} lost connection to master."

规则包含 RedisDown、RedisMemoryHigh、RedisTooManyConnections、RedisReplicationLag。其中内存阈值为 0.85、连接数阈值为 0.9,复制规则仅适用于相关主从指标存在的场景。示例表达式都使用了 job="redis":必须与抓取任务实际生成的 job 标签核对,不能只凭前面配置了 app: "redis_exporter" 就认为一定匹配。

将规则保存为 7.yml 后,编辑 Prometheus 配置:

shell 复制代码
vi prometheus.yml

添加规则文件路径:

shell 复制代码
rule_files:
  -  "/app/prometheus/7.yml"

重启服务:

shell 复制代码
systemctl restart prometheus

通过 IP:9090 查看规则页面。

能够看到告警规则,说明规则已被加载;但"规则已加载""表达式命中"和"通知已由 Alertmanager 发出"是不同结果。这里没有展示 Prometheus 对接 Alertmanager 的路由、接收器或实际通知记录,所以不会直接认定通知链路已完成。

六、异地 Prometheus 需要抓取时,再给 Exporter 配公网入口

如果要监控另一处网络里的 Redis,远端 Prometheus 无法直接访问本地的 localhost:9121。这时可以让 cpolar 为 Exporter 提供 HTTP 入口:cpolar 只负责网络可达性,Exporter 负责生成指标,Prometheus 仍负责抓取与存储。 既不需要把 Redis 6379 作为本方案的公网端口,也不需要把 Prometheus 管理页作为抓取地址。

先安装 cpolar:

shell 复制代码
sudo curl https://get.cpolar.sh | sh

检查服务状态:

shell 复制代码
sudo systemctl status cpolar

通过 主机 IP:9200 进入 cpolar Web UI 并登录。

1. 创建随机 HTTP 隧道验证链路

进入 隧道管理 → 创建隧道,参数如下:

  • 隧道名称:redis_exporter;
  • 协议:http;
  • 本地地址:9121;
  • 域名类型:随机域名;
  • 地区:China Top。

在线隧道列表会显示生成的地址。

从其他网络打开它,确认能到达 Exporter。

对于监控,验证时还应查看公网地址对应的 /metrics,而不仅是 Exporter 首页。将指标接口开放到公网意味着外部网络也能访问其中的运行信息,应结合实际访问控制要求决定开放范围。

2. 远端 Prometheus 抓取随机地址

示例公网主机名为 a214e29.r2.cpolar.top,抓取片段如下:

shell 复制代码
      - targets: ["a214e29.r2.cpolar.top"]
        labels:
          app: "redis_exporter"

随后在 Prometheus 中查看抓取结果。

示例说明中还出现了"本地 9105 端口",但前面的启动命令和隧道都使用 9121。同时,这段公网 target 没写端口和 scheme;实际使用时必须与生成的 HTTP/HTTPS 地址及 Prometheus 配置对应,确认连接的是 Exporter /metrics,而不是仅凭示例字符串推断任何环境都能抓取。

七、固定子域名适合长期抓取

随机域名更适合先测试。Prometheus 要持续抓取时,可以预留固定二级子域名,减少目标地址变更带来的维护工作。

进入 预留 → 保留二级子域名 ,地区选择 china Top,名称使用 redis,填写备注后保留。

实际名称具有唯一性,以账号中保留成功的结果为准。回到 隧道管理 → 隧道列表 ,找到 redis_exporter 隧道并编辑:

  • 域名类型:二级子域名;
  • Sub Domain:填写成功预留的名称;
  • 地区:China Top。

点击更新。

在线隧道列表会显示固定形式的地址。

最后从外部继续验证指标页面。

固定地址稳定的是网络入口,不会替 Redis 修复性能问题,也不会替 Exporter 处理认证、替 Prometheus 修复抓取配置。完成固定域名切换后,还需要同步更新远端 Prometheus 的目标地址,并再次确认抓取状态。

总结

一套能用的 Redis 监控,关键不在于装了多少组件,而在于数据是否能从 Redis 正确进入 Exporter、持续被 Prometheus 抓到,再按照真实标签和阈值进入规则判断。内存、连接、命令和复制指标能够留下时间序列后,排查就不必只依赖故障发生时的一次登录和一次截图。

跨网络场景再由 cpolar 给 9121 提供公网入口,先随机测试,再固定地址。把采集、存储、规则和网络入口分开维护,比把"进程启动、网页可访问、告警已送达"混成一句部署成功更可靠;真正需要通知时,再核实 Alertmanager 的路由与接收器是否配置完整。

相关推荐
可涵不会debug1 小时前
第一次学 LangGraph:用一个快递案例搞懂 State、Node、Edge 和 compile
服务器·数据库·mysql
IvorySQL2 小时前
PostgreSQL 日报 |RLS 机密性绕过漏洞(9 月 27 日)
数据库·postgresql
夕除2 小时前
redis--RDB AOF
数据库·redis·缓存
数据工匠老o3 小时前
"能用应用层解决的不用存储过程",十年数据库经验总结
数据库·架构
AC赳赳老秦3 小时前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
老纪的技术唠嗑局3 小时前
异步索引特性解析:OceanBase 如何提升持续写入场景下的索引检索性能
数据库
老纪的技术唠嗑局3 小时前
Tibo 谈 Codex:harness 总比模型快一步
数据库·人工智能
猫咪宝妖3 小时前
信息安全工程师 第四级 结构化保护级
网络·数据库·安全
Andreapiki4 小时前
风险审计校招技术栈拆解:SQL、Python、Power BI在2026届JD中的真实权重
数据库·python·sql