本文目的
夜莺推荐使用Categraf作为数据采集器,然而Catefraf截止目前提供了关于redis单实例跟哨兵模式的监控配置,但并没有针对Cluster分片集群提供专门的配置,不信看categraf官方介绍。
虽然可以通过增加instances 的方式监控多个redis实例,但监控指标还是针对单实例的方式。对于cluster分片集群,比如经常需要关注的集群是否正常(对应redis命令cluster info
输出的cluster_state值信息)以及集群中节点情况(对应redis命令cluster nodes
输出信息)如节点角色?主从对应关系如何?哈希槽是否有丢失?节点状态是否正常等?categraf并没有提供相应的监控指标,那如何才能借助categraf实现对这些信息的监控及告警,这是本文的目的,当然可能也还有考虑不周的情况,也欢迎各位老板多留言提意见。
exec插件exec.toml文件配置
这个配置文件定义了exec插件定期执行集群状态检查脚本文件:/opt/categraf/scripts/redis_cluster_status.sh
及集群节点状态检查脚本文件:redis_cluster_nodes.sh,并且输出的数据格式为influx
格式。
# # collect interval
# interval = 15
[[instances]]
# # commands, support glob
commands = [
"/opt/categraf/scripts/check_password_expiry.sh",
"/opt/categraf/scripts/redis_cluster_status.sh",
"/opt/categraf/scripts/redis_cluster_nodes.sh"
]
# # timeout for each command to complete
# timeout = 5
# # interval = global.interval * interval_times
# interval_times = 1
# # choices: influx prometheus falcon
# # influx stdout example: mesurement,labelkey1=labelval1,labelkey2=labelval2 field1=1.2,field2=2.3
data_format = "influx"
说明:/opt/categraf/scripts/check_password_expiry.sh脚本是利用exec插件对Linux主机系统用户及密码有效期进行监控及告警的实现,前面已经介绍过。
关于influx格式及格式说明:
mesurement,labelkey1=labelval1,labelkey2=labelval2 field1=1.2,field2=2.3
mesurement
,定义指标名称(或者前缀),比如 connections;mesurement
后面是逗号,逗号后面是标签,如果没有标签,则mesurement后面不需要逗号标签
是k=v的格式,多个标签用逗号分隔,比如region=beijing,env=test标签
之后是空格空格
之后是属性字段,多个属性字段用逗号分隔属性
字段是字段名=值
的格式,在categraf里值只能是数字
最终,mesurement
和各个属性字段名称
拼接成metric名字
监控集群状态脚本redis_cluster_status.sh
#!/bin/bash
#此脚本通过获取redis cluster集群状态cluster_state值并检查是否为ok判断集群是否正常,并以influx格式输出检查结果
# 定义Redis集群节点信息
redis_basedir=/opt/redis/8900/bin/redis-cli
redis_node=10.10.10.110
port=8900
password=123456
# 获取cluster info输出并提取cluster_state
cluster_status=$($redis_basedir -c -h $redis_node -p $port -a $password cluster info 2>/dev/null | grep 'cluster_state' | awk -F: '{print $2}' | tr -d '\r')
# 根据cluster_status的值赋值为1(表示集群正常)或0(表示集群异常)
if [[ "$cluster_status" = "ok" ]]; then
status_value=1
else
status_value=0
fi
# 输出结果
echo "redis_cluster,cluster=redis_cluster status_value=$status_value"
**注意:**脚本执行输出结果一定要满足前面exec.toml配置文件中定义的data_format = "influx"
数据格式,这样categraf截获的stdout内容,才能成功解析并传给服务端,上述脚本执行输出如下:
[root@redis1 categraf]# ./categraf --test --inputs exec | grep redis_cluster_status_value
......
18:25:57 redis_cluster_status_value agent_hostname=redis1-10.10.10.110 cluster=redis_cluster 1
......
监控集群节点状态脚本redis_cluster_nodes.sh
#!/bin/bash
#此脚本通过cluster nodes命令获取redis cluster集群节点状态信息并以influx数据格式输出如下关键信息以判断集群节点是否正常
#1、提取节点ID信息node_id、节点地址信息host、节点角色信息flags_value、节点连接状态信息link_state以及节点哈希槽位信息slots_value
#2、判断集群中节点连接状态是否为正常的connected
#3、对于节点角色信息flags有多个值的情况,中间用&符合连接,以满足influx数据格式
#4、对于节点槽位信息slots有多个值的情况,中间用&符合连接,以满足influx数据格式
# 定义Redis集群节点信息
redis_basedir=/opt/redis/8900/bin/redis-cli
redis_node=10.10.10.110
port=8900
password=123456
# 获取cluster nodes输出
cluster_nodes=$($redis_basedir -c -h $redis_node -p $port -a $password cluster nodes 2>/dev/null)
# 解析cluster nodes输出
echo "$cluster_nodes" | while IFS= read -r line; do
# 提取节点信息
id=$(echo $line | awk '{print $1}')
ip_port=$(echo $line | awk '{print $2}' | cut -d@ -f1)
flags=$(echo $line | awk '{print $3}')
link_state=$(echo $line | awk '{print $8}')
slots=$(echo $line | awk '{for (i=9; i<=NF; i++) printf "%s ", $i; print ""}' | sed 's/ $//')
# 判断节点状态,根据link_state的值赋值为1(表示集群中节点状态正常)或0(表示集群中节点状态异常)
if [[ "$link_state" == "connected" ]]; then
node_status=1
else
node_status=0
fi
# 对于节点角色信息flags有多个值的情况,中间用&符合连接,以满足influx数据格式
flags_value=$(echo $flags | tr ', ' '&')
# 格式化 slots 字段,如果是slave节点,则槽位赋值为null,如果为master节点则输出实际值,同时使用&符号代替空格符号连接多个分散槽位的情况,这也是为了满足influx数据格式
if [[ -z "$slots" ]]; then
slots_value="null"
else
slots_value=$(echo $slots | tr ' ' '&')
fi
# 输出InfluxDB格式的数据
echo "redis_cluster,host=$ip_port,flags_value=$flags_value,node_id=$id,link_state=$link_state,slots_value=$slots_value node_status=$node_status"
done
**注意:**这里脚本执行输出结果也一定要满足前面exec.toml配置文件中定义的data_format = "influx"
数据格式,上述脚本执行输出如下:
[root@redis1 categraf]# ./categraf --test --inputs exec | grep redis_cluster_node_status
......
18:25:57 redis_cluster_node_status agent_hostname=redis1-10.10.10.110 flags_value=master host=10.10.10.112:8900 link_state=connected node_id=b3d9e3b8aca2c1bc9a936dfe41b492907531a4a3 slots_value=10923-16383 1
18:25:57 redis_cluster_node_status agent_hostname=redis1-10.10.10.110 flags_value=master host=10.10.10.111:8900