Redis性能监控与优化脚本
监控Redis性能指标,分析内存使用、命中率、慢查询、连接数,给出优化建议
详细内容
#!/bin/bash
# ==========================================
# Redis性能监控与优化脚本
# 用途:监控Redis性能,分析内存和命中率,给出优化建议
# 使用方法:bash redis_perf_monitor.sh
# ==========================================
REDIS_HOST="${REDIS_HOST:-127.0.0.1}"
REDIS_PORT="${REDIS_PORT:-6379}"
REDIS_PASS="${REDIS_PASS:-}"
echo "========== Redis性能监控报告 =========="
echo "监控时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "目标: $REDIS_HOST:$REDIS_PORT"
echo ""
# 检查redis-cli
if ! command -v redis-cli &> /dev/null; then
echo "❌ 错误: redis-cli未安装"
exit 1
fi
# 构建redis-cli命令
REDIS_CMD="redis-cli -h $REDIS_HOST -p $REDIS_PORT"
if [ -n "$REDIS_PASS" ]; then
REDIS_CMD="$REDIS_CMD -a $REDIS_PASS --no-auth-warning"
fi
# 测试连接
if ! $REDIS_CMD ping &>/dev/null; then
echo "❌ 错误: 无法连接Redis,请检查连接配置"
exit 1
fi
echo "✅ Redis连接成功"
echo ""
# 获取INFO信息
INFO=$($REDIS_CMD INFO all 2>/dev/null)
get_info_value() {
echo "$INFO" | grep "^$1:" | cut -d: -f2 | tr -d '
'
}
# 1. 基本信息
echo "【1. 基本信息】"
echo " Redis版本: $(get_info_value redis_version)"
echo " 运行模式: $(get_info_value redis_mode)"
echo " 操作系统: $(get_info_value os)"
echo " 运行时间: $(get_info_value uptime_in_days) 天"
echo " 进程ID: $(get_info_value process_id)"
echo ""
# 2. 内存使用
echo "【2. 内存使用分析】"
USED_MEMORY=$(get_info_value used_memory)
USED_MEMORY_HUMAN=$(get_info_value used_memory_human)
USED_MEMORY_RSS=$(get_info_value used_memory_rss_human)
USED_MEMORY_PEAK=$(get_info_value used_memory_peak_human)
MAXMEMORY=$(get_info_value maxmemory)
MAXMEMORY_POLICY=$(get_info_value maxmemory_policy)
MEM_FRAGMENTATION_RATIO=$(get_info_value mem_fragmentation_ratio)
echo " 已用内存: $USED_MEMORY_HUMAN"
echo " RSS内存: $USED_MEMORY_RSS"
echo " 内存峰值: $USED_MEMORY_PEAK"
echo " 最大内存配置: $([ "$MAXMEMORY" = "0" ] && echo '未限制' || echo "$MAXMEMORY")"
echo " 淘汰策略: $MAXMEMORY_POLICY"
echo " 内存碎片率: $MEM_FRAGMENTATION_RATIO"
if [ -n "$MEM_FRAGMENTATION_RATIO" ]; then
if (( $(echo "$MEM_FRAGMENTATION_RATIO > 1.5" | bc -l) )); then
echo " ⚠️ 内存碎片率过高(>1.5),建议:"
echo " - 执行 redis-cli --bigkeys 查找大key"
echo " - 考虑重启Redis实例整理内存"
echo " - 检查是否有大量过期key未清理"
fi
fi
if [ "$MAXMEMORY" = "0" ]; then
echo " ⚠️ 未配置maxmemory,建议设置最大内存限制"
fi
echo ""
# 3. 键空间统计
echo "【3. 键空间统计】"
KEYSPACE=$(get_info_value db0)
if [ -n "$KEYSPACE" ]; then
KEYS=$(echo "$KEYSPACE" | grep -oP 'keys=\K[0-9]+')
EXPIRES=$(echo "$KEYSPACE" | grep -oP 'expires=\K[0-9]+')
AVG_TTL=$(echo "$KEYSPACE" | grep -oP 'avg_ttl=\K[0-9]+')
echo " 总键数: $KEYS"
echo " 过期键数: $EXPIRES"
echo " 平均TTL: $([ -n "$AVG_TTL" ] && echo "$((AVG_TTL/1000))秒" || echo 'N/A')"
else
echo " 数据库为空"
fi
# 大key检查提示
echo " 提示: 执行 redis-cli --bigkeys 可查找大key"
echo ""
# 4. 命中率分析
echo "【4. 缓存命中率分析】"
KEYSPACE_HITS=$(get_info_value keyspace_hits)
KEYSPACE_MISSES=$(get_info_value keyspace_misses)
TOTAL_REQUESTS=$((KEYSPACE_HITS + KEYSPACE_MISSES))
if [ "$TOTAL_REQUESTS" -gt 0 ]; then
HIT_RATE=$(echo "scale=2; $KEYSPACE_HITS * 100 / $TOTAL_REQUESTS" | bc)
echo " 命中次数: $KEYSPACE_HITS"
echo " 未命中次数: $KEYSPACE_MISSES"
echo " 命中率: ${HIT_RATE}%"
if (( $(echo "$HIT_RATE < 80" | bc -l) )); then
echo " ⚠️ 命中率低于80%,建议:"
echo " - 检查缓存策略是否合理"
echo " - 增加缓存容量或调整淘汰策略"
echo " - 优化查询,减少不必要的缓存未命中"
else
echo " ✅ 命中率良好"
fi
else
echo " 无请求记录"
fi
echo ""
# 5. 连接数分析
echo "【5. 连接数分析】"
CONNECTED_CLIENTS=$(get_info_value connected_clients)
MAX_CLIENTS=$(get_info_value maxclients)
BLOCKED_CLIENTS=$(get_info_value blocked_clients)
echo " 当前连接数: $CONNECTED_CLIENTS"
echo " 最大连接数: $MAX_CLIENTS"
echo " 阻塞连接数: $BLOCKED_CLIENTS"
if [ -n "$MAX_CLIENTS" ] && [ "$MAX_CLIENTS" -gt 0 ]; then
CONN_RATIO=$(echo "scale=1; $CONNECTED_CLIENTS * 100 / $MAX_CLIENTS" | bc)
echo " 连接使用率: ${CONN_RATIO}%"
if (( $(echo "$CONN_RATIO > 80" | bc -l) )); then
echo " ⚠️ 连接数使用率超过80%,建议增大maxclients"
fi
fi
echo ""
# 6. 命令统计
echo "【6. 命令执行统计】"
TOTAL_COMMANDS=$(get_info_value total_commands_processed)
INSTANTANEOUS_OPS=$(get_info_value instantaneous_ops_per_sec)
echo " 累计命令数: $TOTAL_COMMANDS"
echo " 当前OPS: $INSTANTANEOUS_OPS"
# Top命令
echo " Top 5命令:"
$REDIS_CMD INFO commandstats 2>/dev/null | grep '^cmdstat_' | head -5 | while read line; do
CMD=$(echo "$line" | cut -d: -f1 | sed 's/cmdstat_//')
CALLS=$(echo "$line" | grep -oP 'calls=\K[0-9]+')
USEC=$(echo "$line" | grep -oP 'usec=\K[0-9]+')
if [ -n "$CALLS" ] && [ "$CALLS" -gt 0 ]; then
AVG_USEC=$((USEC / CALLS))
echo " $CMD: 调用$CALLS次, 平均${AVG_USEC}微秒"
fi
done
echo ""
# 7. 持久化状态
echo "【7. 持久化状态】"
RDB_LAST_SAVE=$(get_info_value rdb_last_save_time)
RDB_CHANGES=$(get_info_value rdb_changes_since_last_save)
AOF_ENABLED=$(get_info_value aof_enabled)
echo " RDB最后保存: $(date -d @$RDB_LAST_SAVE '+%Y-%m-%d %H:%M:%S' 2>/dev/null || echo 'N/A')"
echo " RDB未保存变更: $RDB_CHANGES"
echo " AOF启用: $([ "$AOF_ENABLED" = "1" ] && echo '是' || echo '否')"
if [ "$AOF_ENABLED" = "0" ]; then
echo " ⚠️ AOF未启用,建议启用AOF持久化提高数据安全性"
fi
echo ""
# 8. 慢查询
echo "【8. 慢查询日志】"
SLOWLOG_LEN=$($REDIS_CMD SLOWLOG LEN 2>/dev/null)
echo " 慢查询总数: $SLOWLOG_LEN"
if [ "$SLOWLOG_LEN" -gt 0 ]; then
echo " 最近5条慢查询:"
$REDIS_CMD SLOWLOG GET 5 2>/dev/null | while read line; do
echo " $line"
done
fi
echo ""
# 9. 优化建议汇总
echo "【9. 优化建议汇总】"
echo " 1. 内存优化:"
echo " - 设置maxmemory限制最大内存使用"
echo " - 选择合适的淘汰策略(allkeys-lru推荐)"
echo " - 定期执行 --bigkeys 查找大key"
echo " 2. 性能优化:"
echo " - 使用pipeline减少网络往返"
echo " - 避免使用KEYS命令,改用SCAN"
echo " - 大对象考虑拆分或压缩"
echo " 3. 持久化优化:"
echo " - 启用AOF持久化,appendfsync设为everysec"
echo " - RDB和AOF同时使用,兼顾性能和安全"
echo " 4. 高可用:"
echo " - 配置主从复制"
echo " - 使用Sentinel或Cluster实现高可用"
echo " - 定期备份数据"
echo ""
echo "========== 监控完成 =========="
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "REDIS_HOST", "label": "Redis\u4e3b\u673a", "default": "127.0.0.1"}, {"name": "REDIS_PORT", "label": "Redis\u7aef\u53e3", "default": "6379"}, {"name": "REDIS_PASS", "label": "\u5bc6\u7801", "default": ""}]