Redis监控与可观测性

1. 概述

在生产环境中,Redis的监控与可观测性是确保系统稳定运行的关键。本教程将详细介绍Redis的监控工具、核心指标、日志管理和可观测性最佳实践,帮助您构建一个全面的Redis监控系统。

2. 监控工具

2.1 Redis自带监控工具

2.1.1 INFO命令

INFO命令是Redis最基本的监控工具,提供了Redis服务器的详细信息。

# 查看所有信息
redis-cli info

# 查看特定部分的信息
redis-cli info server    # 服务器信息
redis-cli info clients   # 客户端连接信息
redis-cli info memory    # 内存使用情况
redis-cli info persistence  # 持久化信息
redis-cli info stats     # 统计信息
redis-cli info replication  # 复制信息
redis-cli info cpu       # CPU使用情况
redis-cli info commandstats  # 命令执行统计

2.1.2 MONITOR命令

MONITOR命令可以实时查看Redis服务器执行的所有命令。

redis-cli monitor

2.1.3 CLIENT LIST命令

CLIENT LIST命令可以查看当前所有客户端连接的详细信息。

redis-cli client list

2.2 第三方监控工具

2.2.1 Redis Exporter + Prometheus + Grafana

这是目前最流行的Redis监控方案,提供了全面的指标收集和可视化能力。

组件说明:

  • Redis Exporter:收集Redis指标并暴露给Prometheus
  • Prometheus:时序数据库,存储监控指标
  • Grafana:可视化平台,展示监控面板

安装Redis Exporter:

# 下载Redis Exporter
wget https://github.com/oliver006/redis_exporter/releases/download/v1.37.0/redis_exporter-v1.37.0.linux-amd64.tar.gz

# 解压
 tar -xzf redis_exporter-v1.37.0.linux-amd64.tar.gz

# 运行Redis Exporter
cd redis_exporter-v1.37.0.linux-amd64
./redis_exporter --redis.addr=redis://localhost:6379

配置Prometheus:

# prometheus.yml
scrape_configs:
  - job_name: 'redis'
    static_configs:
      - targets: ['localhost:9121']
    scrape_interval: 15s

启动Prometheus:

./prometheus --config.file=prometheus.yml

配置Grafana:

  1. 添加Prometheus数据源
  2. 导入Redis监控面板(推荐面板ID:763)

2.2.2 Redis Sentinel

如果使用了Redis Sentinel,可以通过Sentinel的INFO命令查看监控信息。

redis-cli -p 26379 info sentinel

2.2.3 Redis Cluster

对于Redis Cluster,可以通过CLUSTER INFO命令查看集群状态。

redis-cli cluster info

3. 核心监控指标

3.1 服务器状态指标

指标 说明 正常范围
uptime_in_seconds Redis运行时间(秒) 持续增长
connected_clients 当前连接的客户端数量 根据实际负载
blocked_clients 被阻塞的客户端数量 通常为0
used_memory Redis使用的内存总量 不超过物理内存的80%
used_memory_rss 操作系统分配给Redis的内存 接近used_memory
mem_fragmentation_ratio 内存碎片率 1.0-1.5正常,>2需关注
evicted_keys 因内存不足被驱逐的键数量 持续增长需关注
rejected_connections 因连接数限制被拒绝的连接数 应为0
instantaneous_ops_per_sec 每秒执行的命令数 根据实际负载
keyspace_hits 键命中次数 越高越好
keyspace_misses 键未命中次数 越低越好
hit_rate 命中率(keyspace_hits/(keyspace_hits+keyspace_misses)) >90%

3.2 持久化指标

指标 说明 正常范围
rdb_bgsave_in_progress RDB持久化是否进行中 通常为0
rdb_last_save_time 上次RDB持久化的时间戳 最近时间
rdb_last_bgsave_status 上次RDB持久化的状态 ok
aof_enabled AOF是否启用 根据配置
aof_rewrite_in_progress AOF重写是否进行中 通常为0
aof_last_rewrite_time 上次AOF重写的时间戳 最近时间
aof_last_bgrewrite_status 上次AOF重写的状态 ok
aof_last_write_status 上次AOF写入的状态 ok

3.3 复制指标

指标 说明 正常范围
role 实例角色(master/slave) 根据配置
connected_slaves 连接的从节点数量 根据复制拓扑
master_repl_offset 主节点的复制偏移量 持续增长
slave_repl_offset 从节点的复制偏移量 接近master_repl_offset
repl_backlog_active 复制积压缓冲区是否激活 1
repl_backlog_size 复制积压缓冲区大小 足够大
repl_backlog_first_byte_offset 复制积压缓冲区的起始偏移量 合理范围
repl_backlog_histlen 复制积压缓冲区的历史长度 接近repl_backlog_size

3.4 集群指标

指标 说明 正常范围
cluster_enabled 是否启用集群模式 1
cluster_state 集群状态 ok
cluster_slots_assigned 已分配的槽位数 16384
cluster_slots_ok 正常的槽位数 16384
cluster_slots_pfail 可能失败的槽位数 0
cluster_slots_fail 失败的槽位数 0
cluster_known_nodes 已知的节点数 集群节点数
cluster_size 集群大小 主节点数

4. 日志管理

4.1 Redis日志配置

Redis的日志配置主要通过redis.conf文件中的以下参数设置:

# 日志级别:debug, verbose, notice, warning
loglevel notice

# 日志文件路径,默认为标准输出
logfile "/var/log/redis/redis-server.log"

# 是否在后台运行
daemonize yes

4.2 日志轮转

为了避免日志文件过大,需要配置日志轮转。

使用logrotate配置日志轮转:

# 创建logrotate配置文件
cat > /etc/logrotate.d/redis << EOF
/var/log/redis/redis-server.log {
    daily
    missingok
    rotate 7
    compress
    delaycompress
    notifempty
    create 644 redis redis
    postrotate
        /bin/kill -USR1 $(cat /var/run/redis/redis-server.pid 2>/dev/null) 2>/dev/null || true
    endscript
}
EOF

4.3 日志分析

使用ELK Stack分析Redis日志:

  1. Elasticsearch:存储日志数据
  2. Logstash:收集和处理日志
  3. Kibana:可视化日志数据

Logstash配置示例:

input {
  file {
    path => "/var/log/redis/redis-server.log"
    start_position => "beginning"
    sincedb_path => "/dev/null"
  }
}

filter {
  grok {
    match => {
      "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\] \[%{LOGLEVEL:loglevel}\] %{GREEDYDATA:message}"
    }
  }
  date {
    match => ["timestamp", "ISO8601"]
    target => "@timestamp"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "redis-logs-%{+YYYY.MM.dd}"
  }
}

5. 告警系统

5.1 基于Prometheus Alertmanager的告警

配置告警规则:

# redis_alerts.yml
groups:
- name: redis_alerts
  rules:
  - alert: RedisDown
    expr: redis_up == 0
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "Redis实例宕机"
description: "Redis实例 {{ $labels.instance }} 已宕机超过5分钟"

  - alert: RedisMemoryUsageHigh
    expr: redis_memory_used_bytes / redis_memory_max_bytes * 100 > 80
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "Redis内存使用过高"
description: "Redis实例 {{ $labels.instance }} 内存使用超过80%,当前值: {{ $value }}%"

  - alert: RedisTooManyConnections
    expr: redis_connected_clients > 1000
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Redis连接数过多"
description: "Redis实例 {{ $labels.instance }} 连接数超过1000,当前值: {{ $value }}"

  - alert: RedisReplicationLag
    expr: redis_replication_offset_master - redis_replication_offset_slave > 10000
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "Redis复制延迟"
description: "Redis从节点 {{ $labels.instance }} 复制延迟超过10000,当前值: {{ $value }}"

  - alert: RedisKeyspaceMissRateHigh
    expr: rate(redis_keyspace_misses_total[5m]) / (rate(redis_keyspace_hits_total[5m]) + rate(redis_keyspace_misses_total[5m])) * 100 > 10
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "Redis缓存命中率过低"
description: "Redis实例 {{ $labels.instance }} 缓存命中率低于90%,当前值: {{ $value }}%"

配置Alertmanager:

# alertmanager.yml
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname', 'instance']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'email'

receivers:
- name: 'email'
  email_configs:
  - to: 'admin@example.com'
    from: 'alertmanager@example.com'
    smarthost: 'smtp.example.com:587'
    auth_username: 'alertmanager'
    auth_password: 'password'
    require_tls: true

5.2 基于脚本的告警

简单的内存使用监控脚本:

#!/bin/bash

# Redis连接信息
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""

# 告警阈值
MEMORY_THRESHOLD=80

# 获取内存使用情况
USED_MEMORY_RSS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" info memory | grep used_memory_rss_human | cut -d: -f2 | tr -d '\r\n')
TOTAL_SYSTEM_MEMORY=$(free -h | grep Mem: | awk '{print $2}')
MEMORY_USAGE_PERCENT=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" info memory | grep mem_fragmentation_ratio | cut -d: -f2 | tr -d '\r\n')

# 计算实际内存使用百分比
# 注意:这里只是一个简化的计算方式,实际应该根据系统总内存计算
ACTUAL_MEMORY_PERCENT=$(echo "scale=2; $MEMORY_USAGE_PERCENT * 100" | bc)

# 检查内存使用是否超过阈值
if (( $(echo "$ACTUAL_MEMORY_PERCENT > $MEMORY_THRESHOLD" | bc -l) )); then
    echo "告警:Redis内存使用过高!"
    echo "当前使用:$USED_MEMORY_RSS"
    echo "系统总内存:$TOTAL_SYSTEM_MEMORY"
    echo "内存使用百分比:$ACTUAL_MEMORY_PERCENT%"
    # 这里可以添加发送邮件或其他通知的逻辑
fi

6. 可观测性最佳实践

6.1 构建完整的监控体系

  1. 多层次监控

    • 基础设施监控(CPU、内存、磁盘、网络)
    • Redis实例监控(指标、日志)
    • 应用层监控(Redis操作耗时、错误率)
  2. 监控指标选择

    • 核心指标必须监控(如内存使用、连接数、命中率)
    • 业务相关指标(如特定键的访问频率)
    • 预测性指标(如内存增长趋势)
  3. 告警策略

    • 分级告警(critical、warning、info)
    • 合理的告警阈值和持续时间
    • 告警聚合和去重
    • 告警路由和升级策略

6.2 性能分析

使用Redis-cli的--bigkeys选项分析大键:

redis-cli --bigkeys

使用Redis的MEMORY USAGE命令分析单个键的内存使用:

redis-cli memory usage mykey

使用Redis的SCAN命令遍历键空间:

# 编写脚本遍历键空间
redis-cli --scan | head -20

6.3 健康检查

定期执行健康检查脚本:

#!/bin/bash

# Redis连接信息
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_PASSWORD=""

# 检查Redis是否可访问
PING_RESULT=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" ping)
if [ "$PING_RESULT" != "PONG" ]; then
    echo "Redis不可访问!"
    exit 1
fi

# 检查内存使用情况
MEMORY_USAGE=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" info memory | grep used_memory_rss_human | cut -d: -f2 | tr -d '\r\n')
echo "内存使用:$MEMORY_USAGE"

# 检查连接数
CONNECTED_CLIENTS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" info clients | grep connected_clients | cut -d: -f2 | tr -d '\r\n')
echo "连接数:$CONNECTED_CLIENTS"

# 检查复制状态(如果是从节点)
ROLE=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" role | head -1)
if [ "$ROLE" == "slave" ]; then
    MASTER_LINK_STATUS=$(redis-cli -h $REDIS_HOST -p $REDIS_PORT -a "$REDIS_PASSWORD" info replication | grep master_link_status | cut -d: -f2 | tr -d '\r\n')
    echo "复制状态:$MASTER_LINK_STATUS"
fi

echo "Redis健康检查完成!"
exit 0

6.4 监控仪表盘

使用Grafana构建Redis监控仪表盘:

  1. 导入官方Redis仪表盘

    • 仪表盘ID:763
    • 数据源:Prometheus
  2. 关键监控面板

    • 内存使用情况
    • 连接数
    • 命令执行统计
    • 命中率
    • 复制状态
    • 持久化状态
    • 集群状态(如果使用集群)

7. 案例分析

7.1 内存使用过高问题

问题现象:

  • Redis内存使用持续增长
  • 内存碎片率高
  • 可能出现OOM错误

排查步骤:

  1. 使用redis-cli --bigkeys查找大键
  2. 检查内存使用情况:redis-cli info memory
  3. 分析键的过期时间:redis-cli info keyspace
  4. 检查内存淘汰策略:redis-cli config get maxmemory-policy

解决方案:

  1. 删除或优化大键
  2. 合理设置键的过期时间
  3. 调整内存淘汰策略
  4. 增加Redis实例内存或使用集群分片

7.2 复制延迟问题

问题现象:

  • 从节点复制偏移量远低于主节点
  • 复制状态异常
  • 可能影响高可用性

排查步骤:

  1. 检查网络连接:ping主节点
  2. 检查主节点负载:redis-cli info stats
  3. 检查复制积压缓冲区:redis-cli info replication
  4. 查看复制日志

解决方案:

  1. 优化网络连接
  2. 减轻主节点负载
  3. 增大复制积压缓冲区
  4. 考虑使用级联复制

7.3 连接数过高问题

问题现象:

  • 连接数持续增长
  • 可能达到maxclients限制
  • 影响Redis性能

排查步骤:

  1. 查看客户端连接:redis-cli client list
  2. 检查连接来源和状态
  3. 分析应用代码,检查是否正确释放连接

解决方案:

  1. 使用连接池管理连接
  2. 确保应用正确释放连接
  3. 调整maxclients参数
  4. 考虑使用Redis代理(如Twemproxy、Codis)

8. 总结

本教程详细介绍了Redis的监控与可观测性体系,包括:

  • 监控工具:Redis自带监控命令、Redis Exporter + Prometheus + Grafana等第三方工具
  • 核心指标:服务器状态、持久化、复制、集群等关键指标
  • 日志管理:日志配置、轮转和分析
  • 告警系统:基于Prometheus Alertmanager的告警配置
  • 可观测性最佳实践:构建完整的监控体系、性能分析、健康检查和监控仪表盘
  • 案例分析:内存使用过高、复制延迟、连接数过高等常见问题的排查和解决方案

通过建立完善的Redis监控与可观测性体系,您可以:

  • 及时发现和解决Redis性能问题
  • 预防潜在的故障风险
  • 优化Redis配置和使用方式
  • 提高系统的可靠性和稳定性

在生产环境中,Redis的监控与可观测性是一个持续改进的过程,需要根据实际业务场景和系统特点不断调整和优化。

« 上一篇 Redis与Go集成 下一篇 » Redis备份与恢复