乐趣区

关于云原生-cloud-native:云原生在京东云原生时代下的监控如何基于云原生进行指标采集


从 Kubernetes 成为容器治理畛域的事实标准开始,基于云原生也就是基于 Kubernetes 原生。在云的体系下,根底硬件基本上都被抽象化、模糊化,硬故障须要人为干涉的频次在逐步升高,健康检查、失败自愈、负载平衡等性能的提供,也使得简略的、毁灭性的故障变少。而随着服务的拆分和模块的重叠,不可形容的、含糊的、莫名其妙的故障却比以前更加的频繁。

“看到指标”只是对于数据简略的出现,在目前云的环境下,并不能高效地帮忙咱们找到问题。而“可观测性”体现的是对数据的再加工,旨在挖掘出数据背地暗藏的信息,不仅仅停留在展示数据层面,更是通过对数据的解析和再组织,体现出数据的上下文信息。

为了达成“可观测性”的指标,就须要更加标准化、简洁化的指标数据,以及更便捷的收集形式,更强更丰盛的语义表达能力,更快更高效的存储能力。本篇文章将次要探讨时序指标的采集构造和采集形式,数据也是指时序数据,存储构造以及 tracing、log、event 等监控模式不在本次探讨范畴之内。

采集构造

提到时序数据,让咱们先看看几个目前监控零碎比拟罕用的时序数据库:opentsdb,influxdb,prometheus 等。

经典的时序数据根本构造大家都是有对立认知的:

1. 惟一序列名标识,即指标名称;

2. 指标的标签集,详细描述指标的维度;

3. 工夫戳与数值对,详细描述指标在某个工夫点的值;

时序数据根本构造为指标名称 + 多个 kv 对的标签集 + 工夫戳 + 值,然而在细节上各家又各有不同。

opentsdb 采集的数据结构

[

{

“metric”: “sys.cpu.nice”,

“timestamp”: 1346846400,

“value”: 18,

“tags”: {

“host”: “web01”,

“dc”: “lga”

}

},

{

“metric”: “sys.cpu.nice”,

“timestamp”: 1346846400,

“value”: 9,

“tags”: {

“host”: “web02”,

“dc”: “lga”

}

}

]

字段

类型

必须

阐明

metric

String

指标名称

timestamp

Integer

数据点的工夫戳

value

Integer, Float, String

指标的值

tags

Map

指标的标签集

opentsdb 应用大家耳熟能详的 json 格局,可能是用户第一反馈中结构化的时序数据结构。只有理解根本时序数据结构的人一眼就能晓得各个字段的含意。

influxdb 采集的数据结构

<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]

例如:

cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000

字段

类型

必须

阐明

measurement

String

指标名称

tag_key

String

指标标签集的 key

tag_value

String

指标标签集的 value

field_key

String

指标值的 key

field_value

Integer, Float, String, Boolean

指标值的 value

timestamp

Timestamp

数据点的工夫戳

prometheus 采集的数据结构

metric_name [

“{” label_name “=” `”` label_value `”` { “,” label_name “=” `”` label_value `”`} [“,”] “}”

] value [timestamp]

例如:

http_requests_total{method=”post”,code=”200″} 1027 1395066363000

字段

类型

必须

阐明

metric_name

String

指标名称

label_name

String

指标标签集的 key

label_value

String

指标标签集的 value

value

Float

指标的值

timestamp

Integer

数据点的工夫戳

influxdb 和 prometheus 都应用了自定义文本格式的时序数据形容,通过固定的语法格局将 json 的树状层级构造打平,并且没有语义的失落,行级的表述模式更便于浏览。

文本格式比照 json 格局

l 文本格式劣势

n 更合乎人类浏览习惯

n 行级的表述构造对文件读取的内存优化更敌对

n 缩小了层级的嵌套

l 文本格式劣势

n 解析老本更高

n 校验绝对更麻烦

指标类型

应用过 Prometheus 的同学可能会留神到其实 Prometheus 的采集构造不是单行的,每类指标往往还随同着几行正文内容,其中次要是两类 HELP 和 TYPE,别离标注指标的简介阐明和类型。格局大略是酱:
`
# Anything you want to say

# HELP http_requests_total The total number of HTTP requests.

# TYPE http_requests_total counter

http_requests_total{method=”post”,code=”200″} 1027 1395066363000

http_requests_total{method=”post”,code=”400″}    3 1395066363000`

Prometheus 次要反对 4 类指标类型:

• Counter:只增不减的计数器

• Gauge:可增可减的数值

• Histogram:直方图,分桶采样

• Summary:数据汇总,分位数采样

其中 Counter 和 Gauge 很好了解,Histogram 和 Summary 可能一时间会让人蛊惑。其实 Histogram 和 Summary 都是为了从不同维度解决和过滤长尾问题。

例如,我和首富的均匀身价并不能实在反映出我本人的身价。因而分桶或者分位数能力更精确的形容数据实在的散布状态。

而 Histogram 和 Summary 次要区别就在于对分位数的计算上,Histogram 在客户端只进行分桶计算,因而能够在服务端进行整体的分位数计算。Summary 则是在客户端环境下计算了分位数,因而失去了在整体视图上进行分位数计算的可能性。官网也给进去 Histogram 和 Summary 的区别:

Histogram

Summary

所需配置

须要设置冀望的分桶范畴

须要设置冀望的分位数以及滑动窗口大小

客户端性能耗费

耗费较低,只须要增量计算

比拟费性能,因为须要流式分位数计算

服务器端性能耗费

须要计算分位数,耗费较高,如果破费工夫太长,能够尝试应用预聚合

耗费较低

工夫序列

一个分桶一个

一个分位数一个

分位数误差

误差取决于分桶的数量和桶的大小

误差取决于分位数的值

分位数与工夫窗口

查问时指定

采集时指定

聚合

查问时指定

通常不可做聚合

须要阐明的是,截止到目前为止的 Prometheus 版本 2.20.1,这些 metric types 仅仅应用在客户端库(client libraries)和传输协定(wire protocol)中,服务端临时没有记录这些信息。所以如果你对一个 Gauge 类型的指标应用 histogram_quantile(0.9,xxx) 也是能够的,只不过因为没有 xxx_bucket 的存在,计算不进去值而已。

采集形式

时序监控数据的采集,从监控端来看,数据获取的模式只有两种,pull 和 push,不同的采集形式也决定了部署形式的不同。

还是通过 opentsdb,prometheus 来举例,因为 influxdb 集群版本计划为商业版,暂不做探讨。

push 形式

上图为 opentsdb 架构图,其中:

• Servers:示意被采集数据的服务,C 则是示意采集指标的工具,能够了解为 opensdb 的 agent,servers 通过 C 将数据推送到上游的 TSD;

• TSD:对应理论过程名 TSDMain 是 opentsdb 组件,了解为接管层,每个 TSD 都是独立的,没有 master 和 slave 的辨别,也没有共享状态;

• HBase:opentsdb 理论的最终数据存储在 hbase 中;

从架构图能够看出,如果推送模式的数据量大量增长的状况下,能够通过多级组件,或者扩容无状态的接管层等形式较为简单的进行吞吐量的降级。

pull 形式

上图为 prometheus 架构图,次要看上面几个局部:

• Prometheus Server:用于抓取和存储工夫序列化数据

• Exporters:被动拉取数据的插件

• Pushgateway:被动拉取数据的插件

拉取的形式,通常是监控端定时从配置的各个被监控端的 Exporter 处拉取指标。这样的设计形式能够升高监控端与被监控端的耦合水平,被监控端不须要晓得监控端的存在,这样将指标发送的压力从被监控端本义到监控端。

比照一下 pull 和 push 形式各自的优劣势:

l pull 的劣势

n 上下游解耦

n 被监控端不会因为 push 数据到监控端失败,而导致本身不稳固

n 监控端本身的压力状况基本上能够预测,升高因为被监控端突增的发送流量导致的本身危险,例如 DDoS

n 能够做到被监控端的主动发现机制

n 主动权在监控端这边,能够更灵便的配置须要监控什么,尤其是在调试过程中

l pull 的劣势

n 对于周期性不显著,或者周期显著短与采集周期的指标缺失精度

n 实时性较差

n 可能因为防火墙等简单的网络环境设置,导致拉取不到数据

n 如果数据有缺失,很难进行补数据

简略比照了 pull 和 push 各自的特点,在云原生环境中,prometheus 是目前的时序监控规范,为什么会抉择 pull 的模式,这里有官网的解释(https://prometheus.io/docs/introduction/faq/#why-do-you-pull-rather-than-push)。

下面简略介绍了一下从监控端视角对待数据采集形式的 pull 和 push 模式,而从被监控端来看,数据获取的形式就多种多样了,通常能够分为以下几种类型:

1. 默认采集

2. 探测采集

3. 组件采集

4. 埋点采集

上面一一举例说明。

默认采集

默认采集通常是艰深意义上的所有人都会须要察看的根底指标,往往与业务没有强关联,例如 cpu、memory、disk、net 等等硬件或者零碎指标。通常监控零碎都会有特定的 agent 来固定采集这些指标,而在云原生中十分不便的应用 node_exporter、CAdvisor、process-exporter,别离进行节点机器、容器以及过程的根底监控。

探测采集

探测采集次要是指从内部采集数据的形式。例如域名监控、站点监控、端口监控等都属于这一类。采集的形式对系统没有侵入,因为对网络的依赖比拟强,所以通常会部署多个探测点,缩小因为网络问题造成的误报,然而须要特地小心的是,肯定要评估探测采集的频次,否则很容易对被探测方造成申请压力。

组件采集

通常是指曾经有现成的采集计划,只须要简略的操作或者配置就能够进行具体的指标采集,例如 mysql 的监控,redis 的监控等。在云原生环境中,这种采集形式比拟常见,得益于 prometheus 的发展壮大,常见的组件采集 exporter 层出不穷,prometheus 官网认证的各种 exporter。对于以下比拟非凡或者定制化的需要,也齐全能够依照 /metrics 接口标准本人实现自定义 exporter 的编写。

埋点采集

对于一个零碎的关键性指标,自身的研发同学是最有发言权的,通过埋点的形式能够精准的获取相干指标。在 prometheus 体系中能够十分不便的应用 github.com/prometheus/client_* 的工具包来实现埋点采集。

总结

本文对监控零碎的第一个阶段“采集”,从“采集构造”和“采集形式”两方面做了简略的介绍和梳理。相比于以往,在云原生的环境中,服务颗粒度拆分的更粗疏,迭代效率更高,从开发到上线造成了更快节奏的反馈循环,这也要求监控零碎可能更疾速的反映出零碎的异样,“采集构造”和“采集形式”尽管不是监控零碎最外围的局部,然而简洁的采集构造和便捷的采集形式也为后续实现“可观测性”提供了根底。目前在云原生环境中,应用 prometheus 能够十分方便快捷的实现监控,尽管仍有许多工作须要做,例如集群化、长久化存储等,然而随着 Thanos 等计划的呈现,prometheus 也在慢慢饱满中。

退出移动版