如何用PromQL和node-exporter查询服务器内存峰值?含API调用问题
解决PromQL内存峰值查询的语法错误及curl调用方案
错误原因
你遇到的PromQL语法错误,核心原因是**max_over_time函数要求参数为范围向量(Range Vector),而你直接在计算后的即时向量(Instant Vector)上添加时间范围[1m]**。PromQL规则里,只有原始指标选择器(如node_memory_MemTotal_bytes{instance="xxx"})能直接加时间范围生成范围向量;计算后的表达式需要通过子查询语法(表达式)[范围:步长]转换成范围向量,才能传入max_over_time。
方案1:用query API获取近1分钟内存峰值
正确PromQL
先计算每个时刻的内存使用量(总内存 - 空闲+缓存+缓冲内存),再通过子查询生成近1分钟的范围向量,最后求最大值:
max_over_time( (node_memory_MemTotal_bytes{instance="epgp003:9401"} - node_memory_MemFree_bytes{instance="epgp003:9401"} - node_memory_Cached_bytes{instance="epgp003:9401"} - node_memory_Buffers_bytes{instance="epgp003:9401"})[1m:] )
注:
[1m:]中的步长省略时,会使用Prometheus默认的评估间隔;也可以指定步长如[1m:15s],表示每15秒采样一次近1分钟的数据。
对应的curl命令
使用-g参数避免URL转义问题,直接执行:
curl -X POST -g 'http://epgt012:9070/api/v1/query?query=max_over_time((node_memory_MemTotal_bytes{instance="epgp003:9401"}-node_memory_MemFree_bytes{instance="epgp003:9401"}-node_memory_Cached_bytes{instance="epgp003:9401"}-node_memory_Buffers_bytes{instance="epgp003:9401"})[1m:])'
方案2:用query_range API获取指定时间区间的内存峰值
两种实现方式
方式一:直接获取区间内的峰值(由Prometheus计算)
通过query API结合时间范围查询,指定区间的结束时间time,并设置子查询的范围为区间时长:
# 替换start_timestamp、end_timestamp为实际时间戳(单位:秒) curl -X POST -g 'http://epgt012:9070/api/v1/query?query=max_over_time((node_memory_MemTotal_bytes{instance="epgp003:9401"}-node_memory_MemFree_bytes{instance="epgp003:9401"}-node_memory_Cached_bytes{instance="epgp003:9401"}-node_memory_Buffers_bytes{instance="epgp003:9401"})[$((end_timestamp - start_timestamp))s:])&time=end_timestamp'
方式二:获取区间内所有采样点,客户端自行计算峰值
如果需要查看区间内内存使用的变化趋势,同时计算峰值,用query_range API返回每个采样点的内存使用量:
# 替换start、end、step为实际值(step为采样间隔,单位:秒) curl -X POST -g 'http://epgt012:9070/api/v1/query_range?query=node_memory_MemTotal_bytes{instance="epgp003:9401"}-node_memory_MemFree_bytes{instance="epgp003:9401"}-node_memory_Cached_bytes{instance="epgp003:9401"}-node_memory_Buffers_bytes{instance="epgp003:9401"}&start=1690000000&end=1690003600&step=60s'
返回结果中包含每个step的内存使用值,你可以在客户端提取这些值并计算最大值。
优化建议
如果你的node-exporter版本≥0.16.0,可以用node_memory_MemAvailable_bytes简化内存使用量的计算,这个指标已经包含了空闲、缓存、缓冲等可回收内存,结果更准确:
max_over_time( (node_memory_MemTotal_bytes{instance="epgp003:9401"} - node_memory_MemAvailable_bytes{instance="epgp003:9401"})[1m:] )
内容的提问来源于stack exchange,提问作者user1876484
相关产品推荐
相关产品推荐

