4. 缓存水位指标体系:内存使用率、缓存命中率、逐出率、过期率、平均TTL

缓存水位复核的核心在于建立一套可量化、可预警的指标体系。仅凭单一指标(如内存使用率)无法准确判断缓存健康状态,必须将多个指标组合成“水位仪表盘”,才能区分正常波动、性能瓶颈与容量风险。本章定义五个核心指标,并给出每个指标的计算方式、正常阈值区间及异常联动分析规则。

4.1 指标全景与层级关系

五个指标并非平级关系,而是从容量压力、效率、淘汰行为三个维度构成分层监控模型。下图展示了指标之间的因果链:

缓存水位指标体系分层架构 缓存水位指标体系分层架构 容量压力层 内存使用率 效率层 缓存命中率 淘汰行为层 逐出率 / 过期率 / 平均TTL 压力驱动 效率恶化触发 核心逻辑 内存使用率升高 → 逐出/过期加剧 → 命中率下降 → 平均TTL缩短 → 水位恶化闭环 逐出率 单位时间被逐出key数 / 总key数 × 100% 阈值:< 0.1% / min 过期率 单位时间过期key数 / 总key数 × 100% 阈值:< 5% / min 平均TTL 所有key剩余生存时间 的算术平均值 阈值:> 600s
水位复核第一原则:不要单独看内存使用率。内存使用率超过80%但命中率仍高于95%、逐出率接近0,说明缓存工作正常;内存使用率仅60%但命中率已跌破80%、逐出率持续上升,说明存在大量冷数据或TTL设置不合理。

4.2 指标定义与计算方式

指标名称 定义 计算公式 数据来源
内存使用率 已用内存占最大内存的百分比 used_memory / maxmemory × 100% INFO memory
缓存命中率 读请求中命中缓存的比率 keyspace_hits / (keyspace_hits + keyspace_misses) × 100% INFO stats
逐出率 单位时间内因内存满而被强制淘汰的key占比 evicted_keys_delta / total_keys × 100% INFO stats(差值计算)
过期率 单位时间内因TTL到期而被删除的key占比 expired_keys_delta / total_keys × 100% INFO stats(差值计算)
平均TTL 所有带过期时间key的剩余生存时间均值 avg_ttl = sum(ttl_of_all_expirable_keys) / count INFO keyspace / 自定义采样
注意:逐出率和过期率必须使用差值计算(当前值减去上一采集周期的值),而非值。直接使用INFO命令中的累计值会导致误判。建议采集间隔为30~60秒。

4.3 指标联动分析矩阵

单一指标异常不足以触发扩容或缩容动作,必须结合多指标进行综合判定。下表列出五种典型水位场景及其对应的指标组合特征:

场景 内存使用率 命中率 逐出率 过期率 平均TTL 建议动作
健康水位 60%~75% ≥95% ≈0 < 2%/min > 1800s 无需操作
容量预警 75%~85% 90%~95% < 0.05%/min 2%~5%/min 600~1800s 评估扩容或优化TTL
逐出风暴 ≥85% 80%~90% ≥0.1%/min ≥5%/min < 600s 立即扩容或降级非核心缓存
冷数据堆积 ≥80% < 80% ≈0 < 1%/min > 3600s 主动淘汰冷数据,缩短TTL
TTL过短抖动 40%~60% 85%~95% ≈0 ≥10%/min < 300s 延长热点key的TTL

4.4 采集与聚合策略

为确保水位复核的实时性和准确性,指标采集需遵循以下规范:

  • 采集粒度:生产环境至少每30秒采集一次,核心缓存集群建议10秒一次。
  • 聚合窗口:1分钟、5分钟、15分钟三个窗口分别计算均值、P99和最大值。
  • 异常检测:使用3σ或移动平均法检测指标突增/突降,避免毛刺触发误告警。
  • 存储保留:原始数据保留7天,聚合数据保留30天用于趋势分析。
# 示例:使用Redis INFO命令采集关键指标(Python伪代码)
import redis
import time

def collect_cache_watermark(host, port):
    r = redis.Redis(host=host, port=port)
    info = r.info()
    
    # 内存使用率
    used_memory = info['used_memory']
    maxmemory = info['maxmemory']
    memory_usage = (used_memory / maxmemory) * 100 if maxmemory > 0 else 0
    
    # 命中率(需结合上一周期差值)
    hits = info['keyspace_hits']
    misses = info['keyspace_misses']
    hit_rate = (hits / (hits + misses)) * 100 if (hits + misses) > 0 else 0
    
    # 逐出率与过期率(需存储上一周期值做差值)
    evicted = info['evicted_keys']
    expired = info['expired_keys']
    total_keys = info['db0']['keys']
    
    return {
        'memory_usage': round(memory_usage, 2),
        'hit_rate': round(hit_rate, 2),
        'evicted_keys': evicted,
        'expired_keys': expired,
        'total_keys': total_keys,
        'timestamp': int(time.time())
    }

4.5 水位复核决策树

基于上述指标体系,可构建自动化水位复核决策树,辅助运维人员快速定位问题根因:

缓存水位复核决策树 缓存水位复核决策树 内存使用率 > 75%? 是 检查逐出率 ≥0.1% 逐出风暴 → 扩容 <0.05% 冷数据堆积 → 优化TTL 否 检查命中率 ≥95% 健康水位 → 持续监控 <90% 检查平均TTL是否过短 决策输出 • 内存高 + 逐出高 → 扩容或降级 • 内存高 + 逐出低 + 命中低 → 冷数据清理 • 内存低 + 命中低 + TTL短 → 延长TTL或预热 • 内存低 + 命中高 → 健康状态,持续观察
实战要点:在Redis 6.x及以上版本中,可使用MEMORY STATS命令获取更精细的内存分布数据(如overhead、dataset占比),辅助判断内存使用率升高的根因是数据量增长还是元数据膨胀。

4.6 指标可视化与告警配置建议

在Grafana或自建监控平台中,建议将五个指标组合到同一个仪表盘面板,并配置以下告警规则:

  • P0告警(立即处理):内存使用率 ≥ 90% 且 逐出率 ≥ 0.2%/min
  • P1告警(15分钟内处理):命中率 < 85% 且 逐出率 > 0.05%/min
  • P2告警(1小时内评估):平均TTL < 300s 且 过期率 > 8%/min
  • 通知告警(仅记录):内存使用率 > 75% 持续超过30分钟