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 monitor2.1.3 CLIENT LIST命令
CLIENT LIST命令可以查看当前所有客户端连接的详细信息。
redis-cli client list2.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:
- 添加Prometheus数据源
- 导入Redis监控面板(推荐面板ID:763)
2.2.2 Redis Sentinel
如果使用了Redis Sentinel,可以通过Sentinel的INFO命令查看监控信息。
redis-cli -p 26379 info sentinel2.2.3 Redis Cluster
对于Redis Cluster,可以通过CLUSTER INFO命令查看集群状态。
redis-cli cluster info3. 核心监控指标
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 yes4.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
}
EOF4.3 日志分析
使用ELK Stack分析Redis日志:
- Elasticsearch:存储日志数据
- Logstash:收集和处理日志
- 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: true5.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%"
# 这里可以添加发送邮件或其他通知的逻辑
fi6. 可观测性最佳实践
6.1 构建完整的监控体系
多层次监控:
- 基础设施监控(CPU、内存、磁盘、网络)
- Redis实例监控(指标、日志)
- 应用层监控(Redis操作耗时、错误率)
监控指标选择:
- 核心指标必须监控(如内存使用、连接数、命中率)
- 业务相关指标(如特定键的访问频率)
- 预测性指标(如内存增长趋势)
告警策略:
- 分级告警(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 -206.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 06.4 监控仪表盘
使用Grafana构建Redis监控仪表盘:
导入官方Redis仪表盘:
- 仪表盘ID:763
- 数据源:Prometheus
关键监控面板:
- 内存使用情况
- 连接数
- 命令执行统计
- 命中率
- 复制状态
- 持久化状态
- 集群状态(如果使用集群)
7. 案例分析
7.1 内存使用过高问题
问题现象:
- Redis内存使用持续增长
- 内存碎片率高
- 可能出现OOM错误
排查步骤:
- 使用
redis-cli --bigkeys查找大键 - 检查内存使用情况:
redis-cli info memory - 分析键的过期时间:
redis-cli info keyspace - 检查内存淘汰策略:
redis-cli config get maxmemory-policy
解决方案:
- 删除或优化大键
- 合理设置键的过期时间
- 调整内存淘汰策略
- 增加Redis实例内存或使用集群分片
7.2 复制延迟问题
问题现象:
- 从节点复制偏移量远低于主节点
- 复制状态异常
- 可能影响高可用性
排查步骤:
- 检查网络连接:
ping主节点 - 检查主节点负载:
redis-cli info stats - 检查复制积压缓冲区:
redis-cli info replication - 查看复制日志
解决方案:
- 优化网络连接
- 减轻主节点负载
- 增大复制积压缓冲区
- 考虑使用级联复制
7.3 连接数过高问题
问题现象:
- 连接数持续增长
- 可能达到maxclients限制
- 影响Redis性能
排查步骤:
- 查看客户端连接:
redis-cli client list - 检查连接来源和状态
- 分析应用代码,检查是否正确释放连接
解决方案:
- 使用连接池管理连接
- 确保应用正确释放连接
- 调整maxclients参数
- 考虑使用Redis代理(如Twemproxy、Codis)
8. 总结
本教程详细介绍了Redis的监控与可观测性体系,包括:
- 监控工具:Redis自带监控命令、Redis Exporter + Prometheus + Grafana等第三方工具
- 核心指标:服务器状态、持久化、复制、集群等关键指标
- 日志管理:日志配置、轮转和分析
- 告警系统:基于Prometheus Alertmanager的告警配置
- 可观测性最佳实践:构建完整的监控体系、性能分析、健康检查和监控仪表盘
- 案例分析:内存使用过高、复制延迟、连接数过高等常见问题的排查和解决方案
通过建立完善的Redis监控与可观测性体系,您可以:
- 及时发现和解决Redis性能问题
- 预防潜在的故障风险
- 优化Redis配置和使用方式
- 提高系统的可靠性和稳定性
在生产环境中,Redis的监控与可观测性是一个持续改进的过程,需要根据实际业务场景和系统特点不断调整和优化。