普罗米修斯查询训练营

首先/第一,

这是普罗米修斯万圣节日历2017年第16天的文章。

请问大家有用过 Prometheus 吗?很好用的,Prometheus。
收集数据并随意查询,当发现可疑行为时,喜悦难以言表。

WS000154.png

这种”不知道是什么,但感觉很厉害”的感觉,可说是鲜艳夺目,犹如现代的IT曼陀罗。

用于引用 Prometheus 中积累的各种度量标准的参考是使用一种名为 PromQL 的专有查询语言进行的。虽然一旦熟悉就不会有太多困扰,但由于需要在时间序列度量标准中进行全方位的探索,所以我想在查询道场从基础开始学习。

如果你不知道「Prometheus」到底是什么,那么你可以这样问。

    • Prometheus入門から運用まで徹底解説

次世代監視の大本命! Prometheus を実運用してみた ( @sugitak )

请先阅读这份出色的资料。

关于环境

在这篇文章中使用的Prometheus版本是2.0。
您可以通过查看Prometheus的[状态] -> [运行时和构建信息] -> [构建信息]来确认当前运行的版本。

WS000156.png

文章を参照してください。

自分のマシンでprometheusを動かしてみよう ( @tjinjin )

如果您想尝试环境搭建,可以参考这篇文章。只要能成功安装Docker,就会感到非常轻松。
我自己以Rancher社区目录为基础,在多台设备上搭建了Prometheus 2.0环境。

由于Prometheus仍在不断发展中,因此关于它可以在谷歌上找到的文章版本相当多样化。
我认为仍然有很多人只是随意地复制粘贴运行,然后发现是1系列的版本,所以请注意版本。

如果想要使用最新的Web文章,无论是什么类型的文章,可以参考prometheus/prometheus – GitHub或prom/prometheus – DockerHub。截至到2017年12月16日,最新版本是2.0.0。

了解数据

在Prometheus中查询意味着有要搜索的数据。在学习具体查询之前,让我们首先大致了解一下Prometheus可以收集到哪些数据。

1-1. 确认数据收集设置

Prometheus使用了Pull型架构,所以在服务器端保存了要收集的数据的信息。
可以通过 [Status] -> [Targets] 查看要收集的数据列表,让我们先来看一下。

WS000157.png

由于Rancher社区目录已经设置了几个出口器,所以可以看到相当多的目标。
这取决于在prometheus.yml中定义的scrape_configs的配置。
该配置可以在[状态] -> [配置]中查看。
例如,如果是在第二个HostMetrics中可见,则

scrape_configs:
- job_name: HostsMetrics
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  dns_sd_configs:
  - names:
    - node-exporter
    refresh_interval: 15s
    type: A
    port: 9100

是这样定义的。我希望你在这里注意的是 dns_sd_configs 的部分。通过查看上面的图像,可以看出 HostMetrics 的目标具体有3个,但在设置中似乎并没有看到有3个。在这里实际发挥作用的正是 dns_sd_configs,将其作为 node-exporter 的名称用于收集目标。

您可以通过 static_configs 参数来静态配置目标,也可以通过支持的服务发现机制之一来动态发现目标。

如果理解了”sd”代表”service discovery”的缩略意味,那么对于其工作过程的想象会变得更加容易。除了”dns_sd_config”,还可以查看”CONFIGURATION”页面。

    • ec2_sd_config

 

    • azure_sd_config

 

    • gce_sd_config

 

    • openstack_sd_config

 

    kubernetes_sd_config

似乎可以发现许多不同的事物。

1-2. 数据样本的确认

那么,让我们来看一些实际收集到的数据吧。
一个简单的方法是从Prometheus的界面随便执行一个查询试试看。

WS000160.png

当您在查询窗口中输入指标名称(部分名称)时,会提供与其匹配的指标建议。
这些指标建议非常灵活,从图例中可以看出,提供的建议不仅包含了包含”node_memory_free”的指标,还包括了包含字符 “n/o/d/e/_/m/r/y/f”的指标。

选择候选项并点击“执行”按钮后,您可以在“控制台”选项卡中确认实际数据,并在“图表”选项卡中查看图表。

WS000162.png

在Element中,Metrix的名称后面会出现各种标签,这是查询中一个重要的要点,稍后会进行解释。

WS000163.png

默认显示是最近1小时的图表,但您可以通过[ – ] [ + ]更改显示时间段,也可以通过[◀◀] [▶▶]更改显示起始时间。

除此之外,还有一种方法是直接进入Prometheus容器,参考抓取目标的Endpoint。通过这种方法,您可以实时了解每个Endpoint的度量数据。当抓取出现问题时,我们也会采取这种方法进行故障排除。

# PrometheusコンテナのIDを調べる
$ sudo docker ps -f name=prometheus
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
f4965fc87373        prom/prometheus:v2.0.0       "/.r/r /bin/promet..."   4 hours ago         Up 4 hours                              r-Prometheus-prometheus-1-736c0be3
29e30fcc5a55        infinityworks/prom-conf:19   "/bin/sh"                4 hours ago         Up 4 hours                              r-Prometheus-prometheus-prom-conf-1-1e026d96

# Prometheusコンテナに接続(bashがないのでshにつなぐ)
$ sudo docker exec -it f4965fc87373 /bin/sh

# PrometheusメトリクスのEndpointを参照(curlがないのでwgetを使って標準出力に出している)
$ wget http://127.0.0.1:9090/metrics -qO -
Connecting to 127.0.0.1:9090 (127.0.0.1:9090)
go_gc_duration_seconds{quantile="0"} 2.046e-05
go_gc_duration_seconds{quantile="0.25"} 8.5385e-05
go_gc_duration_seconds{quantile="0.5"} 0.000147534
go_gc_duration_seconds{quantile="0.75"} 0.000350681
go_gc_duration_seconds{quantile="1"} 0.010048808
go_gc_duration_seconds_sum 0.087973045
go_gc_duration_seconds_count 173

()

我认为可以大致了解到正在收集什么样的数据。

1-3. 对数据结构的理解

我想你剛才已經簡單檢查了數據,但現在讓我們再次看看數據。

WS000162.png

在这里有三个数据(元素)出现,它们的区别体现在 node_memory_MemFree 后面的 { } 中。
这些被包含在其中的项目称为标签,并且可以看出这些数据有 instance 标签和 job 标签。

按照时间顺序排列,Prometheus处理所谓时序数据。根据数据模型的提及,每个数据都具有公共的标记(labels),可以用于查询和过滤。

    • timestamp

 

    • metric name

 

    label

将进行识别。

在图表中只显示了三个数据点,但这只是显示了最近的数据,实际上,即使是相同的指标和标签,数据也是如下所示的叠加。

timestampmetric namelabelvalue2017-12-16 11:23:09.456811+09node_memory_MemFreeinstance=”10.42.216.232:9100″,job=”HostsMetrics”10076078082017-12-16 11:23:24.396112+09node_memory_MemFreeinstance=”10.42.216.232:9100″,job=”HostsMetrics”10072473602017-12-16 11:23:39.833171+09node_memory_MemFreeinstance=”10.42.216.232:9100″,job=”HostsMetrics”1007255552…node_memory_MemFreeinstance=”10.42.216.232:9100″,job=”HostsMetrics”…

因此,确定度量标准并形象化数据时

縦 の広がり: 同じメトリクス/同じ時間だが ラベルの違うもの

横 の広がり: 同じメトリクス/同じラベルだが 時間の違うもの

“对于这种感觉的重要性日益凸显。”

WS000164.png

了解查询

那么现在让我们实际上来写一个查询吧。

查询数据

让我们首先选择合适的数据,这是很自然的。让我们尝试以下的查询。

# インスタンスをどれか1つ指定
node_memory_MemFree{instance="10.42.216.232:9100"}

这样一来,数据被筛选出来,只显示具有指定标签的数据。

WS000165.png

如果在查询中将标签条件放在{ }中,只有具有该标签的数据会被返回。标签条件可以使用正则表达式,并将=~作为比较运算符。

# =~ で比較すると正規表現の指定になる
node_memory_MemFree{instance=~"^10.42.*:9100"}

在SQL中,可以把WHERE子句写在{}之中,就像这样。

此外,Prometheus的实现是使用Go语言,因此在PromQL中的正则表达式和转义处理遵循Go语言的规范(正则表达式/字符串)。
如果对转义感到困惑,请阅读Go语言相关的文档。

2-2. 进行数据计算

接下来,让我们进行数据计算试试吧。

# 加減乗除(+-*/)
node_memory_MemFree{instance="10.42.216.232:9100"} + 1000
node_memory_MemFree{instance="10.42.216.232:9100"} - 1000
node_memory_MemFree{instance="10.42.216.232:9100"} * 1000
node_memory_MemFree{instance="10.42.216.232:9100"} / 1000

# 剰余計算(%)
node_memory_MemFree{instance="10.42.216.232:9100"} % 1000

# べき乗計算
node_memory_MemFree{instance="10.42.216.232:9100"} ^ 2

根据数据来看,有时可能很难直观地理解其规模感,所以在这种情况下,经常会通过将其乘以1000倍或除以1/1000来对齐位数。

而且,还可以进行数据之间的计算。

# TotalからFreeを引くと使用中が出る
node_memory_MemTotal - node_memory_MemFree

# さらにTotalで割ると使用率が出る
( node_memory_MemTotal - node_memory_MemFree ) / node_memory_MemTotal

如果有类似”node_memory_MemUsed”这样的东西,我们就不需要这样做了。即使没有这样的东西,Prometheus也很好的一点是可以通过数据之间的计算来轻松补充。

2-3. 进行数据汇总

使用函数可以对列出的数据进行汇总。

# 最大/最小
max(node_memory_MemFree)
min(node_memory_MemFree)

# 合計/平均
sum(node_memory_MemFree)
avg(node_memory_MemFree)

如果没有特定的标签限制查询时,会出现三条数据,上述查询对它们分别提供了”最大值”、”最小值”、”总和”和”平均值”。

由于先前的 node_memory_MemFree 数据没有价值,因此我们将使用 node_filesystem_files_free 数据从这里开始。

WS000166.png

最近出现了一些变化。根据文件系统的不同使用了fstype,在挂载点mountpoint上显示了数据。让我们尝试按挂载点来汇总数据。

# mountpointラベルごとにmaxの値を集計
max(node_filesystem_files) by (mountpoint)

看起来结果是这样的。

WS000168.png

由于原始数据中混合了 fstype=”ext4″ 和 fstype=”overlay”,因此我们需要将它们分开显示。

# mountpointとfstypeラベルごとにmaxの値を集計
max(node_filesystem_files) by (mountpoint, fstype)

结果是这样的。考虑到 fstype 的统计结果增加了一个。

WS000169.png

在中国,可以自由地通过(标签名称)来更改汇总的范围。

试用方便的函数

到目前为止,在这里

    • メトリクス

 

    • ラベル

 

    • 参照

 

    • 計算

 

    集計

我认为你已经理解了这种思维方式以及如何使用它来进行查询。到目前为止,我认为你已经能够进行大部分数据探索并基于此进行图形创建。但是因为Prometheus中有许多有用的函数,所以我想介绍其中的一些。

3-0. 区间向量和瞬时向量

我以後再解釋這個問題,但根據表達語言資料類型,Prometheus的數據有以下4種類型。

    • Instant vector

 

    • Range vector

 

    • Scalar

 

    String (ただし2.0時点では未使用)

到目前为止的查询中,我们使用了Instant vector和Scalar,Instant vector用于对每个元素返回一个值,并用于中间计算。

# Instant vectorにScalarを足す
node_memory_MemFree + 100

以下的查询是针对称为“Range vector”的类型,因为这一点之前没有解释清楚,但您可以尝试一下以更快地理解。

# 直近1分間のデータを表示する
node_memory_MemFree[1m]
WS000170.png

每个元素都有4个数据。
尽管查询指定了1分钟,但是获得的数据似乎有4个。
这是因为 node_memory_MemFree 指标的抓取间隔为15秒。

scrape_configs:
- job_name: HostsMetrics
  scrape_interval: 15s ★ここ
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  dns_sd_configs:
  - names:
    - node-exporter
    refresh_interval: 15s
    type: A
    port: 9100

以指定时间范围获取一系列数据的数据类型被称为Range vector。由于许多函数的参数是Range vector,因此我们先解释了这个概念。

3-1. 三角函数

现在我来解释一下如何使用Range vector函数。

    delta(Range vector)

在Delta函数中,可以取给定的Range向量数据的差分。

# 直近1時間での空きメモリ量の差
delta(node_memory_MemFree[1h])

在Range vector中,它包含了指定时间范围内的大量数据,而delta函数计算的是该时间段内的第一个值与最后一个值之间的差值。
因此,在上述查询中,我们是通过当前值减去1小时之前的值来计算差值。
如果查询结果是负数的话,可以推断出”最近1小时内可用内存减少了”。

3-2. 比率函数

    rate(Range vector)

rate函数是针对相同的Range值,返回当前值相对于期间内平均值的比例。

# idle状態のCPUが直近5分平均に比べてどれくらい増えているか
rate(node_cpu{mode="idle"}[5m])

作为典型示例,你可以在官方示例查询中找到一个使用HTTP请求计数的例子。

# 5分平均のリクエスト数からどれくらい増えているか
rate(http_requests_total{job="api-server"}[5m])

如果您观察这个数值,就可以看到每秒请求数的增加或减少。

顺便提一下,类似的函数中还有一个称为 irate 的函数,但它是将最后两个时间点的平均值与当前值进行比较。
在平稳的情况下,rate 和 irate 的运动方式是相同的,但是当存在非常瞬间的尖峰时,rate 可能无法做出反应,因此 irate 似乎选择最后两个点作为比较对象。

愤怒只应在绘制波动剧烈、迅速变动的计数器时使用。对于警报和缓慢移动的计数器,请使用速率,因为速率的微小变化可以重新设置FOR子句,而仅由罕见的尖峰组成的图表很难阅读。

3-3. 变化函数

    changes(Range vector)

changes函数用于计算给定的Range向量中发生了多少次值的变化。
通常情况下,它会被用于计算状态更改发生了多少次的案例中。

# healthステータスが1時間で何回変化したか
changes(rancher_service_health_status{health_state="healthy"}[1h])

3-4. 其他选项

下面提供了中国人的翻译版本:
这只是一个像小玩笑一样的函数。它可以用来微调结果或者在交互式研究中提供帮助的感觉。

ceil(Instant vector)

与えられたInstant vectorの切り上げを行う関数。 floor が切り下げ。四捨五入なら round 。

abs(Instant vector)

与えられたInstant vectorの絶対値を返す関数。

sort(Instant vector)

結果を昇順でソートする。降順ソートは sort_desc 。

最后

你对整体数据的理解和基本查询的写法都明白了吗?

普罗米修斯还有其他的功能,比如进行对数计算的log2函数,利用线性回归进行线性预测的predict_linear函数,以及进行微分的deriv函数等等。
这个查询本身还有很多深奥的东西,包括如何利用它们来监控系统,似乎还有很大的深入空间。

非常有意义。

    • クエリを使ってダッシュボードを作成する

参考: prometheusとgrafanaを入れたみたが、どうグラフとか出すといいのか?

収集データを追加する

Prometheus – exporters
参考: prometheusのexporter紹介シリーズ1〜blackbox_exporter

按此方式,我们将需要面对监视问题。

结束了。

广告
将在 10 秒后关闭
bannerAds