Maple's Story

实习总结:基于Prometheus + Grafana + JsonDatasource 搭建云资源监控系统

字数统计: 2.6k阅读时长: 10 min
2020/06/15 Share

  为了提升公司AI平台计算资源的利用效率,需要实现AI平台计算资源、应用数据的实时统计,故提出基于Prometheus+Grafana搭建资源监控平台。由于公司云资源分布在不同集群,需引入多个Prometheus DataSource,而Grafana对于多DataSource数据整合分析不具有很好的原生支持。所以使用Json Datasource插件,自行建立基于GO+Gin框架的后端,调用Prometheus Http接口,对不同集群数据进行整合计算,提供Http接口给Grafana平台调用以供展示。

  以下主要总结在实习过程中使用的上述组件的部分功能,并非对相关技术全面概览。


Prometheus

  Prometheus 是一款基于时序数据库的开源监控告警系统,目前已经广泛用于 Kubernetes 集群的监控系统中。Prometheus 的开发者和用户社区非常活跃,它现在是一个独立的开源项目,可以独立于任何公司进行维护。

主要特性

  • 多维度数据模型
  • 方便的部署和维护
  • 灵活的数据采集
  • 强大的查询语言

  Prometheus 数据采集方式也非常灵活。要采集目标的监控数据,首先需要在目标处安装数据采集组件,这被称之为 Exporter,它会在目标处收集监控数据,并暴露出一个 HTTP 接口供 Prometheus 查询。

  Prometheus Server 直接从监控目标中或者间接通过推送网关来拉取监控指标,它在本地存储所有抓取到的样本数据,并对此数据执行一系列规则,以汇总和记录现有数据的新时间序列或生成告警。可以通过 Grafana 或者其他工具来实现监控数据的可视化。

Prometheus 架构

数据模型

  Prometheus 所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中:属于同一指标名称,同一标签集合的、有时间戳标记的数据流。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。

样本

  在时间序列中的每一个点称为一个样本(sample),由三部分组成:

  • 指标(metric):指标名称和描述当前样本特征的 labelsets
  • 时间戳(timestamp):一个精确到毫秒的时间戳
  • 样本值(value): 一个 folat64 的浮点型数据表示当前样本的值

表示方式

<metric name>{<label name>=<label value>, ...}

查询语句PromQL

  Prometheus 提供了一种功能丰富的查询语言 PromQL,允许用户实时选择和汇聚时间序列数据。通过编写相应的表达式可以返回以下四种数据类型:

  • 瞬时向量(Instant vector)
  • 区间向量(Range vector)
  • 标量(Scalar)
  • 字符串(String)

  具体 PromQL 用法可查询Prometheus官方文档

HTTP API

  Prometheus 同样提供 HTTP API 调用接口,通过GET请求带入PromQL表达式、时间戳、时间间隔等参数,返回JSON格式的监控数据

API响应格式

1
2
3
4
5
6
7
8
9
{
"status": "success" | "error",
"data": <data>,

// Only set if status is "error". The data field may still hold
// additional data.
"errorType": "<string>",
"error": "<string>"
}

表达式查询

  通过 HTTP API 我们可以分别通过 /api/v1/query 和 /api/v1/query_range 查询 PromQL 表达式当前或者一定时间范围内的计算结果。

瞬时数据查询

查询语句:

1
2
3
GET /api/v1/query?
query=<string> &
time=<rfc3339 | unix_timestamp>&timeout=<duration>

返回数据格式:

1
2
3
4
5
6
7
{
"status" : "success",
"data" : {
"resultType": "matrix" | "vector" | "scalar" | "string",
"result": <value>
}
}

区间数据查询

查询语句:

1
2
3
4
5
6
GET /api/v1/query_range?
query=<string> &
start=<rfc3339 | unix_timestamp> &
end=<rfc3339 | unix_timestamp> &
step=<duration | float> &
timeout=<duration>

返回数据格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"status" : "success",
"data" : {
"resultType" : "matrix",
"result" : [
{
"metric": { "<label_name>": "<label_value>", ... },
"values": [ [ <unix_time>, "<sample_value>" ], ... ]
},
...
]
}
}


Grafana

  Grafana是一款用Go语言开发的通用的开源数据可视化工具,可以做数据监控和数据统计,带有告警功能。“通用”意味着Grafana不仅仅适用于展示Prometheus下的监控数据,也同样适用于一些其他的数据可视化需求。
  其主要特点如下:

  • 可视化:快速灵活的客户端图表,面板插件有许多不同方式的可视化指标和日志,官方库中具有丰富的仪表盘插件,比如热图、折线图、图表等多种展示方式
  • 报警:以可视方式定义最重要指标的警报规则,Grafana将不断计算并发送通知,在数据达到阈值时通过Slack、PagerDuty等获得通知
  • 混合展示:在同一图表中混合使用不同的数据源,可以基于每个查询指定数据源,甚至自定义数据源
  • 注释:使用来自不同数据源的丰富事件注释图表,将鼠标悬停在事件上会显示完整的事件元数据和标记
  • 过滤器:Ad-hoc过滤器允许动态创建新的键/值过滤器,这些过滤器会自动应用于使用该数据源的所有查询

数据源(Data Source)

  对于Grafana而言,Prometheus这类为其提供数据的对象均称为数据源(Data Source)。目前,Grafana官方提供了对: Prometheus, Graphite, InfluxDB, OpenTSDB等大量数据源的支持。对于Grafana管理员而言,只需要将这些对象以数据源的形式添加到Grafana中,Grafana便可以轻松的实现对这些数据的可视化工作。
  与此同时,Grafana还支持使用第三方数据源插件导入数据,本次工作即通过使用 JSON 数据源插件引入后端自行处理过的数据进行展示。


仪表盘(Dashboard)

  通过数据源定义好可视化的数据来源之后,对于用户而言最重要的事情就是实现数据的可视化。在Grafana中,我们通过Dashboard来组织和管理我们的数据可视化图表:

面板(Panel)

  Panel是Grafana中最基本的可视化单元。每一种类型的面板都提供了相应的查询编辑器(Query Editor),让用户可以从不同的数据源(如Prometheus)中查询出相应的监控数据,并且以可视化的方式展现。例如,如果以Prometheus作为数据源,那在Query Editor中,我们实际上使用的是PromQL,而Panel则会负责从特定的Prometheus中查询出相应的数据,并且将其可视化。由于每个Panel是完全独立的,因此在一个Dashboard中,往往可能会包含来自多个Data Source的数据。
  在本次工作中,由于使用自行设计的后端接口,数据查询语句为自定义的JSON格式。


JSON Datasource

  一个用于Grafana的第三方JSON Datasource插件,通过编写后端实现该插件要求的HTTP API,可以实现以JSON格式向Grafana发送自定义的Datasource

API

  为使该插件正常工作,后端必须实现以下API:

  • GET / :用于测试与datasource之间的连接情况
  • POST /search :根据请求字段返回可用的metrics
  • POST /query :根据输入的查询语句返回对应的metrics
  • POST /annotations :返回注释(本次工作实际未实现,没有影响功能,故似乎为可选实现)

  可选实现:

  • POST /tag-key :根据ad-hoc过滤器返回对应的tag-keys
  • POST /tag-values :根据ad-hoc过滤器返回对应的tag-values

API 具体格式

request:
Variables > New/Edit page 示例:
{ "target": "query field value" }
Panel > Queries page 示例:
{ "type": "timeseries", "target": "upper_50" }

response:
array返回示例:
["upper_25","upper_50","upper_75","upper_90","upper_95"]
map返回示例
[ { "text": "upper_25", "value": 1}, { "text": "upper_75", "value": 2} ]

query

request:
timeseries 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"panelId": 1,
"range": {
"from": "2016-10-31T06:33:44.866Z",
"to": "2016-10-31T12:33:44.866Z",
"raw": {
"from": "now-6h",
"to": "now"
}
},
"rangeRaw": {
"from": "now-6h",
"to": "now"
},
"interval": "30s",
"intervalMs": 30000,
"maxDataPoints": 550,
"targets": [
{ "target": "Packets", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } },
{ "target": "Errors", "refId": "B", "type": "timeseries" }
],
"adhocFilters": [{
"key": "City",
"operator": "=",
"value": "Berlin"
}]
}

Additional data:
request可携带额外的JSON格式的数据作为查询条件,格式如下:
{ "additional": "optional json" }
并将放置在request body 的target-data中,示例如下:
{ "target": "upper_50", "refId": "A", "type": "timeseries", "data": { "additional": "optional json" } }

response:
metric类型选择为timeseries 返回示例: (metric类型为float,unix时间戳类型为milliseconds)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[
{
"target":"pps in",
"datapoints":[
[622,1450754160000],
[365,1450754220000]
]
},
{
"target":"pps out",
"datapoints":[
[861,1450754160000],
[767,1450754220000]
]
},
{
"target":"errors out",
"datapoints":[
[861,1450754160000],
[767,1450754220000]
]
},
{
"target":"errors in",
"datapoints":[
[861,1450754160000],
[767,1450754220000]
]
}
]

metric类型选择为table 返回示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[
{
"columns":[
{"text":"Time","type":"time"},
{"text":"Country","type":"string"},
{"text":"Number","type":"number"}
],
"rows":[
[1234567,"SE",123],
[1234567,"DE",231],
[1234567,"US",321]
],
"type":"table"
}
]

其余API接口本次未使用,便不再记录

参考学习资料

Prometheus中文文档
实战 Prometheus 搭建监控系统
可视化工具Grafana:简介及安装
JSON Datasource – a generic backend datasource

GO后端实现方案与GO学习路径再一同总结

CATALOG
  1. 1. Prometheus
    1. 1.1. Prometheus 架构
    2. 1.2. 数据模型
      1. 1.2.1. 样本
      2. 1.2.2. 表示方式
    3. 1.3. 查询语句PromQL
    4. 1.4. HTTP API
      1. 1.4.1. API响应格式
      2. 1.4.2. 表达式查询
        1. 1.4.2.1. 瞬时数据查询
        2. 1.4.2.2. 区间数据查询
  2. 2. Grafana
    1. 2.1. 数据源(Data Source)
    2. 2.2. 仪表盘(Dashboard)
    3. 2.3. 面板(Panel)
  3. 3. JSON Datasource
    1. 3.1. API
    2. 3.2. API 具体格式
      1. 3.2.1. search
      2. 3.2.2. query
  4. 4. 参考学习资料