4. 热点Key发现与监控:慢查询日志、monitor命令、客户端统计、Redis Exporter + Prometheus + Grafana监控方案
热点Key是Redis生产环境中导致性能雪崩、连接阻塞、CPU飙高的核心诱因。要实施削峰,首先必须精准发现热点Key。本章系统梳理四种主流发现与监控手段,从单机诊断到全链路可视化,构建分层监控体系。
4.1 热点Key发现手段对比
| 手段 | 原理 | 适用场景 | 性能影响 | 实时性 |
|---|---|---|---|---|
| 慢查询日志 | 记录执行时间超过阈值的命令 | 定位耗时命令、大Key操作 | 低(仅记录慢命令) | 事后分析 |
| MONITOR命令 | 实时输出所有命令 | 临时抓取高频Key、调试 | 极高(QPS下降50%+) | 实时 |
| 客户端统计 | 客户端SDK统计命令调用频次 | 生产环境长期采集 | 低(本地计数) | 近实时 |
| Redis Exporter + Prometheus + Grafana | Exporter采集指标,Prometheus存储,Grafana展示 | 全链路监控、告警、趋势分析 | 低(异步拉取) | 准实时(秒级) |
选型建议:生产环境禁止直接使用MONITOR命令;推荐客户端统计作为日常手段,Redis Exporter方案作为标准监控底座,慢查询日志作为辅助诊断工具。
4.2 慢查询日志:事后诊断利器
Redis慢查询日志记录执行时间超过 slowlog-log-slower-than 阈值的命令,默认阈值10000微秒(10ms)。
配置与查看
# 设置慢查询阈值(微秒),生产建议设为1000~5000
CONFIG SET slowlog-log-slower-than 5000
# 设置慢查询日志最大条数
CONFIG SET slowlog-max-len 128
# 查看最近10条慢查询
SLOWLOG GET 10
# 查看慢查询日志长度
SLOWLOG LEN
# 重置慢查询日志
SLOWLOG RESET
慢查询日志字段解析
| 字段 | 含义 | 示例 |
|---|---|---|
| ID | 日志唯一标识 | 105 |
| 时间戳 | 命令执行时的Unix时间戳 | 1712345678 |
| 耗时(微秒) | 命令实际执行时间 | 12000 |
| 命令及参数 | 执行的完整命令 | HGETALL user:profile:9527 |
| 客户端地址 | 发起命令的客户端IP:端口 | 10.0.1.100:54321 |
注意:慢查询日志只记录命令执行时间,不包含排队等待时间。如果Redis因CPU瓶颈导致整体延迟升高,慢查询日志可能无法反映真实问题,需结合其他监控手段。
4.3 MONITOR命令:实时抓取但慎用
MONITOR命令可以实时输出Redis服务器接收到的所有命令,是临时排查热点Key的“杀手锏”,但代价极高——在QPS较高的实例上开启MONITOR,可能导致Redis吞吐量下降50%以上。
安全使用规范
- 禁止在生产高负载实例上长时间开启,建议不超过30秒。
- 配合
redis-cli -c --pipe | grep过滤特定Key模式。 - 使用
redis-cli monitor | head -n 1000 > /tmp/monitor.log抓取样本后离线分析。 - 优先使用
redis-cli --intrinsic-latency评估当前延迟基线。
# 安全抓取示例:抓取1000条命令后自动退出
redis-cli -h 10.0.1.10 -p 6379 monitor | head -n 1000 > /tmp/hotkey_sample.log
# 分析高频Key
cat /tmp/hotkey_sample.log | awk '{print $NF}' | sort | uniq -c | sort -rn | head -20
4.4 客户端统计:生产环境首选
在客户端SDK层面统计命令调用频次,对Redis服务端零侵入,适合长期运行。主流Redis客户端(如Jedis、Lettuce、Redisson)均支持自定义命令拦截器或监听器。
实现思路(以Jedis为例)
// 自定义Jedis命令拦截器
public class HotKeyInterceptor extends JedisMonitor {
private final ConcurrentHashMap<String, AtomicLong> counter = new ConcurrentHashMap<>();
@Override
public void onCommand(String command, String... args) {
if (args.length > 0) {
String key = args[0];
counter.computeIfAbsent(key, k -> new AtomicLong()).incrementAndGet();
}
}
// 定期上报热点Key(例如每10秒输出Top N)
public void reportHotKeys(int topN) {
counter.entrySet().stream()
.sorted((a, b) -> Long.compare(b.getValue().get(), a.getValue().get()))
.limit(topN)
.forEach(entry -> System.out.println(entry.getKey() + " : " + entry.getValue().get()));
}
}
生产建议:客户端统计应配合本地滑动窗口(如每秒重置一次),避免内存泄漏;统计结果可通过日志或Metrics接口暴露给Prometheus等监控系统。
4.5 Redis Exporter + Prometheus + Grafana:全链路可视化监控
这是企业级Redis监控的标准方案,覆盖实例级指标、命令级统计、慢查询、内存、网络等维度,支持告警和趋势分析。
架构组件
部署与配置要点
- Redis Exporter:每个Redis实例部署一个Exporter,支持密码认证、TLS、自定义采集指标。
- Prometheus 配置:通过
scrape_configs定义采集目标,建议采集间隔15秒。 - Grafana 仪表盘:使用官方Redis Dashboard模板(ID:763),或自定义热点Key面板。
# prometheus.yml 示例配置
scrape_configs:
- job_name: 'redis_exporter'
static_configs:
- targets:
- '10.0.1.10:9121' # Redis主节点Exporter
- '10.0.1.11:9121' # Redis从节点Exporter
params:
# 自定义采集脚本路径(可选)
check.keys: ['user:*', 'product:*']
热点Key监控面板设计
| 面板名称 | PromQL查询 | 展示方式 |
|---|---|---|
| QPS趋势 | rate(redis_commands_processed_total[1m]) |
折线图 |
| Top N 热点Key | topk(10, redis_command_calls_total) |
表格 + 柱状图 |
| 慢查询次数 | rate(redis_slowlog_length[5m]) |
折线图 |
| 内存使用率 | redis_memory_used_bytes / redis_memory_max_bytes |
仪表盘 |
| 客户端连接数 | redis_connected_clients |
折线图 |
告警规则示例:当
instantaneous_ops_per_sec > 50000 且持续1分钟,触发“高QPS告警”;当 redis_slowlog_length > 10 持续5分钟,触发“慢查询堆积告警”。
4.6 四种手段协同使用策略
单一手段无法覆盖所有场景,推荐分层协同策略:
- 日常监控层:Redis Exporter + Prometheus + Grafana,7×24小时全量指标采集,设置告警规则。
- 热点发现层:客户端统计(SDK内置),实时输出Top N热点Key,上报至Prometheus。
- 诊断分析层:慢查询日志,定位大Key和慢命令;必要时临时使用MONITOR抓取样本。
- 应急处理层:发现热点Key后,触发本地缓存、Key拆分、读写分离等削峰策略。
最佳实践:在Grafana中创建“热点Key大屏”,同时展示QPS、Top 10 Key、慢查询趋势、内存使用率,并关联告警通道(企业/钉钉/PagerDuty),实现从发现到处理的全闭环。