4.1.3 指标
由时间序列的矩阵坐标原理可知,时间序列的指标(Metrics)可以基于Bigtable[1](Google论文)设计为Key-Value存储的方式,如图4-2所示。
图4-2 基于Bigtable的Key-Value的Prometheus Metrics方式
以图4-2中的http_request_total{status="200",method="GET"}@1434417560938=>94355为例,在Key-Value关系中,94355作为Value(也就是样本值Sample Value),前面的http_request_total{status="200",method="GET"}@1434417560938一律作为Key。在Key中,又由Metric Name(例子中的http_request_total)、Label(例子中的{status="200",method="GET"})和Timestamp(例子中的@1434417560938)3部分构成。
在Prometheus的世界里面,所有的数值都是64 bit的。每条时间序列里面记录的就是64 bit Timestamp(时间戳)和64 bit的Sample Value(采样值)。
思考拓展
这样的Key-Value结构,可以很方便我们根据Key去查询想要的Value值。而Key则需要通过规范或者自定义的Metrics Name、Labels、Timestamp来进行联合查询,而Labels也可以自定义多个,这就是PromQL多条件查询的存储基础。
去除Timestamp,Prometheus Metrics又可以精简为图4-3所示的形式。
图4-3 Prometheus Metrics的两种方式
如图4-3所示,Prometheus的Metrics可以有两种表现方式。第一种方式是经典的形式。
<Metric Name>{<Label name>=<label value>, ...}
其中,Metric Name就是指标名称,反映监控样本的含义。图4-2中所示的http_request_total代表当前系统接收到的HTTP请求总量。指标名称只能由ASCII字符、数字、下划线以及冒号组成并必须符合正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*。
注意
冒号用来表示用户自定义的记录规则。不能在Exporter中或监控对象直接暴露的指标中使用冒号来定义指标名称。
标签反映了当前样本的多种特征维度。通过这些维度,Prometheus可以对样本数据进行过滤、聚合、统计等操作,从而产生新的计算后的一条时间序列。标签名称也只能由ASCII字符、数字以及下划线组成,并且必须满足正则表达式[a-zA-Z_][a-zA-Z0-9_]*。
通过命令go_gc_duration_seconds{quantile="0"}可以在Prometheus的Graph控制台获得图4-4所示的结果。
图4-4 Prometheus Metrics获得的数据(方法一)
第二种方式来源于Prometheus内部。
{__name__=metrics,<label name>=<label value>, ...}
第二种方式和第一种方式是一样的,表示同一条时间序列。这种方式是Prometheus内部的表现形式,是系统保留的关键字,官方推荐只能在系统内部使用。在Prometheus的底层实现中,指标名称实际上是以__name__=<metric name>的形式保存在数据库中的;__name__是特定的标签,代表了Metric Name。标签的值则可以包含任何Unicode编码的字符。
通过命令{__name__="go_gc_duration_seconds",quantile="0"}可以在Prometheus的Graph控制台获得如图4-5所示的结果。
图4-5 Prometheus Metrics获得的数据(方法二)
思考拓展
指标名称和标签的组合代表了一条时间序列上的数据。不同的指标名称自然不是同一类的指标,但是相同的指标名称如果携带不同的标签,也代表了不同类的指标。比如下面的例子就是5条不同的时间序列。
·http_requests_total{status="200",method="POST"}
·http_requests_total{status="200",method="GET"}
·http_requests_total{status="404",method="GET"}
·http_requests_total
·http_requests_total{}
需要注意的是:
1)在没有标签的时候,http_requests_total等同于http_requests_total{},表达式会返回指标名称为http_requests_total的所有时间序列。后者中的花括号{}可以附加一组或者多组标签,从而进一步过滤时间序列。
2)所有的PromQL表达式都必须至少包含一个指标名称(例如http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如{status="200"})。因此{status="200"}{quantile="1"}这样的表达式也是合法的,如图4-6所示。
图4-6 一个不会匹配到空字符串的标签过滤器的合法PromQL语句
[1] Bigtable是一个分布式存储系统,它被用于存储近万台商用服务器规模的、PB级别的数据,包括网页索引、Google Earth、Google Finance(注:这些应用都是2005年Google论文中列举的,现在Google似乎已经抛弃Bigtable使用下一代产品了)在内的许多Google项目都使用Bigtable来存储数据。这些应用在数据粒度和实时性方面的要求大相径庭,而Bigtable却能很好地为这些应用提供灵活、高性能的解决方案。在这篇论文中讨论到Bigtable提供了简单数据模型,这个模型让用户能够动态地控制数据布局和格式。这篇论文中还介绍了Bigtable的设计和实现。