2. Redis热点Key发现与监控:使用Redis-cli --hotkeys、Redis Monitor命令、第三方监控工具(如Grafana+Prometheus)
热点Key是Redis生产环境中性能劣化的首要诱因。一个每秒访问量超过10万次的Key,足以打满单核CPU、耗尽网卡带宽,甚至引发缓存雪崩。本章聚焦热点Key的主动发现与持续监控,覆盖Redis原生工具与开源监控栈的完整实践路径。
2.1 热点Key的判定标准与影响
并非所有高频访问的Key都是热点。下表给出企业级判定参考阈值:
| 指标维度 | 正常范围 | 关注阈值 | 告警阈值 |
|---|---|---|---|
| QPS(单Key) | < 1,000 | 1,000 ~ 5,000 | > 5,000 |
| 带宽占用(单Key) | < 10 MB/s | 10 ~ 50 MB/s | > 50 MB/s |
| CPU使用率(单Key贡献) | < 10% | 10% ~ 30% | > 30% |
| 响应时间P99 | < 1 ms | 1 ~ 5 ms | > 5 ms |
注意:热点Key的QPS阈值需根据实例规格动态调整。例如,8核32GB的Redis实例,单Key QPS超过2万即可能触发CPU软中断瓶颈;而64核大实例可承受更高并发。
2.2 使用Redis-cli --hotkeys 离线扫描
Redis 4.0+ 内置了热点Key扫描功能,通过 redis-cli --hotkeys 命令实现。该命令基于 SCAN 遍历所有Key,结合 OBJECT freq 获取访问频率(需开启 maxmemory-policy 且使用LFU淘汰策略)。
执行命令:
# 连接本地Redis实例
redis-cli --hotkeys
# 指定密码和端口
redis-cli -h 192.168.1.100 -p 6379 -a 'your_password' --hotkeys
输出示例:
# Scanning the entire keyspace to find hot keys as well as
# average sizes per key type. You can use -i 0.1 to sleep 0.1 sec
# per 100 SCAN commands (not usually needed).
[00.00%] Key: user:profile:1001 (type: hash) (freq: 152) (size: 2.1 KB)
[00.00%] Key: product:detail:888 (type: string) (freq: 98) (size: 4.5 KB)
[00.00%] Key: session:token:abc123 (type: string) (freq: 67) (size: 0.3 KB)
-------- summary -------
Sampled 1000000 keys in the keyspace!
Total key lengths: 45.2 MB
Top 1 hot keys:
- Key: user:profile:1001 (freq: 152)
- Key: product:detail:888 (freq: 98)
- Key: session:token:abc123 (freq: 67)
最佳实践:在生产环境使用
--hotkeys 时,务必添加 -i 0.1 参数(每100次SCAN休眠0.1秒),避免扫描期间CPU飙高影响在线业务。建议在业务低峰期(如凌晨2:00-4:00)执行。
局限性:
- 仅支持LFU淘汰策略的实例(
maxmemory-policy allkeys-lfu或volatile-lfu)。 - 扫描全量Key,大Key场景下耗时较长(百万级Key需数分钟)。
- 无法实时监控,只能获取扫描时刻的快照。
2.3 使用Redis Monitor命令实时捕获
MONITOR 命令可以实时打印Redis服务器处理的所有命令,是定位热点Key的“最后一公里”手段。但因其性能开销极大,严禁在生产实例上直接长时间运行。
安全使用方式:
- 在从节点(Replica)上执行,避免影响主节点。
- 限制输出时间:
timeout 10 redis-cli -p 6379 monitor > /tmp/monitor.log。 - 使用管道分析工具快速聚合:
# 捕获10秒MONITOR日志
timeout 10 redis-cli -p 6379 monitor > /tmp/monitor_10s.log
# 使用awk统计Key访问频率(假设命令格式为:timestamp [0 源IP] "GET key_name")
awk -F'"' '{print $2}' /tmp/monitor_10s.log | sort | uniq -c | sort -rn | head -20
输出示例:
234 GET user:profile:1001
187 GET product:detail:888
156 GET session:token:abc123
89 SET cache:config:version
78 GET product:detail:999
风险提示:MONITOR命令会使Redis吞吐量下降50%以上(官方文档明确警告)。建议仅在应急排障时使用,且单次捕获不超过30秒。长期监控请使用下文介绍的第三方工具。
2.4 第三方监控工具:Grafana + Prometheus + redis_exporter
企业级热点Key监控必须实现实时采集、历史回溯、告警联动。Prometheus生态的 redis_exporter 是目前最成熟的方案。
架构组件:
部署步骤:
- 启动redis_exporter(推荐Docker方式):
docker run -d --name redis_exporter -p 9121:9121 \
-e REDIS_ADDR=redis://192.168.1.100:6379 \
-e REDIS_PASSWORD=your_password \
oliver006/redis_exporter:latest
- 配置Prometheus抓取目标(prometheus.yml):
scrape_configs:
- job_name: 'redis_exporter'
static_configs:
- targets: ['192.168.1.100:9121']
scrape_interval: 15s
scrape_timeout: 10s
- Grafana导入仪表盘:使用ID
763(官方Redis Dashboard)或自定义热点Key面板。
关键监控指标:
| 指标名称 | 类型 | 含义 | 热点Key关联 |
|---|---|---|---|
redis_key_size |
Gauge | Key的内存占用(字节) | 大Key可能伴随热点 |
redis_commands_duration_seconds_total |
Counter | 命令执行总耗时 | 高耗时命令指向热点 |
redis_connected_clients |
Gauge | 当前客户端连接数 | 突增可能由热点引起 |
redis_cpu_sys_seconds_total |
Counter | 内核态CPU累计时间 | 热点Key导致sys飙升 |
redis_slowlog_microseconds |
Histogram | 慢查询日志(微秒) | 慢查询常指向热点Key |
进阶技巧:在Grafana中创建“热点Key实时Top10”面板,使用PromQL:
topk(10, sum(rate(redis_commands_duration_seconds_total[1m])) by (cmd, key))。配合变量模板,可快速下钻到具体Key的访问趋势。
2.5 三种发现方式的对比与选型
| 发现方式 | 实时性 | 性能影响 | 适用场景 | 推荐频率 |
|---|---|---|---|---|
redis-cli --hotkeys |
离线快照 | 低(需加-i参数) | 定期巡检、大促前摸底 | 每日1次(低峰期) |
MONITOR 命令 |
实时 | 极高(吞吐下降50%+) | 应急排障、短期抓包 | 仅限从节点,单次<30s |
| Prometheus + redis_exporter | 准实时(15s粒度) | 低(INFO命令开销) | 7×24小时持续监控 | 持续运行 |
推荐组合策略:日常使用Prometheus + Grafana做持续监控和告警;每周执行一次
--hotkeys 扫描做全量校验;遇到突发性能抖动时,在从节点短暂开启MONITOR定位具体Key。三种方式互补,覆盖“长期趋势 + 定期快照 + 应急定位”全场景。
2.6 热点Key监控告警规则示例
在Prometheus中配置告警规则(alert_rules.yml):
groups:
- name: redis_hotkey_alerts
rules:
- alert: RedisHotKeyHighQPS
expr: |
sum(rate(redis_commands_duration_seconds_total[1m])) by (key)
> 5000
for: 2m
labels:
severity: critical
annotations:
summary: "热点Key QPS超过阈值"
description: "Key: {{ $labels.key }} 当前QPS: {{ $value }}"
- alert: RedisHotKeyHighLatency
expr: |
histogram_quantile(0.99, sum(rate(redis_slowlog_microseconds_bucket[5m])) by (le, key))
> 5000
for: 1m
labels:
severity: warning
annotations:
summary: "热点Key响应时间P99超过5ms"
description: "Key: {{ $labels.key }} P99延迟: {{ $value }}μs"
通过Alertmanager将告警推送至钉钉、企业或邮件,确保运维人员5分钟内响应。