在分布式业务场景中,多个Redis实例通常承担不同的业务模块存储任务,单个实例负载过高可能导致响应延迟、连接超时甚至服务不可用,因此统一监控所有Redis实例的负载情况是运维和开发环节的重要工作。

需要关注的Redis多实例负载核心指标
监控Redis多实例负载时,首先要明确需要采集的核心指标,这些指标能直接反映实例的运行状态和负载压力:
- 内存使用率:实例已用内存占总配置内存的比例,内存使用过高可能触发键淘汰甚至OOM
- CPU使用率:Redis单线程模型下,CPU过高会导致命令处理延迟上升
- 连接数:当前客户端连接数,连接数过高可能占用过多资源
- QPS:每秒处理的命令数,反映实例的请求压力
- 键数量:实例中存储的键总数,键数量过多可能影响持久化效率
多实例负载监控的实现方案
方案一:基于Redis原生命令采集
Redis自带INFO命令可以返回实例的所有运行信息,我们可以通过该命令批量采集多个实例的指标,再统一汇总展示。以下是Python实现的批量采集示例:
import redis
import time
# 定义所有需要监控的Redis实例配置,格式为(主机,端口,密码,None表示无密码)
redis_instances = [
("127.0.0.1", 6379, None),
("127.0.0.1", 6380, "redis_pwd_123"),
("192.168.0.1", 6379, None)
]
def get_instance_load(instance_config):
"""采集单个Redis实例的负载指标"""
host, port, password = instance_config
try:
# 创建Redis连接
client = redis.Redis(host=host, port=port, password=password, decode_responses=True)
# 执行INFO命令获取所有信息
info = client.info()
# 提取核心负载指标
load_data = {
"host": host,
"port": port,
"memory_used": info.get("used_memory", 0),
"memory_total": info.get("total_system_memory", 1),
"cpu_usage": info.get("used_cpu_sys", 0) + info.get("used_cpu_user", 0),
"connected_clients": info.get("connected_clients", 0),
"qps": info.get("instantaneous_ops_per_sec", 0),
"keys_num": sum(info.get(f"db{i}", {}).get("keys", 0) for i in range(16))
}
# 计算内存使用率
load_data["memory_usage_rate"] = round(load_data["memory_used"] / load_data["memory_total"] * 100, 2) if load_data["memory_total"] > 0 else 0
return load_data
except Exception as e:
return {"host": host, "port": port, "error": str(e)}
def monitor_all_instances():
"""监控所有Redis实例并输出结果"""
print("开始采集Redis多实例负载数据...")
for instance in redis_instances:
data = get_instance_load(instance)
if "error" in data:
print(f"实例 {data['host']}:{data['port']} 采集失败,错误:{data['error']}")
else:
print(f"实例 {data['host']}:{data['port']} 负载情况:")
print(f" 内存使用率:{data['memory_usage_rate']}%")
print(f" CPU使用率:{round(data['cpu_usage'], 2)}%")
print(f" 连接数:{data['connected_clients']}")
print(f" QPS:{data['qps']}")
print(f" 键数量:{data['keys_num']}")
print("-" * 50)
if __name__ == "__main__":
monitor_all_instances()方案二:基于Prometheus+Grafana搭建可视化监控
如果需要长期监控和可视化展示,可以使用Redis Exporter将实例指标暴露给Prometheus采集,再通过Grafana配置仪表盘统一展示所有实例的负载情况。常用的Redis Exporter可以同时对接多个Redis实例,只需要在启动时配置所有实例的地址即可。
启动Redis Exporter的示例命令如下,多个实例用逗号分隔:
# 启动Redis Exporter,监控三个实例 ./redis_exporter --redis.addr="redis://127.0.0.1:6379,redis://127.0.0.1:6380,redis://192.168.0.1:6379" --redis.password="redis_pwd_123"
Prometheus的配置文件prometheus.yml中添加如下采集任务:
scrape_configs:
- job_name: 'redis_multi_instance'
static_configs:
- targets: ['localhost:9121'] # Redis Exporter的默认端口负载异常告警配置
监控的同时还需要配置异常告警,当某个实例的负载指标超过阈值时及时通知负责人。以下是基于Python的简单告警判断逻辑,可以集成到上面的采集脚本中:
def check_load_alert(load_data):
"""检查负载是否超过阈值,超过则返回告警信息"""
alerts = []
# 内存使用率超过80%告警
if load_data.get("memory_usage_rate", 0) > 80:
alerts.append(f"内存使用率过高:{load_data['memory_usage_rate']}%")
# CPU使用率超过70%告警
if load_data.get("cpu_usage", 0) > 70:
alerts.append(f"CPU使用率过高:{round(load_data['cpu_usage'], 2)}%")
# 连接数超过1000告警
if load_data.get("connected_clients", 0) > 1000:
alerts.append(f"连接数过高:{load_data['connected_clients']}")
# QPS超过5000告警
if load_data.get("qps", 0) > 5000:
alerts.append(f"QPS过高:{load_data['qps']}")
return alerts
# 集成到监控逻辑中
def monitor_all_instances_with_alert():
for instance in redis_instances:
data = get_instance_load(instance)
if "error" in data:
print(f"实例 {data['host']}:{data['port']} 采集失败,错误:{data['error']}")
else:
alerts = check_load_alert(data)
if alerts:
print(f"实例 {data['host']}:{data['port']} 触发告警:")
for alert in alerts:
print(f" - {alert}")
else:
print(f"实例 {data['host']}:{data['port']} 负载正常")
print("-" * 50)注意事项
在监控Redis多实例时,还需要注意以下几点:
- 采集频率不要设置过高,避免采集命令本身对Redis实例造成额外负载,通常1分钟采集一次即可
- 对于密码不同的实例,需要在Exporter或采集脚本中单独配置对应密码
- 如果实例部署在不同的网络区域,要确保监控服务能正常访问所有实例的端口
- 定期清理监控历史数据,避免存储资源占用过高