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 的路由与接收器是否配置完整。