监控-Prometheus01-简介

  • Prometheus官网:https://prometheus.io/
  • Prometheus文档:https://prometheus.io/docs/
  • Prometheus下载:https://prometheus.io/download/
  • Prometheus GitHub主页:https://github.com/prometheus/
  • Prometheus GitHub源码:https://github.com/prometheus/prometheus
  • Prometheus参考视频:大规模Prometheus和时间序列设计(https://www.youtube.com/watch?v=gNmWzkGViAY)。
  • Grafana官网:https://grafana.com/

1、Prometheus起源

  • Google公司推出了大量产品,其中最著名的是广告系统和搜索引擎平台。为了运行这些不同的产品,该公司建立了一个名为Borg的平台。
    • Borg系统:一个集群管理器,可以运行来自数千个不同应用程序的数十万个作业,它跨越多个集群,每个集群都有数万台服务器
    • Borgmon:一个实时的时间序列监控系统,它使用时间序列数据来识别问题并发出警报。Borgmon是为了监控Borg而生。
    • Borg和Borgmon都没有开源,直到最近才有机会了解它们的工作原理。
  • 开源容器管理平台Kubernetes的很多部分都是继承自谷歌的Borg平台。
  • Prometheus的灵感来自谷歌的Borgmon。
    • 它最初由前谷歌SRE Matt T.Proud开发,并转为一个研究项目。在Proud加入SoundCloud之后,他与另一位工程师Julius Volz合作开发了Prometheus。在2015年1月将其发布。
  • 与Borgmon一样,Prometheus主要为动态云和基于容器的微服务、服务和应用程序提供近乎实时的内省监控
  • Prometheus通常用来满足对云上服务和容器的监控,但也可以监控传统架构的资源。
  • Prometheus关注的是当下发生的事情,而不是追踪数周或数月前的数据。
    • 基于这个前提,即Prometheus大多数监控查询和警报都是从最近的(通常是一天内的)数据中生成的。Facebook在其内部时间序列数据库Gorilla的论文中验证了这一观点。Facebook发现85%的查询是针对26小时内的数据。
    • Prometheus假定你尝试修复的问题可能是最近出现的,因此最有价值的是最近时间的数据,这反映在强大的查询语言和通常有限的监控数据保留期上。
  • Prometheus由开源编程语言Go编写,并且是在Apache 2.0许可证下授权的。它孵化于云原生计算基金会(Cloud Native Computing Foundation)。

2、Prometheus架构和原理

  • Prometheus的工作原理是从应用程序中抓取或拉取时间序列数据。(Prometheus主要使用pull方式(拉取),但它也支持推送
    • Prometheus还有一个推送网关(push gateway),通常用于接收短期作业生成的指标数据的,并支持由Prometheus Server进行指标拉取操作。例如,来自无法拉取的目标数据(如临时作业或者防火墙后面的目标)。
  • 时间序列数据通常由应用程序本身通过客户端库或称为exporter(导出器)的代理来作为HTTP端点暴露。
    • 目前已经存在很多exporter和客户端库,支持多种编程语言、框架和开源应用程序,如Apache、Web服务器和MySQL数据库等。
  • Prometheus的架构及其一些生态系统组件如图2-1所示。

  • Prometheus生态组件:

    • Prometheus server:用于收集和存储时间序列数据。
      • Service Discovery:动态发现待监控的Target,从而完成监控配置的重要组件,在容器化环境中尤为重要。该组件目前由Prometheus Server内建支持。
    • Client Libraries:客户端库,为应用程序开发Instrumentation功能提供便捷途径。
    • Exporter:输出被监控组件信息的HTTP接口统称为Exporter(导出器)。
      • Exporter是Prometheus系统中重要的组成部分。收集监控样本数据都是由Exporter完成的。Exporter可以是一个独立运行的进程,对外提供一个用于获取监控数据的HTTP服务。Prometheus server只需要定时通过这些Exporter提供的HTTP服务获取监控数据即可。
      • Exporter类似传统意义上的agent(不监控目标上的进程),区别是Exporter不会主动推送监控数据到Prometheus server。
      • 目前大部分常用组件的监控信息都是由Exporter提供的,比如Nginx、MySQL、Linux系统信息(包括磁盘、内存、CPU、网络等)。
    • Alertmanager:从Prometheus Server接收到“告警通知”后,通过去重、分组、路由等预处理后将告警信息发送给用户。
    • Data Visualization:Prometheus Web UI(Prometheus Server内建),及Grafana等。
  • Prometheus工作流程如下
    • (1)Prometheus服务器周期性地或在设定的时间段内,可以通过以下方式获取内容。
      • 从已经配置好的job或者exporter中拉取metric。
      • 接收从Pushgateway推送过来的metric。
      • 从其他的Prometheus服务器中拉取metric。
    • (2)Prometheus服务器获取到数据后存储在本地(也可以选择远端存储),通过一定规则对数据进行清理和整理,并且把结果存储到新的时间序列中。
    • (3)Prometheus服务器定时查询已经定义好的规则,若发现满足定义的触发条件,便将alert信息推送至已配置好的Alertmanager。
    • (4)Alertmanager收到alert信息后,根据配置文件对接收到的alert信息进行处理(聚合、去重、降噪),然后将它们转换为网页、电子邮件和其他通知方式发出告警。
    • (5)通过PromQL或其他API可视化地展示收集的数据,例如自带Prometheus Web UI、Grafana可视化收集查询数据等。

1、指标收集

  • Prometheus称可以抓取指标的源为端点(endpoint)。端点通常对应单个进程、主机、服务或应用程序。
  • 为了抓取端点数据,Prometheus定义了名为目标(target)的配置。这是执行抓取所需的信息——例如,如何进行连接,要应用哪些元数据,连接需要哪些身份验证,或者定义抓取将如何执行的其他信息。
  • 一组目标被称为作业(job)。作业通常是具有相同角色的目标组——例如,负载均衡器后面的Apache服务器集群,它们实际上是一组相似的进程。
  • 生成的时间序列数据将被收集并存储在Prometheus服务器,也可以设置从服务器发送数据到外部存储器或其他时间序列数据库。

2、服务发现

  • 如何自动发现要监控的资源,可以通过多种方式:
    • 用户提供的静态资源列表。
    • 基于文件的发现。例如,可以使用配置管理工具在Prometheus中自动更新并生成资源列表。
    • 自动发现。例如,查询Consul等数据存储,在Amazon或Google中运行实例,或使用DNS SRV记录来生成资源列表。

3、聚合和告警

  • 服务器可以查询和聚合时间序列数据并创建规则来记录常用的查询和聚合,这样就不需要重复创建常用的聚合了。
    • 允许你从现有时间序列中创建新的时间序列,例如,计算变化率和比率,或者产生类似求和等聚合。
    • 预计算可能比每次需要时运行查询的性能更好。
  • Prometheus可以定义告警规则,即在满足特定条件时触发告警的标准。例如,有的资源的时间序列数据显示异常的CPU使用率。
  • Prometheus服务器没有内置告警工具,而是将告警从Prometheus服务器推送给名为Alertmanager(告警管理器)的独立服务器。
  • Alertmanager可以管理、合并并分发告警到不同目的地。例如,它可以在发出告警时发送电子邮件,并能够防止重复发送。

4、查询数据

  • Prometheus服务器还自带了一套内置的查询语言PromQL一个表达式浏览器(如图2-2所示)以及一个图形界面

5、独立自主

  • 每个Prometheus服务器都被设计成尽可能地独立自主,旨在支持扩展到数千台主机的数百万个时间序列的规模。数据存储格式被设计为尽可能降低磁盘的使用率,并在查询和聚合期间快速检索时间序列数据。
  • 为了速度和可靠性,建议Prometheus服务器充分使用内存(Prometheus在内存中做很多事)和SSD磁盘

6、冗余和高可用

  • 冗余和高可用侧重弹性,而不是数据持久
  • 建议将Prometheus服务器部署成集群,而不是仅部署一个单体Prometheus服务器。
  • 如果要部署高可用HA模式,则可以使用两个或多个配置相同的Prometheus服务器来收集时间序列数据,并且所有生成的告警都由高可用的Alertmanager集群来处理,这样可以删除重复的告警。
  • Prometheus冗余架构如图2-3所示。

7、可视化

  • 可视化是Prometheus内置的表达式浏览器提供的,并可以与开源仪表板Grafana配合使用。此外,Prometheus也支持其他仪表板。

3、Prometheus数据模型

  • Prometheus将所有数据存储为时间序列(time series)数据,每个时间序列数据都是有带时间戳的数据流,数据流由其指标(metric)名称一组键值对(也称为标签(label))唯一标识,即不同的标签代表不同的时间序列。
  • 可以基于这些标签很容易地对监控数据进行聚合、过滤和整理。除了存储的时间序列,Prometheus还可以通过查询结果产生临时的派生时间序列。

3.1、指标的组成

1、metric(指标)

  • 指标:监控目标系统测量特征,可以理解为定义了某个监控指标类型名称。
    • 指标是随时间将数据点链接在一起的标识符,是Prometheus的核心概念之一。
    • Prometheus会将指标存储在其时间序列数据库中,可以对它们进行查询操作,以了解被监控目标随时间的变化情况。
    • 指标名称可以由ASCII字母、数字、下划线和冒号组成,但要以字母开头。注意:冒号“:”是为用户定义的记录规则保留的。
    • 当有多个服务公开相同的指标时,为了对其进行区别,需要添加Label内容。
  • 指标由以下几个字段组成:
    • 指标名称。
    • 任意数量的标签,当然也可以是零个,表示为键值(key value)数组。
    • 当前指标值。
    • 可选的指标标准时间戳。

示例:

//go_gc_duration_second是指标名称,类似quantile="0.75"的是标签,其后是指标值
go_gc_duration_seconds{quantile="0"} 2.4516e-05
go_gc_duration_seconds{quantile="0.25"} 5.2919e-05
go_gc_duration_seconds{quantile="0.5"} 8.8498e-05
go_gc_duration_seconds{quantile="0.75"} 0.000113146
go_gc_duration_seconds{quantile="1"} 0.000708196

2、label(标签)

  • 标签:支持Prometheus的维度数据模型,是一个关键部分。
    • 标签名称可以包含ASCII字母、数字和下划线,需要以字母开头。以__(双下划线)开头的标签名称,只能在系统内部使用。
    • 标签值可以是任何UTF-8字符,也可以为空,但是在Prometheus服务器中,标签值为空可能令人困惑,因为看起来就像没有这个标签一样。
  • 时间序列由指标名称和标签唯一标识(尽管从技术上讲,指标名称本身也是名为__name__的标签)。
    • 更改任何标签值,包括添加或删除标签,都将创建一个新的时间序列。
  • Prometheus可以对标签进行查询,可以筛选出一个时间序列、一组时间序列或所有相关的时间序列。
  • 标签有两大类:插桩标签(instrumentation label)和目标标签(target label)。
    • 插桩标签来自被监控的资源。例如,对于与HTTP相关的时间序列,标签可能显示所使用的特定HTTP动词。这些特定的标签在由诸如客户端或exporter抓取之前被添加到时间序列中。
    • 目标标签更多地与架构相关,它们可能会标识时间序列产生的数据中心。目标标签由Prometheus在抓取期间和之后添加。

3、sample(样本)

  • 样本:时间序列的实际值(指标值),每个样本包括两两部分:
    • 一个float64类型的数值(value)。
    • 一个毫秒精度的时间戳(timestamp)。
  • 对于没有按照顺序收集的样本,Prometheus会将其丢弃。

4、notation(符号)

  • Prometheus将时间序列表示为符号(notation):
<time_series_name>{<label_name>=<label_value>, ...}

示例:

  • 一般所有时间序列都有一个instance标签(标识源主机或应用程序)以及一个job标签(表示抓取特定时间序列的作业名称)。
total_wabsite_visits{site="MegaApp", location="NJ", instance="webserver", job="web"}
  • 一个监控指标名称为api_http_requests_total,标签为method="POST"和handler="/messages"的时间序列
api_http_requests_total{method="POST", handler="/messages"}

3.2、Metric的四种类型

1、Counter(计数器)

  • Counter是最常用的指标类型,是一个严格的单调递增指标,有如下特点:
    • 其值从0开始只能增加,不会减少,可以理解为一个计数器,一种累加型的指标。
    • 重启进程后,会被重置,例如在微服务架构中,服务实例是短暂的,在滚动更新、自动缩放等操作时,计数器就会被重置为0。
  • 该指标类型通常用于跟踪事件的数量或大小,可以用它来记录服务请求次数、任务完成数、错误发生次数。常用的场景有接口请求次数、操作重试次数和消息队列数量等。
  • 在实际应用场景中,大部分指标为Counter类型,因为该类型不会在两次采集间隔中丢失信息,所以它是推荐使用比较多的指标类型。

示例:

  • 对于命名Counter类指标的最佳做法是使用_total后缀,例如,用户和系统CPU总时间监控指标counter类型如下。
# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.
# TYPE process_cpu_seconds_total counter
process_cpu_seconds_total 1.6

2、Gauge(仪表盘)

  • Gauge类型的指标是一种常规指标,反映系统当前状态,是一个瞬时测量值,有如下特点:
    • 测量值是一个瞬时的数据,其值可以任意增加或减少。
    • 重启进程后,会被重置。
  • Gauge类指标通常可以用来记录CPU使用情况、内存使用量、磁盘当前和已经使用的空间容量、网络使用变化、温度变化、业务类游戏在线人数统计和订单数量统计等等。
  • Gauge类型指标适合记录那些无规律变化的数据,而且两次采集之间可能会丢失某些变化数值,当然随着时间周期的粒度变大,丢失关键变化数值的情况也会增多。

示例:

  • 系统可用内存
# HELP node_memory_MemAvailable_bytes Memory information flield MemAvailable_bytes.
# TYPE node_memory_MemAvailable_bytes gauge
node_memory_MemAvailable_bytes 1.551921152e+09

3、Histogram(直方图)

  • 直方图:用于表示在一段时间范围内对数据进行采样,对指定区间以及总数进行分组统计。典型的应用有请求持续时间、响应大小等等。
  • 在Prometheus系统中的查询语言中,它有三种作用:
    • 对每个采样点进行统计,对应到各个分类值中及bucket(可称为“桶”)。
    • 对每个采样点值累计和(sum)。
    • 对采样点的次数累计和(count)。
  • 例如,采用对应的以下几种方式产生直方图(假设监控指标名称为<basename>):
    • 按bucket累计计数,相当于<basename>_bucket{le="<上限边界>"},此值为小于等于上限边界的所有采样点数量。
    • 样本累计总和,相当于<basename>_sum。
    • 样本累计次数总和,相当于<basename>_count。
  • 具有基本监控指标标准名称的直方图,在scrape期间暴露多个时间序列。实践中,直方图将会创建一个额外的带有_bucket后缀的指标,在Prometheus Server返回的自身样本数据中,可以找到该类型的Histogram的监控指标:
# HELP prometheus_http_request_duration_seconds Histogram of latencies for HTTP requests.
# TYPE prometheus_http_request_duration_seconds histogram
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.1"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.2"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="0.4"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="1"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="3"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="8"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="20"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="60"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="120"} 1
prometheus_http_request_duration_seconds_bucket{handler="/",le="+Inf"} 1
prometheus_http_request_duration_seconds_sum{handler="/"} 4.4504e-05
prometheus_http_request_duration_seconds_count{handler="/"} 1
  • 关于Histogram类型,使用的查询会对服务器的CPU有一定的消耗,最直观的反映就是查询结果的返回耗时情况。需要记住,每个独特的标签组合都被视为一个单独的时间序列,因此,通常的做法是尽量保持bucket的数量较小,以及直方图上的其他标签数量较少。

4、Summary(概率图)

  • 概率图:用于跟踪与时间相关的数据。典型的应用包括请求持续时间、响应大小等。
    • Summary同样提供样本的count和sum功能;还提供quantiles功能,可以按百分比划分跟踪结果,例如,quantile取值0.95,表示取样本里面的95%数据。
    • Histogram需要通过<basename>_bucket计算quantile,而Summary直接存储了quantile的值。
  • 同样,Summary在scrape期间暴露多个时间序列,例如以下是Golang垃圾收集器摘要中的summary类型:
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 2.4516e-05
go_gc_duration_seconds{quantile="0.25"} 6.2323e-05
go_gc_duration_seconds{quantile="0.5"} 9.2648e-05
go_gc_duration_seconds{quantile="0.75"} 0.000123879
go_gc_duration_seconds{quantile="1"} 0.000708196
go_gc_duration_seconds_sum 0.014005052
go_gc_duration_seconds_count 135

4、安全模型

  • Prometheus可以通过多种方式进行配置和部署,关于安全有以下两个假设:
    • 不受信任的用户能够访问Prometheus服务器的HTTP API,从而访问数据库中的所有数据。
      • 从Prometheus 2.0开始,默认情况下某些HTTP API的管理功能被禁用。
    • 只有受信任的用户才能访问Prometheus命令行、配置文件、规则文件和运行时配置Prometheus及其组件。
  • Prometheus及其组件不提供任何服务器端的身份验证、授权或加密
  • 因此,如果你想要进行身份验证、授权或加密,则需要自己实施安全控制。例如,通过反向代理访问Prometheus服务器或者正向代理exporter。

5、Prometheus优缺点

  • Prometheus是一个开源的完整监控解决方案,对传统监控系统的测试和告警模型进行了彻底的颠覆,形成了基于集中化的规则计算、统一分析和告警管理的新模型。相比于传统监控系统,Prometheus具有大量优点。

5.1、Prometheus优点

1、易管理性

  • Prometheus核心部分只有一个单独的二进制文件,不存在任何的第三方依赖(数据库、缓存等)。唯一需要的就是本地磁盘,因此不会有潜在关联的故障风险。
  • Prometheus基于Pull模型的架构方式,可以在任何环境(本地主机、开发环境、测试环境等)搭建监控系统。对于一些复杂的情况,还可以结合Prometheus的服务发现能力动态地管理监控目标。

2、更契合的架构

  • 传统监控系统大多采用Push模型架构,客户端需要在服务端上进行注册及监控数据推送。
  • 而Prometheus采用的Pull模型架构,具体的数据拉取行为是完全由服务端决定的。服务端可以基于某种服务发现机制自动发现监控对象,多个服务端之间能够通过集群机制实现数据分片。Push模型想要实现相同的功能,通常需要客户端进行配合,而这在微服务架构里是比较困难的。Prometheus建议用户监控服务的内部状态,可以基于Prometheus提供的丰富Client库,很容易地在应用程序中添加支持Prometheus的监控指标,用户可以获取服务和应用内部真正的运行状态信息。

3、灵活的数据模型

  • 在Prometheus里,监控数据是由值、时间戳和标签表组成的,其中,监控数据的源信息完全记录在标签表里;同时,Prometheus支持在监控数据采集阶段对监控数据的标签表进行修改,这使其具备强大的扩展能力。

4、良好的性能,强大的查询能力

  • 在监控系统中大量的监控任务必然产生大量的数据,Prometheus不仅可以高效地处理这些数据,还提供了PromBench基准测试。在硬件资源满足的情况下,对于单实例Prometheus可以处理数以百万的监控指标以及数十万个数据点。
  • Prometheus内置了一套强大的数据查询语言PromQL。PromQL提供了大量的数据计算函数,大部分情况下用户都可以直接通过PromQL从Prometheus里查询到需要的聚合数据。PromQL也可应用于数据可视化(如Grafana)以及事件告警。

5、可扩展性

  • Prometheus架构非常简单,可以在每个数据中心、每个团队中运行独立的Prometheus服务器实例。
  • 对于大型环境,Prometheus支持联邦(federation)集群方式,把多个Prometheus实例集成单个逻辑集群。
  • 当单个Prometheus服务器实例处理的任务量过大时,通过功能分区(sharding)结合联邦集群可以对其进行扩展。

6、健全的生态,开放、易于与第三方系统集成

  • 使用Prometheus可以快速搭建监控服务,并且可以方便地在应用程序中进行集成。目前已支持Java、JMX、Python、Go、Ruby、.Net、Node.js等语言的客户端软件开发工具(SDK),基于这些SDK可以很容易地将应用程序纳入到Prometheus的监控中,或者开发自己的监控数据收集程序。
  • 同时,Prometheus还支持与其他监控系统进行集成,如Graphite、Statsd、Collected、Scollector、muini、Nagios等。甚至可以在不使用Prometheus的情况下,采用Prometheus的clientlibrary使应用程序支持监控数据采集。
  • Prometheus社区提供了大量第三方实现的监控数据采集支持,如JMX、CloudWatch、EC2、MySQL、PostgresSQL、Haskell、Bash、SNMP、Consul、Haproxy、Mesos、Bind、CouchDB、Django、Memcached、RabbitMQ、Redis、RethinkDB、Rsyslog等。

7、可视化

  • Prometheus服务器中自带了一个Prometheus UI,通过这个UI可以方便地对数据进行查询,并且支持直接以图形化的形式展示数据。最新的Grafana可视化工具已经完美支持Prometheus,基于Grafana可以创建精美、炫酷的监控视图。基于Prometheus提供的API,还可以实现自己的监控可视化UI。

5.2、Prometheus缺点

  • Prometheus虽然具有上述优势,但其仍然无法满足微服务监控的所有需求,具体的不足之处有:
    • 仅适用于监控维度,要用于日志监控、分布式追踪等还有待完善。
    • 告警规则和告警联系人仅支持静态文件配置。
    • 原生支持的数据聚合函数有限,且不支持扩展。
#                                                                                                                        #
posted @ 2022-06-23 01:02  麦恒  阅读(103)  评论(0编辑  收藏  举报