4. 缓存水位指标体系:内存使用率、缓存命中率、逐出率、过期率、平均TTL
缓存水位复核的核心在于建立一套可量化、可预警的指标体系。仅凭单一指标(如内存使用率)无法准确判断缓存健康状态,必须将多个指标组合成“水位仪表盘”,才能区分正常波动、性能瓶颈与容量风险。本章定义五个核心指标,并给出每个指标的计算方式、正常阈值区间及异常联动分析规则。
4.1 指标全景与层级关系
五个指标并非平级关系,而是从容量压力、效率、淘汰行为三个维度构成分层监控模型。下图展示了指标之间的因果链:
水位复核第一原则:不要单独看内存使用率。内存使用率超过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 水位复核决策树
基于上述指标体系,可构建自动化水位复核决策树,辅助运维人员快速定位问题根因:
实战要点:在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分钟