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%以上。

安全使用规范

  1. 禁止在生产高负载实例上长时间开启,建议不超过30秒。
  2. 配合 redis-cli -c --pipe | grep 过滤特定Key模式。
  3. 使用 redis-cli monitor | head -n 1000 > /tmp/monitor.log 抓取样本后离线分析。
  4. 优先使用 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 + Prometheus + Grafana 监控架构 Redis 主节点 Redis 从节点 Redis 哨兵/集群 Redis Exporter INFO / SLOWLOG / 客户端统计 Prometheus 时序存储 + 告警规则 Grafana 仪表盘 + 告警通知 告警通知 采集指标示例 connected_clients instantaneous_ops_per_sec keyspace_hits / misses

部署与配置要点

  1. Redis Exporter:每个Redis实例部署一个Exporter,支持密码认证、TLS、自定义采集指标。
  2. Prometheus 配置:通过 scrape_configs 定义采集目标,建议采集间隔15秒。
  3. 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拆分、读写分离等削峰策略。
热点Key监控分层协同策略 日常监控层:Redis Exporter + Prometheus + Grafana(全量指标,7×24h) 热点发现层:客户端统计(SDK内置,实时Top N) 诊断分析层:慢查询日志 + MONITOR(临时抓取) 应急处理层:本地缓存 / Key拆分 / 读写分离
最佳实践:在Grafana中创建“热点Key大屏”,同时展示QPS、Top 10 Key、慢查询趋势、内存使用率,并关联告警通道(企业/钉钉/PagerDuty),实现从发现到处理的全闭环。