监控-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 server:用于收集和存储时间序列数据。
- 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服务器周期性地或在设定的时间段内,可以通过以下方式获取内容。
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服务器的HTTP API,从而访问数据库中的所有数据。
- 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虽然具有上述优势,但其仍然无法满足微服务监控的所有需求,具体的不足之处有:
- 仅适用于监控维度,要用于日志监控、分布式追踪等还有待完善。
- 告警规则和告警联系人仅支持静态文件配置。
- 原生支持的数据聚合函数有限,且不支持扩展。
# #