一、为什么要做集群监控告警

不管是个人做的小项目,还是企业级的大业务,只要用到集群来承载服务,最怕的就是节点突然“罢工”——比如某个存储数据的节点挂了,导致数据查不出来;或者节点性能不够,跑任务的时候卡成PPT,最后用户投诉、业务中断。 集群监控告警的核心作用,就是帮你提前发现问题,不用等用户找上门才知道出了状况。而TDengine作为专门做时序数据存储的数据库,经常被用来存监控数据、物联网数据这类时间序列的内容,它的集群节点健康和性能好坏,直接影响整个业务的运行。所以给TDengine搭一套靠谱的监控告警体系,是很多开发者绕不开的事。

二、TDengine节点健康检查的核心内容

要监控TDengine集群,第一步得知道节点是不是“活着”、能不能正常工作,也就是做健康检查。健康检查不用搞太复杂,核心看两个方面:节点能不能正常连接、能不能完成基础的读写操作。

2.1 节点连接状态检查

这是最基础的检查,相当于给TDengine节点打个电话,看能不能打通。TDengine本身提供了客户端命令行工具taos,我们可以用这个工具来测试连接。 这里统一用Shell脚本作为技术栈,所有示例都围绕Shell来写,方便在服务器上直接运行。 比如写一个简单的连接测试脚本,代码如下:

#!/bin/bash
# 定义TDengine节点的IP和端口,默认端口是6030
TD_NODE_IP="192.168.1.100"
TD_PORT="6030"
# 用taos命令测试连接,加-q参数是执行完命令后退出,不进入交互模式
taos -h $TD_NODE_IP -P $TD_PORT -q "SELECT 1;"
# 检查上一条命令的返回值,0代表成功,非0代表失败
if [ $? -eq 0 ]; then
    echo "节点$TD_NODE_IP:$TD_PORT 连接正常"
else
    echo "节点$TD_NODE_IP:$TD_PORT 连接失败"
fi

这个脚本的逻辑很简单,就是用taos客户端连接指定的TDengine节点,执行一个最简单的查询语句“SELECT 1;”,如果能执行成功,说明连接没问题,否则就是节点连不上。

2.2 节点基础读写能力检查

光能连接还不够,还得看节点能不能正常存数据、读数据,毕竟TDengine的核心功能就是读写时序数据。比如可以测试往节点里的一个临时表写一条数据,再读出来,看能不能对应上。 示例脚本如下:

#!/bin/bash
TD_NODE_IP="192.168.1.100"
TD_PORT="6030"
# 定义测试用的数据库和表,这里临时用test_db和test_table
TEST_DB="test_db"
TEST_TABLE="test_table"
# 先创建测试数据库,如果已经存在就忽略(-q参数是静默执行)
taos -h $TD_NODE_IP -P $TD_PORT -q "CREATE DATABASE IF NOT EXISTS $TEST_DB;"
# 切换到测试数据库,创建测试表(如果不存在)
taos -h $TD_NODE_IP -P $TD_PORT -q "USE $TEST_DB; CREATE TABLE IF NOT EXISTS $TEST_TABLE (ts TIMESTAMP, value INT);"
# 写测试数据,ts用当前时间,value用123
taos -h $TD_NODE_IP -P $TD_PORT -q "USE $TEST_DB; INSERT INTO $TEST_TABLE VALUES (NOW(), 123);"
# 读刚才写的数据,判断是否存在
READ_RESULT=$(taos -h $TD_NODE_IP -P $TD_PORT -q "USE $TEST_DB; SELECT value FROM $TEST_TABLE WHERE value=123;")
# 检查读取结果,如果包含123,说明读写正常
if [[ $READ_RESULT == *"123"* ]]; then
    echo "节点$TD_NODE_IP:$TD_PORT 读写正常"
else
    echo "节点$TD_NODE_IP:$TD_PORT 读写异常"
fi

这个脚本先创建测试用的库和表,然后写一条数据,再读出来验证,整个过程模拟了TDengine的基础业务操作,能更准确地判断节点的健康状态。

三、TDengine性能指标采集的关键指标

健康检查是看节点“有没有病”,性能指标采集是看节点“病得重不重、为什么病”。TDengine的性能指标主要包括CPU、内存、磁盘、网络这几个常用维度,还有TDengine自身的业务指标,比如读写延迟、连接数、磁盘使用率这些。

3.1 系统级性能指标采集

系统级指标是指节点所在服务器的硬件资源使用情况,比如CPU使用率、内存使用率、磁盘IO这些,这些指标能反映节点的运行环境好不好。 采集系统级指标可以用Shell脚本结合Linux自带的命令,比如top、free、df、iostat这些。示例如下:

#!/bin/bash
TD_NODE_IP="192.168.1.100"
# 采集CPU使用率,top命令-b是批量模式,-n1是执行一次,grep取CPU行,awk提取使用率
CPU_USAGE=$(top -b -n1 | grep "Cpu(s)" | awk '{print $2 + $4}')
# 采集内存使用率,free -h是人类可读格式,grep取Mem行,awk提取使用率
MEM_USAGE=$(free -h | grep Mem | awk '{print $3/$2 * 100}')
# 采集TDengine数据目录的磁盘使用率,假设数据目录是/var/lib/taos
DISK_USAGE=$(df -h /var/lib/taos | grep /var/lib/taos | awk '{print $5}' | tr -d '%')
# 输出采集到的指标
echo "节点$TD_NODE_IP 采集的性能指标:"
echo "CPU使用率:$CPU_USAGE%"
echo "内存使用率:$MEM_USAGE%"
echo "磁盘使用率:$DISK_USAGE%"

这个脚本采集了CPU、内存、磁盘三个核心指标,这些指标是判断节点性能的基础。比如CPU使用率超过80%,说明节点可能负载过高;磁盘使用率超过90%,可能会导致数据写不进去。

3.2 TDengine业务级指标采集

除了系统级指标,还要采集TDengine自身的业务指标,比如当前连接数、读写延迟、存储文件大小这些,这些指标更直接反映TDengine的运行状态。 TDengine的管理命令可以查询这些指标,比如用“SHOW CONNECTIONS”查询当前连接数,用“SHOW DATABASES”查询数据库的存储大小。示例如下:

#!/bin/bash
TD_NODE_IP="192.168.1.100"
TD_PORT="6030"
# 采集当前连接数,SHOW CONNECTIONS返回的结果中,行数就是连接数(去掉表头)
CONNECTIONS=$(taos -h $TD_NODE_IP -P $TD_PORT -q "SHOW CONNECTIONS;" | grep -v "ts" | wc -l)
# 采集测试数据库的存储大小,SHOW DATABASES返回的size字段就是存储大小
DB_SIZE=$(taos -h $TD_NODE_IP -P $TD_PORT -q "SHOW DATABASES;" | grep "test_db" | awk '{print $4}')
# 采集最近10次写操作的平均延迟,这里模拟采集,实际可以通过TDengine的日志或监控接口获取
WRITE_DELAY=$(taos -h $TD_NODE_IP -P $TD_PORT -q "USE test_db; SELECT AVG(ts_diff) FROM (SELECT ts - LAG(ts) OVER (ORDER BY ts) AS ts_diff FROM test_table ORDER BY ts DESC LIMIT 10);" | awk '{print $2}')
# 输出业务指标
echo "节点$TD_NODE_IP 业务指标:"
echo "当前连接数:$CONNECTIONS"
echo "test_db存储大小:$DB_SIZE"
echo "最近10次写平均延迟:$WRITE_DELAY 毫秒"

这个脚本采集了TDengine的连接数、数据库存储大小、写延迟三个核心业务指标,这些指标能反映TDengine的负载情况和性能瓶颈。比如连接数过多,可能会导致节点响应变慢;写延迟过高,说明节点的写入性能有问题。

四、集群监控告警体系的搭建流程

采集到健康状态和性能指标后,还要把这些数据集中起来,设置告警规则,才能形成完整的监控告警体系。

4.1 指标数据的集中存储

采集到的指标数据,要存到一个地方,方便后续查看和分析。因为这些指标本身也是时序数据,所以可以存到TDengine自己的集群里,形成“用TDengine监控TDengine”的闭环。 比如把采集到的CPU、内存、磁盘、连接数这些指标,存到TDengine的一个专门的监控数据库里,示例如下:

#!/bin/bash
TD_NODE_IP="192.168.1.100"
TD_PORT="6030"
MONITOR_DB="monitor_db"
# 创建监控数据库,如果不存在
taos -h $TD_NODE_IP -P $TD_PORT -q "CREATE DATABASE IF NOT EXISTS $MONITOR_DB;"
# 创建监控表,用来存储节点的性能指标
taos -h $TD_NODE_IP -P $TD_PORT -q "USE $MONITOR_DB; CREATE TABLE IF NOT EXISTS node_metrics (ts TIMESTAMP, node_ip VARCHAR(20), cpu_usage FLOAT, mem_usage FLOAT, disk_usage FLOAT, connections INT, write_delay FLOAT);"
# 把采集到的指标插入到监控表中,假设之前采集的指标已经赋值给变量
CPU_USAGE=75.5
MEM_USAGE=68.2
DISK_USAGE=82
CONNECTIONS=120
WRITE_DELAY=25.3
taos -h $TD_NODE_IP -P $TD_PORT -q "USE $MONITOR_DB; INSERT INTO node_metrics VALUES (NOW(), '$TD_NODE_IP', $CPU_USAGE, $MEM_USAGE, $DISK_USAGE, $CONNECTIONS, $WRITE_DELAY);"

这个脚本创建了专门的监控数据库和表,把采集到的指标插入到表中,这样就可以通过查询监控表来查看节点的历史性能数据。

4.2 告警规则的设置

告警规则就是设置一个阈值,当指标超过这个阈值时,就触发告警。比如CPU使用率超过80%、内存使用率超过90%、磁盘使用率超过85%、连接数超过200、写延迟超过50毫秒,这些都可以设置为告警阈值。 告警规则可以通过Shell脚本结合TDengine的查询来实现,示例如下:

#!/bin/bash
TD_NODE_IP="192.168.1.100"
TD_PORT="6030"
MONITOR_DB="monitor_db"
# 设置告警阈值
CPU_THRESHOLD=80
MEM_THRESHOLD=90
DISK_THRESHOLD=85
CONNECTIONS_THRESHOLD=200
WRITE_DELAY_THRESHOLD=50
# 查询最近一次采集的指标
LAST_METRICS=$(taos -h $TD_NODE_IP -P $TD_PORT -q "USE $MONITOR_DB; SELECT cpu_usage, mem_usage, disk_usage, connections, write_delay FROM node_metrics WHERE node_ip='$TD_NODE_IP' ORDER BY ts DESC LIMIT 1;")
# 提取指标值,这里用awk按空格分割,提取对应的字段
CPU_USAGE=$(echo $LAST_METRICS | awk '{print $2}')
MEM_USAGE=$(echo $LAST_METRICS | awk '{print $3}')
DISK_USAGE=$(echo $LAST_METRICS | awk '{print $4}')
CONNECTIONS=$(echo $LAST_METRICS | awk '{print $5}')
WRITE_DELAY=$(echo $LAST_METRICS | awk '{print $6}')
# 检查每个指标是否超过阈值,触发告警
if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
    echo "告警:节点$TD_NODE_IP CPU使用率$CPU_USAGE%超过阈值$CPU_THRESHOLD%"
fi
if (( $(echo "$MEM_USAGE > $MEM_THRESHOLD" | bc -l) )); then
    echo "告警:节点$TD_NODE_IP 内存使用率$MEM_USAGE%超过阈值$MEM_THRESHOLD%"
fi
if (( $(echo "$DISK_USAGE > $DISK_THRESHOLD" | bc -l) )); then
    echo "告警:节点$TD_NODE_IP 磁盘使用率$DISK_USAGE%超过阈值$DISK_THRESHOLD%"
fi
if (( $CONNECTIONS > $CONNECTIONS_THRESHOLD )); then
    echo "告警:节点$TD_NODE_IP 连接数$CONNECTIONS超过阈值$CONNECTIONS_THRESHOLD"
fi
if (( $(echo "$WRITE_DELAY > $WRITE_DELAY_THRESHOLD" | bc -l) )); then
    echo "告警:节点$TD_NODE_IP 写延迟$WRITE_DELAY毫秒超过阈值$WRITE_DELAY毫秒"
fi

这个脚本先查询最近一次采集的指标,然后和预设的阈值比较,超过阈值就输出告警信息。实际使用中,可以把告警信息发送到企业微信、钉钉、邮件等渠道,方便开发者及时收到通知。

4.3 监控告警的自动化运行

为了让监控告警持续运行,不用手动执行脚本,可以用Linux的定时任务工具crontab来实现。比如每5分钟执行一次健康检查和指标采集,每10分钟执行一次告警规则检查。 示例如下:

# 编辑crontab任务,-e是编辑,-u root是指定用户(可以根据实际情况修改)
crontab -u root -e
# 在crontab中添加以下内容,每5分钟执行一次健康检查脚本
*/5 * * * * /bin/bash /opt/scripts/health_check.sh >> /var/log/health_check.log 2>&1
# 每5分钟执行一次指标采集脚本
*/5 * * * * /bin/bash /opt/scripts/metrics_collect.sh >> /var/log/metrics_collect.log 2>&1
# 每10分钟执行一次告警检查脚本
*/10 * * * * /bin/bash /opt/scripts/alert_check.sh >> /var/log/alert_check.log 2>&1

这样设置后,系统就会自动定时执行这些脚本,实现监控告警的自动化。

五、应用场景、技术优缺点与注意事项

5.1 应用场景

这套监控告警体系适用于所有使用TDengine集群的场景,比如物联网数据采集平台、服务器监控平台、时序数据存储业务等。比如物联网平台需要实时采集设备的温度、湿度、电量等数据,TDengine集群用来存储这些数据,这套监控体系可以及时发现TDengine节点的异常,保证数据的正常采集和存储;再比如企业的服务器监控平台,用TDengine存储服务器的CPU、内存、磁盘等监控数据,这套体系可以监控TDengine集群的运行状态,保证监控平台自身的稳定。

5.2 技术优缺点

优点方面,这套体系用Shell脚本实现,简单易用,不需要额外安装复杂的监控工具,适合中小规模的TDengine集群;用TDengine自己存储监控数据,形成闭环,不需要额外的存储系统,降低了维护成本;可以根据实际需求灵活调整健康检查的内容、指标采集的维度和告警的阈值,灵活性高。 缺点方面,Shell脚本的扩展性有限,对于大规模的TDengine集群,比如上百个节点的集群,脚本的维护成本会比较高;没有可视化的界面,只能通过日志或命令行查看指标和告警,不够直观;告警渠道比较单一,只能通过脚本输出告警信息,需要额外开发对接企业微信、钉钉等渠道。

5.3 注意事项

首先,要保证TDengine的客户端taos命令能正常使用,不同版本的TDengine客户端可能有差异,要保证客户端版本和集群版本一致;其次,要给脚本设置正确的权限,比如执行脚本的用户要有权限访问TDengine节点、有读写日志文件的权限;第三,要合理设置定时任务的时间间隔,间隔太短会增加节点的负载,间隔太长会导致告警不及时;第四,要定期清理监控数据,避免监控数据占用过多的磁盘空间;第五,要根据实际业务调整告警阈值,比如业务高峰期的CPU使用率可能会比较高,阈值可以适当调高,避免频繁触发告警。

六、文章总结

给TDengine集群搭建监控告警体系,核心就是做两件事:健康检查和性能指标采集。健康检查保证节点能正常工作,性能指标采集反映节点的运行状态,然后通过集中存储指标、设置告警规则、自动化运行,形成完整的监控告警体系。这套体系适合中小规模的TDengine集群,简单易用,灵活可扩展,能有效提前发现集群的异常,保证业务的稳定运行。对于大规模的集群,可以在这套体系的基础上,结合Prometheus、Grafana等监控工具,实现更强大的监控和可视化功能。