Prometheus是一个开源监控系统和时间序列数据库。Prometheus最重要的一个方面是它的多维数据模型以及随附的查询语言。此查询语言允许您对维度数据进行切片和切块,以便以临时方式回答操作问题,在仪表板中显示趋势,或生成有关系统故障的警报。
在本教程中,我们将学习如何查询Prometheus 1.3.1。为了使用适合的示例数据,我们将设置三个相同的演示服务实例,用于导出各种合成度量。然后,我们将设置一个Prometheus服务器来抓取并存储这些指标。使用示例指标,我们将学习如何查询Prometheus,从简单查询开始,然后转到更高级的查询。
在本教程之后,您将了解如何根据维度,聚合和转换时间序列选择和过滤时间序列,以及如何在不同指标之间进行算术运算。在后续教程中,我们将基于本教程中的知识来介绍更高级的查询用例。
要学习本教程,您需要:
在此步骤中,我们将下载,配置和运行Prometheus服务器以刮取三个(尚未运行的)演示服务实例。
首先,下载Prometheus:
wget https://github.com/prometheus/prometheus/releases/download/v1.3.1/prometheus-1.3.1.linux-amd64.tar.gz
提取tarball:
tar xvfz prometheus-1.3.1.linux-amd64.tar.gz
在~/prometheus.yml
上的主机文件系统上创建一个最小的Prometheus配置文件:
nano ~/prometheus.yml
将以下内容添加到文件中:
# Scrape the three demo service instances every 5 seconds.
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'demo'
static_configs:
- targets:
- 'localhost:8080'
- 'localhost:8081'
- 'localhost:8082'
保存并退出nano。
此示例配置使Prometheus刮掉了演示实例。Prometheus使用拉模型,这就是为什么需要配置它来了解从中提取指标的端点。演示实例尚未运行,但将在端口8080
,8081
,8082
更高版本运行。
使用nohup
和作为后台进程启动Prometheus :
nohup ./prometheus-1.3.1.linux-amd64/prometheus -storage.local.memory-chunks=10000 &
将nohup
在命令开始发送输出到文件~/nohup.out
,而不是stdout
。在命令结束时&
将使这个进程继续在后台运行,同时给你的其他的命令提示符后面。要使进程返回到前台(即,返回到终端的运行进程),请使用在同一终端上的fg
命令。
如果一切顺利,在~/nohup.out
文件中,您应该看到类似于以下内容的输出:
time="2016-11-23T03:10:33Z" level=info msg="Starting prometheus (version=1.3.1, branch=master, revision=be476954e80349cb7ec3ba6a3247cd712189dfcb)" source="main.go:75"
time="2016-11-23T03:10:33Z" level=info msg="Build context (go=go1.7.3, user=root@37f0aa346b26, date=20161104-20:24:03)" source="main.go:76"
time="2016-11-23T03:10:33Z" level=info msg="Loading configuration file prometheus.yml" source="main.go:247"
time="2016-11-23T03:10:33Z" level=info msg="Loading series map and head chunks..." source="storage.go:354"
time="2016-11-23T03:10:33Z" level=info msg="0 series loaded." source="storage.go:359"
time="2016-11-23T03:10:33Z" level=warning msg="No AlertManagers configured, not dispatching any alerts" source="notifier.go:176"
time="2016-11-23T03:10:33Z" level=info msg="Starting target manager..." source="targetmanager.go:76"
time="2016-11-23T03:10:33Z" level=info msg="Listening on :9090" source="web.go:240"
在另一个终端中,您可以使用tail -f ~/nohup.out
命令监视此文件的内容。当内容写入文件时,它将显示给终端。
默认情况下,Prometheus将从prometheus.yml
(我们刚刚创建的)加载其配置并将其度量数据存储在当前工作目录中的./data
中。
-storage.local.memory-chunks
标志将Prometheus的内存使用量调整为主机系统的极少量RAM(仅512MB)和本教程中存储的少量时间序列。
您现在应该可以访问http://your_server_ip:9090/
的Prometheus服务器了。通过在“ 目标”部分中指向http://your_server_ip:9090/status
并找到demo
作业的三个目标端点,验证它是否已配置为从三个演示实例中收集指标。所有三个目标的State列应该将目标的状态显示为DOWN,因为演示实例尚未启动,因此无法删除:
在本节中,我们将安装并运行三个演示服务实例。
下载演示服务:
wget https://github.com/juliusv/prometheus_demo_service/releases/download/0.0.4/prometheus_demo_service-0.0.4.linux-amd64.tar.gz
提取它:
tar xvfz prometheus_demo_service-0.0.4.linux-amd64.tar.gz
在不同的端口上运行演示服务三次:
./prometheus_demo_service -listen-address=:8080 &
./prometheus_demo_service -listen-address=:8081 &
./prometheus_demo_service -listen-address=:8082 &
&
将在后台启动演示服务。他们不会记录任何内容,但他们会在各自端口上的/metrics
HTTP端点上公开Prometheus指标。
这些演示服务导出有关几个模拟子系统的综合指标。这些是:
各个指标在后面部分的查询示例中介绍。
Prometheus服务器现在应该自动开始抓取您的三个演示实例。前往Prometheus服务器的状态页面http://your_server_ip:9090/status``demo
,并验证作业的目标现在是否显示为UP状态:
在这一步中,我们将熟悉Prometheus的内置查询和图形Web界面。虽然此接口非常适合于关于Prometheus查询语言的临时数据探索和学习,但它不适合构建持久性仪表板,也不支持高级可视化功能。
转到Prometheus服务器http://your_server_ip:9090/graph
上。它应该如下所示:
如您所见,有两个选项卡:Graph和Console。Prometheus允许您以两种不同的模式查询数据:
由于Prometheus可以扩展到数百万个时间序列,因此可以构建非常昂贵的查询(将其视为类似于从SQL数据库中的大表中选择所有行)。为了避免超时或超载服务器的查询,建议首先在Console视图中开始探索和构建查询,而不是立即绘制它们。在单个时间点评估可能代价高昂的查询将比在一段时间内尝试绘制相同查询的资源少得多。
一旦您充分缩小了查询范围(根据它选择加载的系列,它需要执行的计算以及输出时间序列的数量),您就可以切换到图形选项卡以显示随时间推移的计算表达式。了解何时查询的价格足够便宜,并不是一个精确的科学,它取决于您的数据,延迟要求以及运行Prometheus服务器的机器的功能。随着时间的推移,你会有这种感觉。
由于我们的测试Prometheus服务器不会刮掉大量数据,因此我们实际上无法在本教程中制定任何代价高昂的查询。可以在“ 图形”和“ 控制台”视图中查看任何示例查询,而不会有任何风险。
要缩小或增加图形时间范围,请单击-或+按钮。要移动图形的结束时间,请按<<或>>按钮。您可以通过激活堆叠复选框来堆叠图形。最后,Res。(s)输入允许您指定自定义查询分辨率(本教程不需要)。
在我们开始查询之前,让我们快速回顾一下Prometheus的数据模型和术语。Prometheus从根本上将所有数据存储为时间序列。每个时间序列都由度量标准名称标识,以及Prometheus调用标签的一组键值对。度量标准名称表示正在测量的系统的整体方面(例如,自进程启动以来处理的HTTP请求的数量http_requests_total
)。标签用于区分度量的子维度,例如HTTP方法(例如method="POST"
)或路径(例如path="/api/foo"
)。最后,一系列样本形成一系列的实际数据。每个样本由时间戳和值组成,其中时间戳具有毫秒精度,值始终为64位浮点值。
我们可以制定的最简单的查询返回具有给定度量标准名称的所有系列。例如,演示服务导出一个度量demo_api_request_duration_seconds_count
,该度量表示虚拟服务处理的合成API HTTP请求的数量。您可能想知道为什么度量标准名称包含字符串duration_seconds
。这是因为此计数器是一个较大的直方图度量标准的一部分,该度量标准demo_api_request_duration_seconds
主要跟踪请求持续时间的分布,但也公开了跟踪请求的总计数(此处以_count
为后缀)作为有用的副产品。
确保选中“ 控制台查询”选项卡,在页面顶部的文本字段中输入以下查询,然后单击“ 执行”按钮以执行查询:
demo_api_request_duration_seconds_count
由于Prometheus正在监视三个服务实例,您应该看到一个表格输出,其中包含27个带有此度量标准名称的结果时间序列,每个跟踪服务实例一个,路径,HTTP方法和HTTP状态代码。除了由服务实例本身(设置标签method
,path
和status
),该系列将有适当的job
和instance
从彼此区分不同的服务实例的标签。当存储刮擦目标的时间序列时,Prometheus会自动附加这些标签。输出应如下所示:
右侧表格列中显示的数值是每个时间序列的当前值。可以随意绘制输出图形(单击“ 图形”选项卡并再次单击“ 执行”)以获取此查询和后续查询,以查看值随时间的变化情况。
我们现在可以添加标签匹配器,以根据标签限制返回的系列。标签匹配器直接遵循花括号中的度量标准名称。在最简单的形式中,它们过滤具有给定标签的精确值的系列。例如,此查询仅显示任何GET
请求的请求计数:
demo_api_request_duration_seconds_count{method="GET"}
匹配器可以使用逗号组合。例如,我们还可以仅从实例localhost:8080
和作业demo
中过滤指标:
demo_api_request_duration_seconds_count{instance="localhost:8080",method="GET",job="demo"}
结果将如下所示:
组合多个匹配器时,所有匹配器都需要匹配才能选择一个系列。上面的表达式仅返回在端口8080上运行的服务实例的API请求计数以及HTTP方法GET
所在的位置。我们还确保只选择属于该demo
职位的指标。
注意:建议在选择时间序列时始终指定标签job
。这可以确保您不会意外地从不同的工作中选择具有相同名称的指标(当然,除非这确实是您的目标!)。虽然我们仅在本教程中监视一个作业,但我们仍将在以下大多数示例中按作业名称进行选择,以强调此练习的重要性。
除了相等匹配,Prometheus还支持非相等匹配(!=
),正则表达式匹配(=~
)以及负正则表达式匹配(!~
)。也可以完全省略度量标准名称,仅使用标签匹配器进行查询。例如,要列出以/api
开头的path
标签所在的所有系列(无论是哪个度量标准名称或作业),您都可以运行此查询:
{path=~"/api.*"}
由于以.*
结尾的正则表达式始终与Prometheus中的完整字符串匹配,因此上述正则表达式需要结束。
生成的时间序列将是具有不同度量标准名称的系列的混合:
您现在知道如何根据其度量标准名称以及它们的标签值的组合来选择时间序列。
在本节中,我们将学习如何计算度量标准的速率或增量。
您将在Prometheus使用的最常用功能之一是rate()
。在Prometheus中,不是直接在仪表化服务中计算事件率,而是通常使用原始计数器跟踪事件并让Prometheus服务器在查询时间内临时计算费率(这具有许多优点,例如不会丢失率峰值刮擦之间,以及能够在查询时选择动态平均窗口)。计数器在受监视服务启动时从0
开始,并在服务进程的生命周期内持续递增。有时,当受监视的进程重新启动时,其计数器将重置为0
然后从那里再次开始攀爬。绘制原始计数器通常不是很有用,因为您只会看到不断增加的行,偶尔会重置。您可以通过绘制演示服务的API请求计数来查看:
demo_api_request_duration_seconds_count{job="demo"}
看起来有点像这样:
为了使计数器有用,我们可以使用该rate()
函数来计算它们的每秒增长率。我们需要告知rate()
通过在系列匹配器之后提供范围选择器来判断平均速率的时间窗口(如[5m]
)。例如,要计算上述计数器指标的每秒增量(如过去五分钟的平均值),请绘制以下查询:
rate(demo_api_request_duration_seconds_count{job="demo"}[5m])
结果现在更加有用:
rate()
是智能的,并通过假设计数器值的任何复位都是复位来自动调整计数器重设。
rate()
的一个变种是irate()
。虽然在给定时间窗口内rate()
平均了所有样本的速率(在这种情况下为5分钟),但irate()
只能回顾过去的两个样本。它仍然需要您指定一个时间窗口(如[5m]
),以了解这两个样本的最大回溯时间。irate()
将对速率变化做出更快的反应,因此通常建议用于图表。相反,rate()
将提供更平滑的速率,建议用于警报表达式(因为短时间的峰值会受到抑制而不会在夜间叫醒你)。
有了irate()
,上面的图表看起来像这样,在请求率中发现短暂的间歇性下降:
rate()
和irate()
始终计算每秒的速率。有时您会想知道计数器在一段时间内增加的总量,但仍然可以校正计数器的重置。您可以使用该increase()
功能实现此目的。例如,要计算过去一小时内处理的请求总数,请查询:
increase(demo_api_request_duration_seconds_count{job="demo"}[1h])
除了计数器(只能增加),还有计量指标。仪表是可以随时间上升或下降的值,如温度或可用磁盘空间。如果我们想计算仪表随时间的变化,我们就不能使用rate()
/ irate()
/ increase()
系列函数。这些都是针对计数器的,因为它们将度量值的任何减少解释为计数器重置并对其进行补偿。相反,我们可以使用deriv()
函数,该函数基于线性回归计算仪表的每秒导数。
例如,要查看基于最近15分钟的线性回归,我们的演示服务导出的虚构磁盘使用量增加或减少(以每秒MiB为单位)的速度有多快,我们可以查询:
deriv(demo_disk_usage_bytes{job="demo"}[15m])
结果应如下所示:
我们现在知道如何计算具有不同平均行为的每秒速率,如何在速率计算中处理计数器复位,以及如何计算仪表的导数。
在本节中,我们将学习如何聚合单个系列。
Prometheus收集具有高维细节的数据,这可能导致每个度量标准名称的许多系列。但是,通常您并不关心所有尺寸,甚至可能有太多系列以合理的方式一次性绘制它们。解决方案是聚合某些维度并仅保留您关注的维度。例如,演示服务通过跟踪API的HTTP请求method
,path
和status
。Prometheus从节点出口商刮时,增加了进一步维度这个指标:用于跟踪标签处理的指标instance
和job
是从哪里来的。现在,要查看所有维度的总请求率,我们可以使用sum()
聚合运算符:
sum(rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
但是,这会聚合所有维度并创建单个输出系列:
但通常,您需要保留输出中的某些维度。为此,sum()
和其他聚合器支持一个without(<label names>)
子句,该子句指定要聚合的维度。还有一个替代的反向by(<label names>)
子句允许您指定要保留的标签名称。如果我们想知道在所有三个服务实例和所有路径上求和的总请求率,但是通过方法和状态代码将结果拆分,我们可以查询:
sum without(method, status) (rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
这相当于:
sum by(instance, path, job) (rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
该结果现在被instance
,path
以及job
进行分组:
注意:始终计算rate()
,irate()
或increase()
之前应用任何聚合。如果您首先应用聚合,它将隐藏计数器重置,这些功能将无法再正常工作。
Prometheus支持以下聚合运算符,每个运算符都支持一个by()
或without()
子句来选择要保留的维度:
sum
:汇总聚合组中的所有值。min
:选择聚合组中所有值的最小值。max
:选择聚合组中所有值的最大值。avg
:计算聚合组中所有值的平均值(算术平均值)。stddev
:计算聚合组中所有值的标准偏差。stdvar
:计算聚合组中所有值的标准差异。count
:计算聚合组中的序列总数。您现在已经学会了如何聚合系列列表以及如何仅保留您关心的维度。
在本节中,我们将学习如何在Prometheus中进行算术运算。
作为最简单的算术示例,您可以使用Prometheus作为数字计算器。例如,在“ 控制台”视图中运行以下查询:
(4 + 7) * 3
您将获得单个标量输出值33
:
标量值是没有任何标签的简单数值。为了使这更加有用,Prometheus,可以应用普通的算术运算符(+
,-
,*
,/
,%
),以整个时间序列矢量。例如,以下查询将模拟的上次批处理作业运行的处理字节数转换为MiB:
demo_batch_last_run_processed_bytes{job="demo"} / 1024 / 1024
结果将显示在MiB中:
虽然良好的可视化工具(如Grafana)也可以为您处理转换,但通常会对这些类型的单位转换使用简单的算法。
Prometheus的特色(Prometheus真正闪耀的地方!)是两组时间序列之间的二进制算术。在两组系列之间使用二元运算符时,Prometheus会自动匹配操作左侧和右侧具有相同标签集的元素,并将运算符应用于每个匹配对以生成输出序列。
例如,demo_api_request_duration_seconds_sum
度量标准告诉我们在回答HTTP请求时花了多少秒,同时demo_api_request_duration_seconds_count
告诉我们有多少 HTTP请求。两个指标具有相同的尺寸(method
,path
,status
,instance
,job
)。为了计算每个维度的平均请求延迟,我们可以简单地查询请求中花费的总时间除以请求总数的比率。
rate(demo_api_request_duration_seconds_sum{job="demo"}[5m])
/
rate(demo_api_request_duration_seconds_count{job="demo"}[5m])
请注意,我们还在操作的每一侧包装一个rate()
函数,以仅考虑最近5分钟内发生的请求的延迟。这也增加了抵御计数器重置的弹性。
生成的平均请求延迟图应如下所示:
但是当标签在两面都不完全匹配时我们该怎么办?特别是当我们在操作的两侧都有不同大小的时间序列集时会出现这种情况,因为一侧的尺寸比另一侧的尺寸大。例如,演示工作出口在各种模式中花费虚构的CPU时间(idle
,user
,system
)作为有mode
标签尺寸的指标demo_cpu_usage_seconds_total
。它还会导出一个虚构的CPU总数为demo_num_cpus
(此指标没有额外的维度)。如果您尝试将一个除以另一个以达到三种模式中每种模式的平均CPU使用百分比,则查询将不会产生任何输出:
# BAD!
# Multiply by 100 to get from a ratio to a percentage
rate(demo_cpu_usage_seconds_total{job="demo"}[5m]) * 100
/
demo_num_cpus{job="demo"}
在这些一对多或多对一的匹配中,我们需要告诉Prometheus哪些标签子集用于匹配,我们还需要指定如何处理额外的维度。为了解决匹配问题,我们在二元运算符中添加了一个on(<label names>)
子句,用于指定要匹配的标签。要通过较大侧的额外维度的各个值扇出并分组计算,我们分别添加一个在左侧或右侧列出额外维度的子句group_left(<label names>)
或者group_right(<label names>)
。
在这种情况下,正确的查询将是:
# Multiply by 100 to get from a ratio to a percentage
rate(demo_cpu_usage_seconds_total{job="demo"}[5m]) * 100
/ on(job, instance) group_left(mode)
demo_num_cpus{job="demo"}
结果应如下所示:
该on(job, instance)
告诉操作者只匹配系列从左侧和右侧上其job
和instance
标签(并因此不是在mode
标签上,这在右侧是不正确的存在),而group_left(mode)
子句告诉操作者扇出并显示每个模式的CPU使用率平均。这是多对一匹配的情况。要执行反向(一对多)匹配,请以相同方式使用group_right(<label names>)
子句。
您现在知道如何在时间序列集之间使用算术,以及如何处理不同的维度。
在本教程中,我们设置了一组演示服务实例,并使用Prometheus对其进行监视。然后,我们学习了如何对收集的数据应用各种查询技术来回答我们关心的问题。您现在知道如何选择和过滤系列,如何聚合尺寸,以及如何计算速率或衍生物或做算术。您还学习了如何一般地构建查询以及如何避免Prometheus服务器过载。
想要了解更多关于查询Prometheus的相关教程,请前往腾讯云+社区学习更多知识。
参考文献:《How To Query Prometheus on Ubuntu 14.04 Part 1》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有