【数据库】【Redis】监控与告警体系构建

Redis 作为高性能内存数据库,其监控体系是保障业务连续性的生命线。完善的监控需覆盖性能、资源、连接、持久化、集群 五大维度,配合主动告警+自动恢复机制,实现从"看得见"到"管得住"的闭环

核心监控指标全景图

1. 性能指标(P0 - 直接影响用户体验)

指标 采集命令 健康阈值 告警阈值 影响说明
QPS INFO statsinstantaneous_ops_per_sec < 5万 > 10万 超过单实例性能上限,延迟飙升
平均延迟 SLOWLOG GET / LATENCY LATEST < 1ms > 10ms 用户感知卡顿,业务超时
慢查询数量 SLOWLOG LEN < 100 > 1000 大key或复杂命令阻塞
命令执行时间 SLOWLOG GET < 10ms > 100ms 定位具体慢命令

实战采集代码:

java 复制代码
// Java 定时任务采集性能指标(每10秒)[⁸⁹]
Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT);
String info = jedis.info("stats");
Map<String, String> stats = parseInfo(info);
int qps = Integer.parseInt(stats.get("instantaneous_ops_per_sec"));
long slowlogLen = jedis.slowlogLen();

问题定位:

  • QPS 突增:业务流量暴涨 or 缓存穿透导致大量请求打到 Redis
  • 延迟飙升:BigKey 操作、AOF 重写、RDB 快照、网络抖动

2. 资源利用指标(P0 - 决定系统稳定性)

指标 采集命令 健康阈值 危险阈值 应对方案
内存使用率 INFO memoryused_memory_rss / maxmemory < 70% > 90% 扩容 or 淘汰策略优化
内存碎片率 used_memory_rss / used_memory 1.0-1.5 > 2.0 重启 or MEMORY PURGE
CPU 使用率 INFO cpuused_cpu_sys / used_cpu_user < 60% > 80% 排查慢查询、优化命令
网络输入/输出流量 INFO statstotal_net_input_bytes < 500MB/s > 1GB/s 压缩 value or 减少批量操作

关键指标详解:

  • 内存占用used_memory_human:Redis 数据占用的内存大小(不含碎片)

    • 风险:超过 maxmemory 触发淘汰 or OOM
    • 优化:设置 maxmemory-policy allkeys-lru,监控大 key
  • 内存峰值used_memory_peak:历史最大内存占用

    • 用途:评估 maxmemory 设置是否合理
  • 碎片率mem_fragmentation_ratio:

    • 1.0-1.5:健康
    • 大于1.5 :存在碎片,频繁更新删除导致
    • 大于2.0:严重碎片,建议重启 or MEMORY PURGE(4.0+)

大 key 监控:

java 复制代码
# 命令行扫描大 key(生产环境慎用)
redis-cli --bigkeys

# 推荐:用 MEMORY USAGE 采样
MEMORY USAGE user:1001  # 返回字节数

3. 连接状态指标(P1 - 服务可用性)

指标 采集命令 阈值 问题场景
客户端连接数 INFO clientsconnected_clients < 5000 > maxclients 导致新连接被拒
阻塞客户端数 blocked_clients < 10 BLPOP/BRPOP 长时间阻塞
拒绝连接数 rejected_connections 0 > 0 说明已达最大连接数

连接数突增排查:

  • 连接池泄漏(未归还)
  • 业务代码循环创建连接
  • 网络分区导致客户端重连风暴

应对:

java 复制代码
# 调整最大连接数
maxclients 10000

# 设置连接超时,避免空闲连接堆积
timeout 300

4. 持久化指标(P1 - 数据安全)

指标 采集方式 健康状态 告警规则
RDB 最后一次成功时间 INFO persistencerdb_last_save_time < 3600s > 86400s(1天未备份)
AOF 重写状态 aof_rewrite_in_progress 0 = 1(持续 > 10分钟)
AOF 缓冲区大小 aof_buffer_length < 10MB > 100MB(写入过快)
主从复制延迟(Offset) master_repl_offset - slave_repl_offset < 1MB > 10MB(延迟严重)

主从延迟监控:

java 复制代码
# 在 Slave 上执行
INFO replication
# 指标:master_link_status: up, slave_repl_offset, master_repl_offset

# 计算延迟字节数
delay = master_repl_offset - slave_repl_offset

延迟原因与解决:

  • 网络带宽:升级带宽 or 压缩传输(repl-diskless-sync yes)
  • Slave 性能:Slave 配置低,处理慢 → 提升 Slave 配置
  • 大 key:主节点删除大 key,生成 RDB 慢 → 拆分大 key

5. 键空间指标(P2 - 业务健康度)

指标 采集命令 业务含义 优化建议
Key 总数 INFO keyspacedb0:keys=100000 增长趋势 设置 TTL 或定期清理
过期 key 数量 expired_keys 活跃度 监控过期速率
Key 命中率 keyspace_hits / (hits + misses) 缓存效率 > 95% 为健康
淘汰 key 数量 evicted_keys 内存压力 > 0 说明内存不足

命中率计算:

java 复制代码
long hits = Long.parseLong(stats.get("keyspace_hits"));
long misses = Long.parseLong(stats.get("keyspace_misses"));
double hitRate = (double) hits / (hits + misses) * 100;
// 告警:hitRate < 90%

命中率低的原因:

  • 缓存穿透(查询不存在的数据):布隆过滤器拦截
  • 缓存雪崩(大量 key 同时过期):过期时间加随机值
  • 缓存击穿(热点 key 过期):互斥锁重建缓存

6. 集群健康指标(P1 - 分布式场景)

指标 采集命令 正常值 告警场景
主节点数 CLUSTER INFOcluster_known_nodes = 预期节点数 节点下线
失败槽位数 cluster_slots_fail 0 > 0(部分数据不可访问)
主从同步延迟 master_link_status up down
正在迁移的槽位数 cluster_slots_pfail 0 > 0(扩容迁移中)

二、监控工具选型与集成

工具 1:Redis 原生命令(轻量级)

适用场景: 快速诊断、脚本化监控

bash 复制代码
# 实时性能监控
redis-cli INFO [section]  # section: server, clients, memory, stats, replication, cpu, keyspace, cluster

# 慢查询日志
CONFIG SET slowlog-log-slower-than 10000  # 记录 >10ms 的命令
SLOWLOG GET 10  # 获取最近10条慢查询

# 延迟诊断
redis-cli --latency-history -i 100  # 每100ms采样延迟

# 实时监控命令
redis-cli MONITOR  # 高开销,仅用于调试

优缺点:

✅ 零依赖,开箱即用

❌ 数据不持久化,无可视化,无法告警

工具 2:RedisInsight(官方可视化)

官网https://redis.com/redis-enterprise/redis-insight/
核心功能:

  • 实时监控:QPS、内存、CPU、连接数仪表盘
  • 慢查询分析:图形化展示慢命令排行榜
  • 大 Key 检测:扫描并展示 Top 100 BigKey
  • 数据浏览:CRUD 操作,支持多种数据结构
  • 配置优化建议:基于当前负载给出 redis.conf 优化建议

部署:

bash 复制代码
docker run -d -p 8001:8001 redislabs/redisinsight

优缺点:

✅ 功能全面,官方支持,免费

❌ 资源消耗较高(需 1GB+ 内存)

❌ 不支持多实例集中监控(需部署多个)

工具 3:Prometheus + Grafana(企业级标准)

架构:

Redis → Redis Exporter → Prometheus → Grafana → 告警(AlertManager)
部署 Redis Exporter:

bash 复制代码
docker run -d --name redis-exporter \
  -p 9121:9121 \
  oliver006/redis_exporter \
  --redis.addr=redis://192.168.1.101:6379 \
  --redis.password=your_password

Prometheus 配置(yaml):

yaml 复制代码
scrape_configs:
  - job_name: 'redis'
    static_configs:
      - targets: ['192.168.1.101:9121']

Grafana 仪表盘:

告警规则 (Prometheus):

yaml

yaml 复制代码
groups:
- name: redis
  rules:
  - alert: RedisDown
    expr: up{job="redis"} == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Redis {{ $labels.instance }} down"
  
  - alert: RedisMemoryHigh
    expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Redis memory usage > 90%"
  
  - alert: RedisSlowLog
    expr: increase(redis_slowlog_length[5m]) > 10
    labels:
      severity: warning
    annotations:
      summary: "Redis slow query increased"

优缺点:

✅ 生产级标准:支持大规模集群、长期存储、灵活告警

✅ 生态完善:与 Kubernetes、AlertManager 无缝集成

❌ 部署复杂:需维护 Prometheus、Grafana、Exporter 三套组件

工具 4:Another Redis Desktop Manager(运维利器)

GitHubhttps://github.com/qishibo/AnotherRedisDesktopManager
特点:

  • 开源免费:GitHub 20k+ star
  • SSH 隧道:支持跳板机连接
  • Dark Mode:程序员友好
  • 大 Key 分析:内置扫描功能
  • 命令行模式:支持 Redis CLI

适用场景: 日常运维、开发调试

三、告警规则配置实战

一级告警(Critical)- 立即处理

yaml 复制代码
- alert: RedisDown
  expr: up{job="redis"} == 0
  for: 1m
  labels:
    severity: critical
    channel: phone  # 电话告警
  annotations:
    summary: "Redis 实例 {{ $labels.instance }} 宕机"
    runbook: "1. 检查 Redis 进程 2. 查看系统日志 3. 执行故障转移"

- alert: RedisMemoryCritical
  expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.95
  for: 3m
  labels:
    severity: critical
  annotations:
    summary: "Redis 内存使用率 > 95%,可能触发 OOM"
    action: "1. 检查大 key 2. 清理过期 key 3. 紧急扩容"

二级告警(Warning)- 4 小时内处理

yaml 复制代码
- alert: RedisSlowQuery
  expr: rate(redis_slowlog_length[5m]) > 5  # 5 分钟新增 5 条慢查询
  for: 10m
  labels:
    severity: warning
  annotations:
    summary: "Redis 慢查询增多"
    action: "查看慢查询日志,优化命令或大 key"

- alert: RedisReplicationLag
  expr: redis_master_repl_offset - redis_slave_repl_offset > 1048576  # 1MB 延迟
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "主从同步延迟过大"
    action: "检查网络带宽、Slave 性能、是否有大 key"

三级告警(Info)- 24 小时内处理

yaml 复制代码
- alert: RedisHitRateLow
  expr: redis_keyspace_hits / (redis_keyspace_hits + redis_keyspace_misses) < 0.8
  for: 1h
  labels:
    severity: info
  annotations:
    summary: "Redis 命中率低于 80%"
    suggestion: "检查业务逻辑,优化缓存策略,避免缓存穿透"

四、常见问题应对方案

问题 1:Redis 内存耗尽(OOM)

现象 :used_memory > maxmemory,写入报错 OOM command not allowed
告警配置

yaml 复制代码
expr: redis_memory_used_bytes / redis_memory_max_bytes > 0.9

应对方案(按优先级):

1.紧急处理:

bash 复制代码
# 1. 排查大 key(立即释放)
redis-cli --bigkeys
# 删除大 key(慎用,会阻塞)
DEL bigkey

# 2. 调整淘汰策略(允许淘汰)
CONFIG SET maxmemory-policy allkeys-lru

# 3. 临时增加 maxmemory(物理内存足够时)
CONFIG SET maxmemory 8gb

2.短期优化:

  • 拆分大 key:Hash/List 拆分为多个小 key
  • 设置 TTL:非热点 key 自动过期
  • 使用内存压缩:启用 list-max-ziplist-size 等编码优化

3.长期规划:

  • 垂直扩容:升级服务器内存
  • 水平扩容:Cluster 分片,分散数据
  • 冷热分离:冷数据迁移到 SSD(Redis on Flash)

问题 2:缓存雪崩(大量 key 同时过期)

现象 :QPS 突增,数据库压力剧增,响应延迟飙升
监控指标

yaml 复制代码
expr: increase(redis_expired_keys[1m]) > 10000  # 1 分钟过期超过 1 万个

应对方案:

  • 1.过期时间加随机值:
java 复制代码
// 设置 TTL 时 + 随机值
int ttl = 3600 + new Random().nextInt(300); // 3600-3900 秒
redis.setex(key, ttl, value);
  • 2.互斥锁重建缓存
java 复制代码
String getWithRebuild(String key) {
    String value = redis.get(key);
    if (value == null) {
        // 获取互斥锁
        if (redis.setnx("lock:" + key, "1")) {
            redis.expire("lock:" + key, 30);
            value = db.query(); // 查询数据库
            redis.setex(key, 3600, value);
            redis.del("lock:" + key);
        } else {
            Thread.sleep(100);
            return getWithRebuild(key); // 重试
        }
    }
    return value;
}
  • 3.提前预热:在业务低峰期主动加载热点数据

问题 3:缓存穿透(查询不存在的数据)

现象 :缓存命中率极低(< 50%),数据库压力持续高位
监控指标

yaml 复制代码
expr: redis_keyspace_misses / (redis_keyspace_hits + redis_keyspace_misses) > 0.5

应对方案:

  • 布隆过滤器
java 复制代码
RBloomFilter<String> bloomFilter = redisson.getBloomFilter("bloom:product");
bloomFilter.tryInit(1000000, 0.01);

// 查询时先查布隆过滤器
if (!bloomFilter.contains(productId)) {
    return null; // 一定不存在
}
// 再查询缓存和数据库
  • 缓存空值
java 复制代码
String value = db.query(productId);
if (value == null) {
    redis.setex(productId, 60, "NULL"); // 缓存空值,防止重复查询
}

问题 4:主从同步延迟

现象 :从节点数据落后主节点,读请求读到旧数据
监控指标

yaml 复制代码
expr: redis_master_repl_offset - redis_slave_repl_offset > 10485760  # 10MB 延迟

应对方案:

  • 诊断
bash 复制代码
# 在 Slave 上执行
INFO replication
# 查看:master_last_io_seconds_ago(主从最后通信时间)
# 查看:slave_repl_offset 与主节点对比
  • 优化
    • 升级网络带宽(建议 10Gbps)
    • 提升 Slave 配置(与 Master 同规格)
    • 减少大 key:repl-timeout 默认 60 秒,大 key 传输超时
    • 开启无盘复制:repl-diskless-sync yes(减少主节点磁盘 IO)

问题 5:慢查询阻塞

现象 :某些命令执行时间 > 100ms,导致 Redis 阻塞
监控配置

ini 复制代码
# redis.conf
slowlog-log-slower-than 10000  # 记录 >10ms 的命令
slowlog-max-len 1000            # 保留最近 1000 条

告警:

yaml 复制代码
expr: increase(redis_slowlog_length[5m]) > 10

应对方案:

  • 1.定位慢查询
bash 复制代码
redis-cli SLOWLOG GET 10
# 输出:ID、时间戳、执行时长(微秒)、命令及参数
  • 2.优化
    • 大 key 拆分:DEL 100万元素的List → LTRIM 分批删除
    • 复杂命令禁用:生产环境禁用 KEYS *、FLUSHALL、EVAL 大量数据
    • 使用 Pipeline:批量操作减少 RTT
    • 缩短慢查询阈值:CONFIG SET slowlog-log-slower-than 5000

问题 6:Redis Cluster 槽位故障

现象 :cluster_slots_fail > 0,部分数据不可访问
监控指标

yaml 复制代码
expr: redis_cluster_slots_fail > 0

应对方案:

  • 1.定位故障节点
bash 复制代码
redis-cli CLUSTER NODES
# 查看节点状态:fail?、disconnected?
  • 自动恢复
    • Sentinel 会自动提升 Slave 为 Master
    • 手动修复:重启故障节点,执行 CLUSTER MEET 重新加入集群
  • 预防
    • 每个 Master 至少 1 个 Slave
    • 跨机架部署,避免单机架故障
    • 设置 cluster-require-full-coverage no(允许部分槽位故障)

五、运维最佳实践

1. 监控覆盖率要求

  • 100% 实例覆盖:所有 Redis 实例(包括测试环境)接入监控
  • 7x24 小时监控:保留 30 天历史数据,支持趋势分析
  • 秒级采集:核心指标(QPS、内存)采集频率 ≤ 10 秒

2. 告警分级响应

级别 响应时间 通知方式 处理人
Critical 5 分钟内 电话 + 短信 + 邮件 值班运维 + 架构师
Warning 30 分钟内 短信 + 邮件 + 企业微信 值班运维
Info 4 小时内 邮件 运维

3. 监控与业务联动

java 复制代码
// 业务代码嵌入监控埋点
public void createOrder(Order order) {
    long start = System.currentTimeMillis();
    try {
        redis.setex("order:" + order.getId(), 3600, JSON.toJSONString(order));
        Metrics.timer("redis.setex.duration", System.currentTimeMillis() - start);
    } catch (Exception e) {
        Metrics.counter("redis.setex.errors").increment();
        throw e;
    }
}

4. 定期健康检查

bash 复制代码
# 每周执行
redis-cli INFO ALL > redis_health_$(date +%Y%m%d).log
redis-cli --latency-history -i 100 > latency_report.log
redis-cli SLOWLOG RESET  # 重置慢查询日志

# 分析报告
检查:内存使用率、命中率、主从延迟、慢查询数量

六、一句话总结

Redis 监控体系 = 核心指标全采集 + Prometheus 持久化 + Grafana 可视化 + 分级精准告警 + 自动化应对方案。记住:监控不是为了好看,而是为了在故障发生前尽早发现问题,在故障发生后尽快恢复服务。从 QPS、内存、命中率这 3 个黄金指标开始,逐步完善你的监控版图

相关推荐
老华带你飞2 小时前
个人网盘管理|基于springboot + vue个人网盘管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
代码or搬砖2 小时前
悲观锁讲解
开发语言·数据库
soft20015252 小时前
MySQL Buffer Pool深度解析:冷热数据分离下的LRU链表工作机制
数据库·mysql·链表
whn19772 小时前
磁盘空间不足导致oracle的system01.dbf损坏
数据库·oracle
此生只爱蛋2 小时前
【Redis】Hash 哈希
数据库·redis·哈希算法
Irene19912 小时前
前端缓存方式 对比 和 Service Worker 缓存详解
缓存·service worker
郑州光合科技余经理3 小时前
PHP构建:支撑欧美澳市场的同城生活服务平台开发
java·开发语言·数据库·uni-app·php·排序算法·生活
JIngJaneIL11 小时前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
微学AI12 小时前
复杂时序场景的突围:金仓数据库是凭借什么超越InfluxDB?
数据库