Prometheus 3.0 Beta 版本发布

Prometheus 团队很自豪地宣布 Prometheus 3.0-beta 版本现已发布!您可以在这里下载。按照惯例,我们**不建议**用户在关键生产系统上安装 Prometheus 3.0-beta,但我们希望每个人都能试用它并发现错误。

总的来说,唯一破坏性的更改是删除了弃用的功能标志。Prometheus 团队努力确保向后兼容性,不破坏现有安装,因此以下描述的所有新功能都在现有功能之上构建。大多数用户应该能够在不进行任何配置更改的情况下直接试用 Prometheus 3.0。

新增功能

自 Prometheus 2.0 发布以来的 7 年中,累计了超过 7500 次提交,其中新功能和修复的细节太多,无法一一列举,但我们想重点介绍一些重大且破坏性的更改。我们需要社区中的每个人都试用它们,并报告您可能遇到的任何问题。我们收到的反馈越多,最终的 3.0 版本就越稳定。

新的 UI

Prometheus 3.0 中的一大亮点是默认启用的全新 UI。

New UI query page

UI 已经完全重写,减少了混乱,更现代的外观和感觉,新增了PromLens风格的树状视图等功能,并且使用更现代的技术堆栈,将使未来的维护更加容易。

Julius 在 PromLabs 博客上发表的详细文章中,您可以了解更多关于新 UI 的信息。用户可以通过使用 old-ui 功能标志临时启用旧的 UI。由于新的 UI 尚未经过实战检验,因此也可能存在一些错误。如果您发现任何错误,请在 GitHub 上报告它们.

远程写入 2.0

远程写入 2.0 在之前的协议版本的基础上进行了迭代,增加了对包括元数据、示例、创建时间戳和原生直方图在内的一系列新元素的原生支持。它还使用字符串驻留,在压缩和解压缩时减少了有效载荷大小和 CPU 使用率。更多详细信息请点击此处.

OpenTelemetry 支持

Prometheus 旨在成为存储 OpenTelemetry 指标的默认选择,3.0 包含一些重大的新功能,使其作为 OpenTelemetry 指标数据的存储后端更加出色。

UTF-8

默认情况下,Prometheus 将允许在指标和标签名称以及标签值中使用所有有效的 UTF-8 字符,这在 2.x 版本中一直如此。

用户需要确保他们的指标生产者被配置为传递 UTF-8 名称,如果任一方不支持 UTF-8,则指标名称将使用传统的下划线替换方法进行转义。PromQL 查询可以使用新的引号语法来检索 UTF-8 指标,或者用户可以手动指定 __name__ 标签名称。

并非所有语言绑定都已更新以支持 UTF-8,但主要的 Go 库已经更新了。

OTLP 摄取

Prometheus 可以配置为 OTLP 指标协议的原生接收器,在 /api/v1/otlp/v1/metrics 端点接收 OTLP 指标。

原生直方图

原生直方图是 Prometheus 指标类型,它提供了一种比经典直方图更高效、成本更低的替代方案。原生直方图不需要根据数据集选择(并可能需要更新)桶边界,而是基于指数增长预先设置桶边界。

原生直方图目前处于实验阶段,尚未默认启用,可以通过传递 --enable-feature=native-histograms 来开启。原生直方图的某些方面,例如文本格式和访问器函数/运算符,仍在积极设计中。

其他破坏性更改

以下功能标志已被删除,改为默认启用。应从配置中删除对这些标志的引用,并且在 Prometheus 从 3.0 版本开始将被忽略。

  • promql-at-modifier
  • promql-negative-offset
  • remote-write-receiver
  • no-scrape-default-port
  • new-service-discovery-manager

范围选择现在是左开右闭,这将避免在极少数情况下包含比预期更多的点。

代理模式现在已稳定,并拥有自己的配置标志,而不是功能标志。

我们对 OpenTelemetry 的承诺

OpenTelemetry 项目是一个可观察性框架和工具包,旨在创建和管理遥测数据,例如跟踪、指标和日志。由于其信号之间的一致规范以及减少供应商锁定(这是我们感到兴奋的一点)的承诺,它正在得到广泛采用。

回顾 2023 年

在过去几年中,我们与 OpenTelemetry 社区合作,确保 OpenTelemetry 和 Prometheus 可以双向支持彼此。这导致了在两个系统之间转换的官方规范草案,以及允许您将 Prometheus 指标摄取到 OpenTelemetry Collector 以及反之亦然的实现。

从那时起,我们花了很多时间了解OpenTelemetry 用户在将他们的指标存储在 Prometheus 中时面临的挑战,并在此基础上探索了如何解决这些挑战。一些提出的更改需要仔细考虑,以避免破坏任一方的操作承诺,例如支持推送和拉取。在 2023 年柏林 PromCon 上,我们尝试在其中一次演讲中总结我们的想法。

在我们的柏林开发者峰会上,我们大部分时间都在深入讨论这些更改以及我们对 OpenTelemetry 的总体立场,并且普遍共识是,我们希望“成为 OpenTelemetry 指标的默认存储库”

我们已经组建了一个核心开发人员团队来领导这项工作,我们将在 2024 年发布一个具有 OTel 支持作为其最重要功能之一的 Prometheus 3.0。以下是 2024 年即将发布的功能的抢先看。

未来一年

OTLP 摄取 GA

2023 年 9 月 6 日发布的 Prometheus v2.47.0中,我们为 Prometheus 添加了对 OTLP 摄取的实验性支持。我们一直在不断改进它,并计划添加对陈旧性的支持,并将其作为一项稳定功能。我们还将标记对乱序摄取的支持作为稳定功能。这还涉及 GA-ing 对原生/指数直方图的支持。

支持 UTF-8 指标和标签名称

OpenTelemetry 语义约定推动使用 “.” 作为命名空间字符。例如,http.server.request.duration。但是,Prometheus 目前要求使用更有限的字符集,这意味着在将指标摄取到 Prometheus 时,我们会将其转换为 http_server_request_duration

这会导致不必要的差异,我们正在通过为所有标签和指标名称添加 UTF-8 支持来消除这种限制。进度在此跟踪

对资源属性的原生支持

OpenTelemetry 区分指标属性(标识指标本身的标签,例如 http.status_code)和资源属性(标识指标来源的标签,例如 k8s.pod.name),而 Prometheus 具有更扁平的标签模式。这会导致许多可用性问题,此处详细说明。

我们正在探索解决这个问题的多种解决方案,从多个方面(查询、用户体验、存储等),但我们的目标是使对资源属性进行过滤和分组变得非常容易。这是一项正在进行的工作,我们希望得到您的反馈和帮助!

生态系统中的 OTLP 导出

Prometheus 远程写入已得到大多数领先的可观察性项目和供应商的支持。但是,OpenTelemetry 协议 (OTLP) 越来越受欢迎,我们希望在整个 Prometheus 生态系统中支持它。

我们希望为 Prometheus 服务器、SDK 和导出器添加对它的支持。这意味着使用 Prometheus SDK 的任何服务也可以推送 OTLP,并且它将为 OpenTelemetry 用户解锁丰富的 Prometheus 导出器生态系统。

但是,我们打算保留并开发 OpenMetrics 公开格式作为 Prometheus 和基于拉取的使用场景的优化/简化格式。

Delta 时间性

OpenTelemetry 项目还支持Delta 时间性,它在可观察性生态系统中有一些用例。我们有很多 Prometheus 用户出于各种原因仍在运行 statsd 并使用 statsd_exporter。

我们希望在 Prometheus 服务器中支持 OpenTelemetry 的 Delta 时间性,并且正在努力实现它.

呼吁贡献!

如您所见,很多新的令人兴奋的功能即将出现在 Prometheus 中!如果您在两个最相关的开源可观察性项目之间工作的交叉点中工作听起来很有挑战性和趣味,我们很乐意让您加入!

今年,治理方面也有一些变化正在进行中,这将使成为维护者的过程比以往更容易!如果您曾经想对 Prometheus 产生影响,现在是一个绝佳的时机。

我们的首要目标始终是尽可能公开透明地介绍我们如何组织所有上述工作,以便您也可以做出贡献。我们正在寻找贡献者来支持这项工作并帮助实现这些功能。查看Prometheus 3.0 公开看板Prometheus OTel 支持里程碑,以跟踪功能开发的进度,并了解您可以做出贡献的方式。

结论

一些提出的更改很大且具有侵入性,或者涉及对 Prometheus 的原始数据模型的根本改变。但是,我们计划逐步引入这些更改,以便 Prometheus 3.0 不会出现重大破坏性更改,大多数用户可以无缝升级。

我们很高兴开启 Prometheus 的新篇章,并期待您对建议的更改提出反馈。

PromCon Europe 2023 的日程表现已公布

PromCon Europe 是第八届完全专注于 Prometheus 监控系统的会议

德国柏林 - 2023 年 9 月 1 日 - CNCF 和 Prometheus 团队发布了为期两天的单轨 PromCon Europe 2023 会议日程,该会议将于 2023 年 9 月 28 日至 29 日在德国柏林举行。与会者将能够从 21 个完整长度(25 分钟)的会议中选择,以及最多 20 个时长五分钟的闪电演讲,涵盖与 Prometheus 相关的各种主题。

PromCon 现已举办到第八届,它将来自世界各地的 Prometheus 用户和开发者聚集在一起,交流使用 Prometheus 获得的知识、最佳实践和经验。节目委员会审查了 66 份提交内容,将提供关于当今 Prometheus 周围最紧迫主题的新鲜和信息丰富的见解。

"我们非常高兴 PromCon 回到柏林。Prometheus 是 2012 年在柏林 Soundcloud 启动的。第一次 PromCon 举办地也是柏林,后来搬到了慕尼黑。今年,我们将接待约 300 名与会者,活动地点位于柏林弗里德里希斯海因的 Radialsystem。柏林有一个充满活力的 Prometheus 社区,许多 Prometheus 团队成员都住在附近。这是一个与 Prometheus 家庭成员建立联系和交流的好机会,他们都对系统和服务监控充满热情,”Polar Signals 高级软件工程师兼今年 PromCon 项目委员会负责人 Matthias Loibl 表示。“这将是一次很棒的活动,可以了解 Prometheus 团队本身的最新进展,并近距离接触 Prometheus 的一些大型用户。”

社区策划的日程将包括来自开源社区成员的会议,包括

有关 PromCon Europe 2023 的完整节目,请访问 日程

注册

通过 9 月 25 日,以 350 美元的标准价格注册 现场参会。场地可容纳 300 名与会者,所以不要犹豫!

感谢我们的赞助商

PromCon Europe 2023 的举办得益于围绕 Prometheus 的优秀社区以及我们钻石赞助商 Grafana Labs、白金赞助商 Red Hat 以及许多其他黄金赞助商和初创企业赞助商的支持。今年的活动由 Polar Signals 和 CNCF 组织。

观看 Prometheus 纪录片

联系

Jessie Adams-Shore - Linux 基金会 - [email protected]

PromCon 组织者 - [email protected]

关于 Prometheus 2.43 字符串标签优化的常见问题解答

Prometheus 2.43 刚刚发布,它带来了一些令人兴奋的功能和增强功能。其中一项重大改进是 stringlabels 版本,它使用新的标签数据结构。这篇文章将回答关于 2.43 版本和 stringlabels 优化的常见问题解答。

什么是 stringlabels 版本?

stringlabels 版本是 Prometheus 2.43 版本,它使用新的标签数据结构。它将所有标签/值存储在一个字符串中,从而导致更小的堆大小,并且在大多数情况下可以加快速度。这些优化没有在默认二进制文件中提供,需要使用 Go 标签 stringlabels 编译 Prometheus。

为什么没有使用可以切换的功能标志?

我们考虑过使用功能标志,但它会带来不值得的内存开销。因此,我们决定为那些有兴趣在生产环境中测试和衡量收益的人提供一个包含这些优化的单独版本。

这些优化何时会普遍可用?

这些优化将在即将发布的 Prometheus 2.44 版本中默认提供。

如何获取 2.43 版本?

Prometheus 2.43 版本 在官方 Prometheus GitHub 版本页面上提供,用户可以直接从那里下载二进制文件。此外,Docker 映像也适用于那些喜欢使用容器的用户。

字符串标签优化不包含在这些默认二进制文件中。要使用此优化,用户需要下载 2.43.0+stringlabels 版本 二进制文件或 标记为 v2.43.0-stringlabels 的 Docker 映像

为什么版本是 v2.43.0+stringlabels,而 Docker 标签是 v2.43.0-stringlabels

在语义版本控制中,加号 (+) 用于表示构建元数据。因此,包含 stringlabels 优化的 Prometheus 2.43 版本被命名为 2.43.0+stringlabels,表示它包含实验性的 stringlabels 功能。但是,Docker 标签不允许在名称中使用加号。因此,加号被替换为连字符 (-) 以使 Docker 标签为 v2.43.0-stringlabels。这允许 Docker 标签通过下游项目的语义版本控制检查,例如 Prometheus 运算符。

Prometheus 2.43 版本中还有哪些值得注意的功能?

除了 stringlabels 优化之外,Prometheus 2.43 版本还带来了许多新功能和增强功能。一些重要的补充包括

  • 我们添加了对 scrape_config_files 的支持,以包含来自不同文件的抓取配置。这使得管理和组织配置变得更加容易。
  • HTTP 客户端现在包括两个新的配置选项:no_proxy 用于从代理请求中排除 URL,以及 proxy_from_environment 用于从环境变量中读取代理。这些功能使管理 HTTP 客户端在不同环境中的行为变得更加容易。

您可以在 完整变更日志 中了解更多有关功能和错误修复的信息。

介绍 Prometheus 代理模式,一种高效且云原生化的指标转发方式

Bartek Płotka 自 2019 年起担任 Prometheus 维护者,同时也是 Red Hat 的首席软件工程师。CNCF Thanos 项目的合著者。CNCF 大使和 CNCF TAG 可观测性技术负责人。在他的业余时间,他与 O'Reilly 共同撰写了一本名为“高效 Go”的书。观点仅代表个人!

我个人喜欢 Prometheus 项目的地方,也是我加入团队的众多原因之一,就是该项目对目标的专注。Prometheus 一直致力于在提供实用、可靠、廉价且宝贵的基于指标的监控方面突破界限。Prometheus 超级稳定和强大的 API、查询语言和集成协议(例如远程写入和 OpenMetrics)使云原生计算基金会 (CNCF) 指标生态系统能够在这些坚实的基础上不断发展。结果是惊人的

  • 我们可以看到用于获取几乎所有内容的指标的社区导出器,例如 容器eBPFMinecraft 服务器统计信息,甚至 园艺时植物的健康状况
  • 如今,大多数人期望云原生软件具有 HTTP/HTTPS /metrics 端点,以便 Prometheus 可以抓取。这是 Google 内部秘密开发并在全球范围内由 Prometheus 项目开创的概念。
  • 可观测性范式发生了转变。我们看到 SRE 和开发人员从一开始就严重依赖指标,这提高了软件的弹性、可调试性和数据驱动决策!

最终,我们几乎看不到没有运行 Prometheus 的 Kubernetes 集群。

Prometheus 社区的强烈关注也使其他开源项目得以发展,以将 Prometheus 部署模型扩展到单个节点之外(例如 CortexThanos 等)。更不用说云供应商采用 Prometheus 的 API 和数据模型(例如 Amazon Managed PrometheusGoogle Cloud Managed PrometheusGrafana Cloud 等)。如果您想找出一个 Prometheus 项目如此成功的原因,那就是:专注于监控社区关注的事情

在这篇(冗长)博文中,我想要介绍一种新的运行 Prometheus 的操作模式,称为“代理”。它直接内置到 Prometheus 二进制文件中。代理模式会禁用一些 Prometheus 通常的功能,并针对抓取和远程写入到远程位置优化二进制文件。引入一种减少功能数量的模式可以实现新的使用模式。在这篇博文中,我将解释为什么它对于 CNCF 生态系统中的某些部署来说是一个改变游戏规则的模式。我对此超级兴奋!

转发用例的历史

Prometheus 的核心设计在整个项目生命周期中一直保持不变。受 Google 的 Borgmon 监控系统 的启发,您可以在想要监控的应用程序旁边部署一个 Prometheus 服务器,告诉 Prometheus 如何访问它们,并允许它定期抓取其指标的当前值。这种收集方法通常被称为“拉取模型”,是 使 Prometheus 变得轻量级且可靠 的核心原则。此外,它使应用程序检测和导出器变得非常简单,因为它们只需要提供一个简单的易于理解的 HTTP 端点,其中包含所有跟踪指标的当前值(以 OpenMetrics 格式)。所有这些都无需复杂的推送基础设施和非平凡的客户端库。总的来说,典型的简化 Prometheus 监控部署如下所示

Prometheus high-level view

这效果很好,多年来我们已经看到了数百万个这样的成功部署,它们处理了数千万个活动时间序列。其中一些用于更长时间的保留,例如两年左右。所有这些都允许查询、警报和记录对集群管理员和开发人员都有用的指标。

然而,云原生世界正在不断发展和演变。随着托管 Kubernetes 解决方案的增长以及按需创建的集群以秒为单位出现,我们现在终于能够将集群视为“牛群”,而不是“宠物”(换句话说,我们不再关心这些集群的单个实例)。在某些情况下,解决方案甚至不再具有集群的概念,例如 kcpFargate 和其他平台。

Yoda

另一个有趣的用例是边缘集群或网络的概念。随着电信、汽车和物联网设备等行业采用云原生技术,我们看到越来越多的资源有限的小型集群。这迫使所有数据(包括可观察性)都必须传输到远程、更大的集群,因为几乎无法在这些远程节点上存储数据。

这意味着什么?这意味着监控数据必须以某种方式聚合,并呈现给用户,有时甚至存储在全局级别。这通常被称为全局视图功能。

我们可以简单地考虑通过在全局级别部署 Prometheus 并跨远程网络抓取指标,或者将指标直接从应用程序推送到中心位置进行监控,来实现这一点。让我解释一下为什么两者通常都是非常糟糕的方案。

🔥 跨网络边界抓取可能会成为一项挑战,因为它会在监控管道中添加新的未知因素。本地拉取模型允许 Prometheus 准确地了解指标目标出现问题的具体原因和时间。可能是目标宕机、配置错误、重启、响应速度太慢而无法提供指标(例如 CPU 饱和)、服务发现无法发现、没有访问凭据,或者只是 DNS、网络或整个集群宕机。通过将我们的抓取器置于网络外部,我们可能会由于引入与单个目标无关的抓取不可靠性而丢失部分信息。除此之外,如果网络暂时宕机,我们可能会完全失去重要的可见性。请不要这样做。它不值得。(

🔥 将指标直接从应用程序推送到某个中心位置同样糟糕。特别是当您监控一个庞大的集群时,如果您看不到来自远程应用程序的指标,您将一无所知。应用程序是否宕机?我的接收器管道是否宕机?也许应用程序授权失败?也许它获取远程集群的 IP 地址失败?也许它太慢了?也许网络宕机?更糟糕的是,您可能甚至不知道某些应用程序目标的数据是否丢失。而且您并没有真正获得太多收益,因为您需要跟踪所有应该发送数据的对象的状况和状态。这种设计需要仔细分析,因为它很容易成为失败的根源。

注意: 无服务器函数和短暂容器通常是我们将从应用程序推送到中心位置作为解决方案的情况。然而,在这种情况下,我们指的是我们可能想要聚合到生命周期更长的时间序列的事件或指标片段。此主题已在此处进行讨论,欢迎您贡献并帮助我们更好地支持这些用例!

Prometheus 引入了三种支持全局视图用例的方法,每种方法都有其优缺点。让我们简要地介绍一下这些方法。它们在下图中以橙色显示。

Prometheus global view

  • 联邦是为聚合目的而引入的第一项功能。它允许全局级别的 Prometheus 服务器从叶子 Prometheus 抓取指标子集。这种“联邦”抓取减少了跨网络的某些未知因素,因为联邦端点公开的指标包含原始样本的时间戳。然而,它通常无法联邦所有指标,并且在较长的网络分区(分钟)期间不会丢失数据。
  • Prometheus 远程读取允许从远程 Prometheus 服务器的数据库中选择原始指标,而无需直接执行 PromQL 查询。您可以在全局级别部署 Prometheus 或其他解决方案(例如 Thanos)来对这些数据执行 PromQL 查询,同时从多个远程位置获取所需的指标。这非常强大,因为它允许您“本地”存储数据,并在需要时才访问。不幸的是,它也有缺点。如果没有诸如查询下推之类的功能,在极端情况下,我们需要拉取 GB 级别的压缩指标数据来回答一个单一查询。此外,如果存在网络分区,我们就会暂时失明。最后但同样重要的是,某些安全准则不允许入站流量,只允许出站流量。
  • 最后,我们有Prometheus 远程写入,它似乎是目前最受欢迎的选择。由于代理模式侧重于远程写入用例,因此让我们详细解释一下。

远程写入

Prometheus 远程写入协议允许我们将 Prometheus 收集的所有指标或部分指标转发(流式传输)到远程位置。您可以配置 Prometheus 将部分指标(如果需要,可以包含所有元数据和示例!)转发到一个或多个支持远程写入 API 的位置。事实上,Prometheus 支持同时接收和发送远程写入,因此您可以在全局级别部署 Prometheus 来接收该流并跨集群聚合数据。

虽然官方的Prometheus 远程写入 API 规范处于审查阶段,但生态系统已将远程写入协议作为默认指标导出协议。例如,Cortex、Thanos、OpenTelemetry 和 Amazon、Google、Grafana、Logz.io 等云服务都支持通过远程写入接收数据。

Prometheus 项目还为其 API 提供了官方合规性测试,例如,用于提供远程写入客户端功能的解决方案的远程写入发送器合规性。这是一种快速判断您是否正确实现该协议的绝佳方法。

从这样的抓取器流式传输数据通过允许您将指标数据存储在中心位置来实现全局视图用例。这也实现了关注点分离,这在应用程序由不同团队管理而可观察性或监控管道由其他团队管理的情况下非常有用。此外,这也是供应商选择使用远程写入的原因,他们希望尽可能地从客户那里卸载工作量。

等等,Bartek。您之前提到直接从应用程序推送指标并不是最佳方案!

没错,但最棒的是,即使使用远程写入,Prometheus 仍然使用拉取模型从应用程序收集指标,这使我们能够了解这些不同的故障模式。之后,我们将样本和序列批处理并导出,并将数据复制(推送)到远程写入端点,从而限制中心点所具有的监控未知因素的数量!

重要的是要注意,可靠且高效的远程写入实现是一个非凡的难题。Prometheus 社区花了大约三年时间才提出一个稳定且可扩展的实现。我们重新实现了 WAL(预写日志)几次,添加了内部队列、分片、智能回退等等。所有这些都对用户隐藏,用户可以享受高性能的流式传输或存储在中心位置的大量指标。

动手实践远程写入示例:Katacoda 教程

所有这些对于 Prometheus 来说都不是什么新鲜事。我们中的许多人已经使用 Prometheus 抓取所有需要的指标,并将所有或部分指标远程写入到远程位置。

假设您想尝试远程写入功能的动手实践体验。在这种情况下,我们推荐Thanos Katacoda 教程,它介绍了从 Prometheus 远程写入指标,该教程解释了 Prometheus 将所有指标转发到远程位置所需的所有步骤。它是免费的,只需注册一个帐户,就可以享受教程的乐趣!🤗

请注意,此示例使用 Thanos 的接收模式作为远程存储。现在,您可以使用许多其他与远程写入 API 兼容的项目。

那么,如果远程写入效果很好,为什么我们还要为 Prometheus 添加一个特殊的代理模式呢?

Prometheus 代理模式

从 Prometheus v2.32.0(下一个版本)开始,每个人都可以使用实验性的 --enable-feature=agent 标志运行 Prometheus 二进制文件。如果您想在发布之前尝试它,请随意使用Prometheus v2.32.0-beta.0 或使用我们的 quay.io/prometheus/prometheus:v2.32.0-beta.0 镜像。

代理模式针对远程写入用例对 Prometheus 进行了优化。它禁用了查询、警报和本地存储,并将其替换为定制的 TSDB WAL。其他一切保持不变:抓取逻辑、服务发现和相关配置。如果您只想将数据转发到远程 Prometheus 服务器或任何其他支持远程写入的项目,可以使用它作为 Prometheus 的直接替代品。本质上,它看起来像这样

Prometheus agent

Prometheus 代理最棒的地方在于它是内置于 Prometheus 中的。相同的抓取 API、相同的语义、相同的配置和发现机制。

如果您计划不本地查询或警报数据,并流式传输外部指标,那么使用代理模式有什么好处呢?有一些好处。

首先,效率。我们定制的代理 TSDB WAL 在成功写入后立即删除数据。如果它无法到达远程端点,它会将数据暂时持久存储到磁盘上,直到远程端点恢复在线。目前,这仅限于两小时缓冲区,类似于非代理 Prometheus,希望很快就能解除限制。这意味着我们不需要在内存中构建数据块。我们不需要维护一个完整的索引以进行查询。本质上,代理模式使用的是正常 Prometheus 服务器在类似情况下使用的资源的一小部分。

这种效率重要吗?当然!正如我们提到的,对于某些部署来说,边缘集群上的每 GB 内存和每个 CPU 内核都很重要。另一方面,使用指标进行监控的范式在如今已经相当成熟了。这意味着,对于相同的成本,您能够发送的具有更多基数的相关指标越多越好。

注意: 随着代理模式的引入,原始的 Prometheus 服务器模式仍然是推荐的、稳定且维护的模式。使用远程存储的代理模式会带来额外的复杂性。请谨慎使用。

其次,新代理模式的优势在于它使摄取的横向扩展变得更加容易。这是我最激动的一点。让我解释一下为什么。

梦想:可自动扩展的指标摄取

一个真正可自动扩展的抓取解决方案需要基于指标目标的数量和它们公开的指标数量。我们抓取的数据越多,我们就自动部署的 Prometheus 实例越多。如果目标数量或其指标数量下降,我们可以缩减规模并删除一些实例。这将消除手动调整 Prometheus 大小和停止在集群暂时较小时过度分配 Prometheus 的需要。

仅使用服务器模式下的 Prometheus,这很难实现。这是因为服务器模式下的 Prometheus 是有状态的。收集到的任何内容都会原样保留在一个地方。这意味着缩减规模过程需要在终止之前将收集到的数据备份到现有实例。然后,我们会遇到重叠抓取、误导性的陈旧标记等等问题。

除此之外,我们还需要一些能够跨所有实例聚合所有样本的全局视图查询(例如 Thanos Query 或 Promxy)。最后但同样重要的是,服务器模式下的 Prometheus 的资源使用情况取决于比摄取更多的因素。还有警报、记录、查询、压缩、远程写入等等,它们可能需要更多或更少的资源,而与指标目标的数量无关。

代理模式本质上将发现、抓取和远程写入迁移到一个独立的微服务。这允许专注于摄取的集中运营模型。因此,代理模式下的 Prometheus 基本上是无状态的。是的,为了避免指标丢失,我们需要部署一对高可用性的代理并为它们附加一个持久磁盘。但从技术角度来说,如果我们有数千个指标目标(例如容器),我们可以部署多个 Prometheus 代理,并安全地更改哪个副本正在抓取哪些目标。这是因为,最终,所有样本都将被推送到同一个中央存储。

总的来说,代理模式下的 Prometheus 使基于 Prometheus 的抓取能够轻松实现水平自动扩展功能,从而能够应对指标目标的动态变化。这绝对是我们将来会与 Prometheus Kubernetes 运营商 社区一起关注的内容。

现在让我们看看 Prometheus 中当前实现的代理模式状态。它可以使用了吗?

代理模式已在规模上得到验证

Prometheus 的下一个版本将包含代理模式作为实验性功能。磁盘上的标志、API 和 WAL 格式可能会发生变化。但由于 Grafana Labs' 的开源工作,该实现的性能已经过实战检验。

我们代理的自定义 WAL 的初始实现受当前 Prometheus 服务器的 TSDB WAL 启发,由 Robert Fratto 在 2019 年创建,在 Prometheus 维护者 Tom Wilkie 的指导下。它随后被用于一个开源的 Grafana Agent 项目,该项目此后已被许多 Grafana Cloud 客户和社区成员使用。鉴于该解决方案的成熟度,现在是时候将该实现捐赠给 Prometheus 以实现原生集成和更广泛的采用。Robert(Grafana Labs)在 Srikrishna(Red Hat)和社区的帮助下,将代码移植到 Prometheus 代码库,该代码库在 2 周前合并到 main 分支!

捐赠过程非常顺利。由于一些 Prometheus 维护者之前曾在 Grafana Agent 中贡献过此代码,并且由于新的 WAL 受 Prometheus 自身 WAL 的启发,因此当前的 Prometheus TSDB 维护者很容易将它完全维护!Robert 将加入 Prometheus 团队担任 TSDB 维护者(恭喜!),这也确实很有帮助。

现在,让我们解释一下如何使用它!(

如何详细使用代理模式

从现在开始,如果您显示 Prometheus 的帮助输出(--help 标志),您应该看到如下所示的内容:

usage: prometheus [<flags>]

The Prometheus monitoring server

Flags:
  -h, --help                     Show context-sensitive help (also try --help-long and --help-man).
      (... other flags)
      --storage.tsdb.path="data/"
                                 Base path for metrics storage. Use with server mode only.
      --storage.agent.path="data-agent/"
                                 Base path for metrics storage. Use with agent mode only.
      (... other flags)
      --enable-feature= ...      Comma separated feature names to enable. Valid options: agent, exemplar-storage, expand-external-labels, memory-snapshot-on-shutdown, promql-at-modifier, promql-negative-offset, remote-write-receiver,
                                 extra-scrape-metrics, new-service-discovery-manager. See https://prometheus.ac.cn/docs/prometheus/latest/feature_flags/ for more details.

由于代理模式位于功能标志之后,如前所述,请使用 --enable-feature=agent 标志以代理模式运行 Prometheus。现在,其余的标志要么适用于服务器和代理,要么只适用于特定模式。您可以通过查看标志帮助字符串的最后一句来查看哪个标志对应于哪个模式。“仅与服务器模式一起使用”表示它仅适用于服务器模式。如果您没有看到类似的描述,则表示该标志是共享的。

代理模式接受具有相同发现选项和远程写入选项的相同抓取配置。

它还公开了一个 Web UI,该 UI 禁用了查询功能,但显示了构建信息、配置、目标和服务发现信息,就像在正常的 Prometheus 服务器中一样。

实践 Prometheus 代理示例:Katacoda 教程

与 Prometheus 远程写入教程类似,如果您想尝试 Prometheus 代理功能的实践体验,我们建议您使用 Thanos Katacoda 的 Prometheus 代理教程,它解释了运行 Prometheus 代理是多么容易。

总结

希望您发现这很有趣!在这篇文章中,我们介绍了以下新情况:

  • 边缘集群
  • 访问受限的网络
  • 大量的集群
  • 短暂的和动态的集群

然后,我们解释了新的 Prometheus 代理模式,它允许将抓取的指标有效地转发到远程写入端点。

与往常一样,如果您有任何问题或反馈,请随时 在 GitHub 上提交问题或在邮件列表中提问

这篇博文是 CNCF、Grafana 和 Prometheus 之间协调发布的一部分。请随时阅读 CNCF 公告 和有关 构成 Prometheus 代理基础的 Grafana 代理 的观点。

Prometheus 符合性计划:第一轮结果

今天,我们发布了 Prometheus 符合性计划,其目标是确保 Prometheus 监控领域中不同项目和供应商之间的互操作性。虽然法律文书仍在最终确定中,但我们已经进行了测试,我们认为以下是我们的第一轮结果。作为此次发布的一部分,Julius Volz 更新了他的 PromQL 测试结果

作为快速提醒:该计划被称为 Prometheus 符合性,软件可以符合特定测试,从而产生兼容性评级。这种命名法可能看起来很复杂,但它使我们能够讨论这个主题,而不会使用无休止的词语组合。

前言

新类别

我们发现,很难推理出什么需要应用于什么软件。为了帮助理清思路,我们创建了 一个概述,介绍了我们可以将软件归入的四个新类别:

  • 指标公开者
  • 代理/收集器
  • Prometheus 存储后端
  • 完全 Prometheus 兼容性

行动号召

非常欢迎反馈。也许与直觉相反,我们希望社区(不仅仅是 Prometheus 团队)来塑造这项工作。为了帮助实现这一点,我们将在 Prometheus 中启动一个 WG 符合性小组。与 WG 文档WG 存储 一样,这些小组将是公开的,我们积极邀请参与。

正如我们 最近提到的,Prometheus 的维护者/采用率出人意料地(或者说是令人震惊地)低。换句话说,我们希望围绕 Prometheus 兼容性的经济激励措施会促使供应商分配资源来与我们一起构建测试。如果您一直希望在工作时间为 Prometheus 做贡献,这可能是您的机会;并且您将有机会接触到 Prometheus 的许多高度相关方面。您可以通过多种方式 与我们联系

注册进行测试

如果您想注册进行测试,可以使用 相同的沟通渠道 与我们联系。一旦文件到位,我们将把联系信息和合同操作移交给 CNCF。

测试结果

完全 Prometheus 兼容性

我们知道要构建哪些测试,但我们还没有完成。正如之前宣布的那样,对项目或供应商施加这种要求是不公平的。因此,测试垫片被定义为已通过。例如,Julius 本周运行的 PromQL 测试 的当前半手动性质意味着 Julius 在大多数情况下,作为 PromQL 测试的一部分,测试了通过 Prometheus 远程写入发送数据。我们在这里以多种方式重复使用他的结果。这很快就会解决,来自不同角度的更多测试将不断提高要求,从而提高最终用户的信心。

将项目和 aaS 产品分成两组进行观察是有意义的。

项目

通过

  • Cortex 1.10.0
  • M3 1.3.0
  • Promscale 0.6.2
  • Thanos 0.23.1

未通过

VictoriaMetrics 1.67.0 未通过,并且 不打算通过。本着最终用户信心的精神,我们决定跟踪他们的结果,同时他们将自己定位为 Prometheus 的直接替代品。

aaS

通过

  • Chronosphere
  • Grafana Cloud

未通过

  • Amazon 托管服务 for Prometheus
  • Google Cloud 托管服务 for Prometheus
  • New Relic
  • Sysdig Monitor

注意:由于 Amazon 托管服务 for Prometheus 基于 Cortex,就像 Grafana Cloud 一样,我们预计它们将在下一个更新周期后通过。

代理/收集器

通过

  • Grafana Agent 0.19.0
  • OpenTelemetry 收集器 0.37.0
  • Prometheus 2.30.3

未通过

  • Telegraf 1.20.2
  • Timber Vector 0.16.1
  • VictoriaMetrics Agent 1.67.0

注意:我们测试了 Vector 0.16.1 而不是 0.17.0,因为 0.17.0 没有二进制下载,而我们的测试工具链目前需要二进制文件。

关于勒索软件命名

正如奥斯卡·王尔德所说,模仿是奉承的最高形式。

"Prometheus" 和 "Thanos" 这些名称 最近被一个勒索软件团伙使用。除了通知您正在发生这种情况之外,我们无能为力。您也无能为力,除了意识到正在发生这种情况。

虽然我们没有理由相信该团伙会试图诱使任何人下载我们项目的假二进制文件,但我们仍然建议遵循常见的供应链和安全实践。在部署软件时,请通过以下机制之一进行:

除非您能够合理地信任特定的来源和供应链,否则您不应使用软件。

由于勒索软件团伙故意选择这些名称的可能性不为零,因此他们可能会看到这篇文章:请停止。停止勒索软件以及命名选择。

Prometheus 符合性计划:远程写入符合性测试结果

CNCF我们自己 宣布的那样,我们正在启动 Prometheus 符合性计划。

为了让每个人在正式运行测试之前了解生态系统的现状,我们想展示我们快乐的小测试套件中最新的成员:Prometheus 远程写入 符合性测试套件测试了远程写入协议的发送方部分,以符合我们的 规范

在星期一的 PromCon 上,Tom Wilkie 展示了几周前录制时的测试结果。在直播部分,他已经有了 更新。两天后,我们又有了两个更新:添加了 可观测性管道工具 Vector,以及 现有系统的最新版本

所以,不多说,当前的结果按字母顺序排列如下

发送方 版本 得分
Grafana Agent 0.13.1 100%
Prometheus 2.26.0 100%
OpenTelemetry Collector 0.26.0 41%
Telegraf 1.18.2 65%
Timber Vector 0.13.1 35%
VictoriaMetrics Agent 1.59.0 76%

原始结果是

--- PASS: TestRemoteWrite/grafana (0.01s)
    --- PASS: TestRemoteWrite/grafana/Counter (10.02s)
    --- PASS: TestRemoteWrite/grafana/EmptyLabels (10.02s)
    --- PASS: TestRemoteWrite/grafana/Gauge (10.02s)
    --- PASS: TestRemoteWrite/grafana/Headers (10.02s)
    --- PASS: TestRemoteWrite/grafana/Histogram (10.02s)
    --- PASS: TestRemoteWrite/grafana/HonorLabels (10.02s)
    --- PASS: TestRemoteWrite/grafana/InstanceLabel (10.02s)
    --- PASS: TestRemoteWrite/grafana/Invalid (10.02s)
    --- PASS: TestRemoteWrite/grafana/JobLabel (10.02s)
    --- PASS: TestRemoteWrite/grafana/NameLabel (10.02s)
    --- PASS: TestRemoteWrite/grafana/Ordering (26.12s)
    --- PASS: TestRemoteWrite/grafana/RepeatedLabels (10.02s)
    --- PASS: TestRemoteWrite/grafana/SortedLabels (10.02s)
    --- PASS: TestRemoteWrite/grafana/Staleness (10.01s)
    --- PASS: TestRemoteWrite/grafana/Summary (10.01s)
    --- PASS: TestRemoteWrite/grafana/Timestamp (10.01s)
    --- PASS: TestRemoteWrite/grafana/Up (10.02s)
--- PASS: TestRemoteWrite/prometheus (0.01s)
    --- PASS: TestRemoteWrite/prometheus/Counter (10.02s)
    --- PASS: TestRemoteWrite/prometheus/EmptyLabels (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Gauge (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Headers (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Histogram (10.02s)
    --- PASS: TestRemoteWrite/prometheus/HonorLabels (10.02s)
    --- PASS: TestRemoteWrite/prometheus/InstanceLabel (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Invalid (10.02s)
    --- PASS: TestRemoteWrite/prometheus/JobLabel (10.02s)
    --- PASS: TestRemoteWrite/prometheus/NameLabel (10.03s)
    --- PASS: TestRemoteWrite/prometheus/Ordering (24.99s)
    --- PASS: TestRemoteWrite/prometheus/RepeatedLabels (10.02s)
    --- PASS: TestRemoteWrite/prometheus/SortedLabels (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Staleness (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Summary (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Timestamp (10.02s)
    --- PASS: TestRemoteWrite/prometheus/Up (10.02s)
--- FAIL: TestRemoteWrite/otelcollector (0.00s)
    --- FAIL: TestRemoteWrite/otelcollector/Counter (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Histogram (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/InstanceLabel (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Invalid (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/JobLabel (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Ordering (13.54s)
    --- FAIL: TestRemoteWrite/otelcollector/RepeatedLabels (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Staleness (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Summary (10.01s)
    --- FAIL: TestRemoteWrite/otelcollector/Up (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/EmptyLabels (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/Gauge (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/Headers (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/HonorLabels (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/NameLabel (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/SortedLabels (10.01s)
    --- PASS: TestRemoteWrite/otelcollector/Timestamp (10.01s)
--- FAIL: TestRemoteWrite/telegraf (0.01s)
    --- FAIL: TestRemoteWrite/telegraf/EmptyLabels (14.60s)
    --- FAIL: TestRemoteWrite/telegraf/HonorLabels (14.61s)
    --- FAIL: TestRemoteWrite/telegraf/Invalid (14.61s)
    --- FAIL: TestRemoteWrite/telegraf/RepeatedLabels (14.61s)
    --- FAIL: TestRemoteWrite/telegraf/Staleness (14.59s)
    --- FAIL: TestRemoteWrite/telegraf/Up (14.60s)
    --- PASS: TestRemoteWrite/telegraf/Counter (14.61s)
    --- PASS: TestRemoteWrite/telegraf/Gauge (14.60s)
    --- PASS: TestRemoteWrite/telegraf/Headers (14.61s)
    --- PASS: TestRemoteWrite/telegraf/Histogram (14.61s)
    --- PASS: TestRemoteWrite/telegraf/InstanceLabel (14.61s)
    --- PASS: TestRemoteWrite/telegraf/JobLabel (14.61s)
    --- PASS: TestRemoteWrite/telegraf/NameLabel (14.60s)
    --- PASS: TestRemoteWrite/telegraf/Ordering (14.61s)
    --- PASS: TestRemoteWrite/telegraf/SortedLabels (14.61s)
    --- PASS: TestRemoteWrite/telegraf/Summary (14.60s)
    --- PASS: TestRemoteWrite/telegraf/Timestamp (14.61s)
--- FAIL: TestRemoteWrite/vector (0.01s)
    --- FAIL: TestRemoteWrite/vector/Counter (10.02s)
    --- FAIL: TestRemoteWrite/vector/EmptyLabels (10.01s)
    --- FAIL: TestRemoteWrite/vector/Headers (10.02s)
    --- FAIL: TestRemoteWrite/vector/HonorLabels (10.02s)
    --- FAIL: TestRemoteWrite/vector/InstanceLabel (10.02s)
    --- FAIL: TestRemoteWrite/vector/Invalid (10.02s)
    --- FAIL: TestRemoteWrite/vector/JobLabel (10.01s)
    --- FAIL: TestRemoteWrite/vector/Ordering (13.01s)
    --- FAIL: TestRemoteWrite/vector/RepeatedLabels (10.02s)
    --- FAIL: TestRemoteWrite/vector/Staleness (10.02s)
    --- FAIL: TestRemoteWrite/vector/Up (10.02s)
    --- PASS: TestRemoteWrite/vector/Gauge (10.02s)
    --- PASS: TestRemoteWrite/vector/Histogram (10.02s)
    --- PASS: TestRemoteWrite/vector/NameLabel (10.02s)
    --- PASS: TestRemoteWrite/vector/SortedLabels (10.02s)
    --- PASS: TestRemoteWrite/vector/Summary (10.02s)
    --- PASS: TestRemoteWrite/vector/Timestamp (10.02s)
--- FAIL: TestRemoteWrite/vmagent (0.01s)
    --- FAIL: TestRemoteWrite/vmagent/Invalid (20.66s)
    --- FAIL: TestRemoteWrite/vmagent/Ordering (22.05s)
    --- FAIL: TestRemoteWrite/vmagent/RepeatedLabels (20.67s)
    --- FAIL: TestRemoteWrite/vmagent/Staleness (20.67s)
    --- PASS: TestRemoteWrite/vmagent/Counter (20.67s)
    --- PASS: TestRemoteWrite/vmagent/EmptyLabels (20.64s)
    --- PASS: TestRemoteWrite/vmagent/Gauge (20.66s)
    --- PASS: TestRemoteWrite/vmagent/Headers (20.64s)
    --- PASS: TestRemoteWrite/vmagent/Histogram (20.66s)
    --- PASS: TestRemoteWrite/vmagent/HonorLabels (20.66s)
    --- PASS: TestRemoteWrite/vmagent/InstanceLabel (20.66s)
    --- PASS: TestRemoteWrite/vmagent/JobLabel (20.66s)
    --- PASS: TestRemoteWrite/vmagent/NameLabel (20.66s)
    --- PASS: TestRemoteWrite/vmagent/SortedLabels (20.66s)
    --- PASS: TestRemoteWrite/vmagent/Summary (20.66s)
    --- PASS: TestRemoteWrite/vmagent/Timestamp (20.67s)
    --- PASS: TestRemoteWrite/vmagent/Up (20.66s)

我们将继续改进我们的测试套件,包括添加更多测试和新的测试目标。如果您想帮助我们,请考虑添加更多 我们的远程写入集成列表

介绍 Prometheus 兼容性计划

Prometheus 是云原生空间及其他领域中度量监控的标准。为了确保互操作性,保护用户免受意外情况的影响,并促进更多并行创新,Prometheus 项目正在引入 Prometheus 兼容性计划,在 CNCF 的帮助下,对组件的兼容性和 Prometheus 兼容性进行认证。

CNCF 管理委员会预计将在下次会议上正式审查并批准该计划。我们邀请更广泛的社区在这个快速发展阶段帮助改进我们的测试。

借助我们 广泛且不断扩展的测试套件,项目和供应商可以确定其对我们规范的符合性和 Prometheus 生态系统内的兼容性。

在发布时,我们为三个组件提供兼容性测试

  • PromQL(需要手动解释,基本完整)
  • 远程读写(全自动,开发中)
  • OpenMetrics(部分自动,基本完整,需要问卷调查)

我们计划添加更多组件。Prometheus 远程读取或我们的数据存储/TSDB 的测试很可能作为下一个添加项。我们明确邀请大家扩展和改进现有测试,并提交新的测试。

Prometheus 兼容性计划的工作原理如下

对于每个组件,都会有一个标记“foo YYYY-MM 兼容”,例如“OpenMetrics 2021-05 兼容”、“PromQL 2021-05 兼容”和“Prometheus 远程写入 2021-05 兼容”。任何项目或供应商都可以提交其符合性文档。达到 100% 时,将授予该标记。

对于任何完整的软件,都会有一个标记“Prometheus x.y 兼容”,例如“Prometheus 2.26 兼容”。相关组件的符合性分数将相乘。达到 100% 时,将授予该标记。

例如,Prometheus Agent 支持 OpenMetrics 和 Prometheus 远程写入,但不支持 PromQL。因此,只将 OpenMetrics 和 Prometheus 远程写入的符合性分数相乘。

兼容和符合标记的有效期为 2 个小版本或 12 周,以较长者为准。

介绍“@”修饰符

您是否曾经选择过前 10 个时间序列以获取某些信息,但结果却不是 10 个而是 100 个?如果是的话,这篇文章就是为您准备的。让我带您了解潜在的问题以及我如何解决它。

目前,topk() 查询只有在您获得正好 k 个结果的瞬时查询中才有意义,但在您将其作为范围查询运行时,您可能会获得远远超过 k 个结果,因为每个步骤都是独立评估的。此 @ 修饰符可让您修复范围查询中所有步骤的排名。

在 Prometheus v2.25.0 中,我们引入了一个新的 PromQL 修饰符 @。类似于 offset 修饰符允许您将向量选择器、范围向量选择器和子查询的评估相对于评估时间偏移固定持续时间,@ 修饰符允许您固定这些选择器的评估,而与查询评估时间无关。该语法的功劳归于 Björn Rabenstein

<vector-selector> @ <timestamp>
<range-vector-selector> @ <timestamp>
<subquery> @ <timestamp>

<timestamp> 是一个 Unix 时间戳,用浮点字面量表示。

例如,查询 http_requests_total @ 1609746000 返回 http_requests_total2021-01-04T07:40:00+00:00 时的值。查询 rate(http_requests_total[5m] @ 1609746000) 返回 http_requests_total 在同一时间时的 5 分钟速率。

此外,start()end() 也可以用作 @ 修饰符的值,作为特殊值。对于范围查询,它们分别解析为范围查询的开始和结束,并且对于所有步骤都保持相同。对于瞬时查询,start()end() 都解析为评估时间。

回到 topk() 修复,以下查询绘制了那些时间序列的 http_requests_total1m 速率,这些时间序列的最后 1h 速率排名前 5。因此,现在即使作为范围查询,您也可以理解 topk(),它绘制了正好 k 个结果。

rate(http_requests_total[1m]) # This acts like the actual selector.
  and
topk(5, rate(http_requests_total[1h] @ end())) # This acts like a ranking function which filters the selector.

类似地,topk() 排名可以替换为其他函数,如 histogram_quantile(),该函数目前只有作为瞬时查询才有意义。rate() 可以替换为 <aggregation>_over_time() 等。请告诉我们您如何使用此新修饰符!

@ 修饰符默认情况下处于禁用状态,可以使用标志 --enable-feature=promql-at-modifier 启用。在 这篇博文 中了解有关功能标志的更多信息,并在此处找到 @ 修饰符的文档 这里

介绍功能标志

我们一直根据 SemVer 模型在稳定性和破坏性变更方面做出坚定的承诺。情况将继续如此。

由于我们希望在实验方面更加大胆,因此我们计划更多地使用功能标志。

从 v2.25.0 开始,我们引入了一个名为 禁用功能 的新部分,这些功能隐藏在 --enable-feature 标志后面。您可以在未来的版本中看到更多功能添加到此部分。

此列表中的功能被认为是实验性的,并且只要它们仍在 --enable-feature 后面,就会伴随以下注意事项

  1. 如果功能有任何 API(Web API、代码接口等),API 规范可能会更改。
  2. 功能的行为可能会更改。
  3. 它们可能会破坏您可能对 Prometheus 存在的一些假设。
    • 例如,假设查询不会提前查看样本的评估时间,而这将被 @ 修饰符和负偏移量破坏。
  4. 它们可能不稳定,但当然,我们会尽力保持它们的稳定。

这些注意事项使我们能够在实验方面更加大胆,并更快地进行创新。一旦任何功能得到广泛使用,并且在 API、行为和实现方面被认为是稳定的,它们可能会从禁用功能列表中移出,并默认启用。如果我们发现任何功能不值得或存在问题,我们可能会将其完全删除。如果启用某个功能被认为是对 Prometheus 的重大破坏性变更,它将保持禁用状态,直到下一个主要版本发布。

关注每次发布的此列表,并尝试使用它们!

远程读取支持流式传输

新版本的 Prometheus 2.13.0 现已发布,与往常一样,它包含了许多修复和改进。您可以在 此处 阅读更改内容。但是,有一个功能是许多项目和用户一直在等待的:远程读取 API 的分块流式传输版本

在本文中,我想深入介绍我们在远程协议中做出的更改,更改原因以及如何有效地使用它。

远程 API

从 1.x 版本开始,Prometheus 就可以通过 远程 API 直接与它的存储进行交互。

此 API 允许第三方系统通过两种方法与度量数据进行交互

  • 写入 - 接收 Prometheus 推送的样本
  • 读取 - 从 Prometheus 拉取样本

Remote read and write architecture

这两种方法都使用带有 protobuf 编码消息的 HTTP。这两种方法的请求和响应都使用 snappy 进行压缩。

远程写入

这是将 Prometheus 数据复制到第三方系统中最常用的方法。在此模式下,Prometheus 通过定期向给定端点发送一批样本,来流式传输样本。

远程写入最近在 3 月份通过 基于 WAL 的远程写入 进行了大幅改进,从而提高了可靠性和资源消耗。还值得注意的是,远程写入几乎受 此处 提到的所有第三方集成支持。

远程读取

读取方法不太常见。它是在 2017 年 3 月(服务器端)添加的,从那时起就没有看到过重大的发展。

Prometheus 2.13.0 的发布包括对读取 API 中已知资源瓶颈的修复。本文将重点介绍这些改进。

远程读取的关键思想是允许直接查询 Prometheus 存储 (TSDB),而无需 PromQL 评估。它类似于 PromQL 引擎用来从存储中检索数据的 Querier 接口。

这实际上允许读取 Prometheus 收集的 TSDB 中的时间序列。远程读取的主要用例是

  • 在 Prometheus 的不同数据格式之间进行无缝的 Prometheus 升级,因此可以 让 Prometheus 从另一个 Prometheus 读取数据
  • Prometheus 能够从第三方长期存储系统(例如 InfluxDB)读取数据。
  • 第三方系统从 Prometheus 查询数据(例如 Thanos)。

远程读取 API 公开了一个简单的 HTTP 端点,该端点期望以下 protobuf 负载

message ReadRequest {
  repeated Query queries = 1;
}

message Query {
  int64 start_timestamp_ms = 1;
  int64 end_timestamp_ms = 2;
  repeated prometheus.LabelMatcher matchers = 3;
  prometheus.ReadHints hints = 4;
}

使用此负载,客户端可以请求匹配给定 matchers 和使用 endstart 指定的时间范围的特定时间序列。

响应同样简单

message ReadResponse {
  // In same order as the request's queries.
  repeated QueryResult results = 1;
}

message Sample {
  double value    = 1;
  int64 timestamp = 2;
}

message TimeSeries {
  repeated Label labels   = 1;
  repeated Sample samples = 2;
}

message QueryResult {
  repeated prometheus.TimeSeries timeseries = 1;
}

远程读取返回匹配的时间序列,其中包含值和时间戳的原始样本。

问题陈述

这种简单的远程读取有两个主要问题。它易于使用和理解,但在我们定义的 protobuf 格式中,单个 HTTP 请求没有流式传输功能。其次,响应包含原始样本(float64 值和 int64 时间戳),而不是编码压缩的样本批次(称为“块”),这些批次用于在 TSDB 内存储度量。

没有流式传输的远程读取的服务器算法是

  1. 解析请求。
  2. 从 TSDB 中选择度量。
  3. 对于所有解码后的时间序列
    • 对于所有样本
      • 添加到响应 protobuf
  4. 编组响应。
  5. Snappy 压缩。
  6. 发送回 HTTP 响应。

远程读取的整个响应必须以原始未压缩的格式缓冲在内存中,以便在将其发送到客户端之前以潜在的大型 protobuf 消息进行编组。然后,整个响应必须在客户端中再次完全缓冲,以便能够将其从接收到的 protobuf 中解组。只有在之后,客户端才能使用原始样本。

这意味着,对于只匹配 10,000 个时间序列的 8 小时请求,客户端和服务器各自可能需要分配多达 2.5GB 的内存!

以下是远程读取请求时间期间 Prometheus 和 Thanos Sidecar(远程读取客户端)的内存使用情况度量

Prometheus 2.12.0: RSS of single read 8h of 10k series

Prometheus 2.12.0: Heap-only allocations of single read 8h of 10k series

值得注意的是,即使对于 Prometheus 本身的 HTTP query_range 终端,查询 10,000 个时间序列也不是一个好主意,因为您的浏览器将无法愉快地获取、存储和渲染数百兆字节的数据。此外,出于仪表板和渲染目的,拥有如此大量的数据并不实用,因为人类不可能读取它。这就是为什么通常我们会编写查询,这些查询最多包含 20 个时间序列。

这很好,但一种非常常见的技术是以这样一种方式编写查询:查询返回 **聚合** 的 20 个时间序列,但查询引擎在底层必须接触到可能数千个时间序列才能评估响应(例如,使用 聚合运算符 时)。这就是为什么像 Thanos 这样的系统(除了其他数据外,它还使用来自远程读取的 TSDB 数据)经常会出现请求过重的现象。

解决方案

为了解释这个问题的解决方案,了解 Prometheus 在查询时如何遍历数据是有帮助的。核心概念可以在 QuerierSelect 方法返回的称为 SeriesSet 的类型中展示。该接口如下所示

// SeriesSet contains a set of series.
type SeriesSet interface {
    Next() bool
    At() Series
    Err() error
}

// Series represents a single time series.
type Series interface {
    // Labels returns the complete set of labels identifying the series.
    Labels() labels.Labels
    // Iterator returns a new iterator of the data of the series.
    Iterator() SeriesIterator
}

// SeriesIterator iterates over the data of a time series.
type SeriesIterator interface {
    // At returns the current timestamp/value pair.
    At() (t int64, v float64)
    // Next advances the iterator by one.
    Next() bool
    Err() error
}

这些接口集允许在进程内部进行“流式”操作。我们不再需要预先计算包含样本的时间序列列表。使用此接口,每个 SeriesSet.Next() 实现都可以按需获取时间序列。类似地,在每个时间序列中,我们也可以分别通过 SeriesIterator.Next 动态地获取每个样本。

通过这种契约,Prometheus 可以最大程度地减少分配的内存,因为 PromQL 引擎可以最佳地遍历样本以评估查询。TSDB 以一种从存储在文件系统中的块中逐个最佳地获取时间序列的方式实现 SeriesSet,从而最大限度地减少内存分配。

这对远程读取 API 非常重要,因为我们可以通过将响应的一部分以单个时间序列的少量块的形式发送给客户端,从而重用相同的流式模式。由于 protobuf 没有本地的分隔逻辑,我们 扩展 了 proto 定义,以允许发送 **一组小的协议缓冲消息** 而不是单个巨大的消息。我们将此模式称为 STREAMED_XOR_CHUNKS 远程读取,而旧模式称为 SAMPLES。扩展的协议意味着 Prometheus 不再需要缓冲整个响应。相反,它可以按顺序处理每个时间序列,并在每次 SeriesSet.NextSeriesIterator.Next 迭代的一批迭代中发送单个帧,从而有可能为下一个时间序列重用相同的内存页!

现在,STREAMED_XOR_CHUNKS 远程读取的响应是一组 Protobuf 消息(帧),如下所示

// ChunkedReadResponse is a response when response_type equals STREAMED_XOR_CHUNKS.
// We strictly stream full series after series, optionally split by time. This means that a single frame can contain
// partition of the single series, but once a new series is started to be streamed it means that no more chunks will
// be sent for previous one.
message ChunkedReadResponse {
  repeated prometheus.ChunkedSeries chunked_series = 1;
}

// ChunkedSeries represents single, encoded time series.
message ChunkedSeries {
  // Labels should be sorted.
  repeated Label labels = 1 [(gogoproto.nullable) = false];
  // Chunks will be in start time order and may overlap.
  repeated Chunk chunks = 2 [(gogoproto.nullable) = false];
}

如您所见,帧不再包含原始样本。这是我们做的第二个改进:我们在消息中发送分批成块的样本(参见 此视频 以了解有关块的更多信息),这些块与我们存储在 TSDB 中的块完全相同。

我们最终得到了以下服务器算法

  1. 解析请求。
  2. 从 TSDB 中选择度量。
  3. 对于所有时间序列
    • 对于所有样本
      • 编码成块
        • 如果帧 >= 1MB; 退出
    • 封送 ChunkedReadResponse 消息。
    • Snappy 压缩
    • 发送消息

您可以在 此处 找到完整的設計。

基准测试

这种新方法的性能与旧解决方案相比如何?

让我们比较一下 Prometheus 2.12.02.13.0 之间的远程读取特性。关于本文开头介绍的初始结果,我使用 Prometheus 作为服务器,以及 Thanos 侧车作为远程读取的客户端。我通过使用 grpcurl 对 Thanos 侧车运行 gRPC 调用来调用测试远程读取请求。测试是在我的笔记本电脑(联想 X1 16GB,i7 第 8 代)上使用 docker 中的 Kubernetes 进行的(使用 kind)。

数据是人工生成的,代表高度动态的 10,000 个时间序列(最坏情况)。

完整的测试平台可在 thanosbench 仓库 中找到。

内存

无流式传输

Prometheus 2.12.0: Heap-only allocations of single read 8h of 10k series

有流式传输

Prometheus 2.13.0: Heap-only allocations of single read 8h of 10k series

减少内存是我们解决方案的目标。Prometheus 在整个请求期间缓冲大约 50MB 的内存,而 Thanos 只使用很少的内存。由于流式 Thanos gRPC StoreAPI,侧车现在只是一个非常简单的代理。

此外,我还尝试了不同的时间范围和时间序列数量,但正如预期的那样,我仍然看到 Prometheus 的内存分配最大为 50MB,而 Thanos 的内存分配几乎不可见。这证明我们的远程读取使用了 **每个请求恒定的内存,无论您请求多少样本**。每个请求分配的内存也极大地减少了对数据基数的影响,因此获取的时间序列数量不再像以前那样重要。

这使得在并发限制的帮助下,更容易根据用户流量进行容量规划。

CPU

无流式传输

Prometheus 2.12.0: CPU time of single read 8h of 10k series

有流式传输

Prometheus 2.13.0: CPU time of single read 8h of 10k series

在我的测试中,CPU 使用率也得到了改善,CPU 时间减少了 2 倍。

延迟

由于流式传输和更少的编码,我们也成功地减少了远程读取请求的延迟。

使用 10,000 个时间序列的 8 小时范围内的远程读取请求延迟

2.12.0:平均时间 2.13.0:平均时间
实际 0m34.701s 0m8.164s
用户 0m7.324s 0m8.181s
系统 0m1.172s 0m0.749s

以及使用 2 小时的时间范围

2.12.0:平均时间 2.13.0:平均时间
实际 0m10.904s 0m4.145s
用户 0m6.236s 0m4.322s
系统 0m0.973s 0m0.536s

除了延迟降低了约 2.5 倍之外,与非流式版本相比,响应会立即流式传输,在非流式版本中,客户端延迟仅在 Prometheus 和 Thanos 端的处理和封送处理上就为 27 秒(实际 减去 用户 时间)。

兼容性

远程读取以向后和向前兼容的方式扩展。这是由于 protobuf 和 accepted_response_types 字段,该字段对于旧服务器被忽略。同时,如果较旧的客户端没有提供 accepted_response_types,服务器仍然可以正常工作,假设旧的 SAMPLES 远程读取。

远程读取协议以向后和向前兼容的方式扩展

  • v2.13.0 之前的 Prometheus 将安全地忽略较新的客户端提供的 accepted_response_types 字段,并假设 SAMPLES 模式。
  • v2.13.0 之后的 Prometheus 将默认对没有提供 accepted_response_types 参数的旧客户端使用 SAMPLES 模式。

用法

要在 Prometheus v2.13.0 中使用新的流式远程读取,第三方系统必须在请求中添加 accepted_response_types = [STREAMED_XOR_CHUNKS]

然后 Prometheus 将流式传输 ChunkedReadResponse 而不是旧消息。每个 ChunkedReadResponse 消息都遵循 varint 大小和用于 CRC32 Castagnoli 校验和的固定大小大端 uint32。

对于 Go,建议使用 ChunkedReader 直接从流中读取。

请注意,storage.remote.read-sample-limit 标志不再适用于 STREAMED_XOR_CHUNKSstorage.remote.read-concurrent-limit 与以前一样工作。

还有一个新的选项 storage.remote.read-max-bytes-in-frame,它控制每条消息的最大大小。建议将其保持为默认的 1MB,因为 Google 建议将 protobuf 消息 不要大于 1MB

如前所述,Thanos 从这项改进中受益匪浅。流式远程读取是在 v0.7.0 中添加的,因此这个版本或任何后续版本,只要 Prometheus 2.13.0 或更高版本与 Thanos 侧车一起使用,就会自动使用流式远程读取。

后续步骤

2.13.0 版本引入了扩展的远程读取和 Prometheus 服务器端实现,但是,在撰写本文时,为了充分利用扩展的远程读取协议,仍然有一些工作要做

总结

总而言之,块状远程读取流式传输的主要优势是

  • 客户端和服务器都能够使用 **每个请求实际上恒定的内存大小**。这是因为 Prometheus 在远程读取期间逐个发送单个小帧,而不是整个响应。这对容量规划非常有帮助,特别是对于像内存这样的不可压缩资源来说。
  • Prometheus 服务器在远程读取期间不再需要将块解码为原始样本。如果系统重用了本地的 TSDB XOR 压缩(就像 Thanos 所做的那样),则客户端端也是如此。

与往常一样,如果您遇到任何问题或反馈,请随时在 GitHub 上提交工单或在邮件列表中提问。

与 ForgeRock 的访谈

在与 Prometheus 用户进行的一系列访谈中,来自 ForgeRock 的 Ludovic Poitou 谈论了他们的监控之旅。

您能告诉我们关于您自己以及 ForgeRock 做什么吗?

我是 Ludovic Poitou,ForgeRock 的产品管理总监,总部位于法国格勒诺布尔附近。ForgeRock 是一家国际身份和访问管理软件公司,拥有 500 多名员工,成立于 2010 年的挪威,现总部位于美国旧金山。我们提供解决方案来保护与客户、员工、设备和事物进行的每一次在线互动。我们拥有 800 多家客户,从金融公司到政府服务机构。

您在使用 Prometheus 之前的监控体验是什么?

ForgeRock 身份平台一直提供监控接口。但是,该平台由 4 种主要产品组成,每种产品都有不同的选项。例如,目录服务产品通过 SNMP、JMX 或 LDAP 提供监控信息,甚至在最新版本中通过 HTTP 提供 RESTful API。其他产品只有 REST 或 JMX。因此,监控整个平台很复杂,需要能够集成这些协议的工具。

为什么您决定尝试 Prometheus?

我们需要有一个统一的公共接口来监控我们所有的产品,同时还要保持现有的接口以实现向后兼容性。

我们开始在所有产品中使用 DropWizard 收集指标。同时,我们也开始将这些产品迁移到云端,并在 Docker 和 Kubernetes 中运行它们。因此,由于 Prometheus 与 Kubernetes 的集成、部署的简单性和 Grafana 的集成,它变得十分突出。我们也研究了 Graphite,虽然我们在产品中也添加了对它的支持,但我们的客户几乎没有使用它。

你是如何过渡的?

我们的一些产品已经使用 DropWizard 库,我们决定在所有产品中使用一个通用的库,因此 DropWizard 是编写仪器代码的明显选择。但很快,我们就遇到了数据模型的问题。Prometheus 接口使用维度,而我们倾向于为指标使用分层模型。我们也开始使用 Micrometer,很快便遇到了一些限制。所以我们最终构建了一个自定义实现,使用 Micrometer 接口来收集我们的指标。我们调整了 DropWizard Metrics 以满足我们的要求,并对 DropWizard Prometheus 导出器进行了调整。现在,使用单个仪器,我们可以用维度或分层方式公开指标。然后,我们开始构建客户可以安装和定制的 Grafana 样板仪表盘,以获得自己的监控视图和警报。

Access Management ForgeRock's Grafana dashboard

我们确实继续提供以前的面板,但我们强烈建议客户使用 Prometheus 和 Grafana。

切换后你看到了哪些改进?

第一个好处来自我们的质量工程团队。当他们开始测试我们的 Prometheus 支持和不同的指标时,他们开始在所有压力和性能测试中默认启用它。他们开始为特定的测试定制 Grafana 仪表盘。不久之后,他们开始突出显示并指向各种指标,以解释一些性能问题。

在为了理解和修复问题而重现问题时,我们的工程团队也使用了 Prometheus,并扩展了一些仪表盘。整个过程为我们提供了一个更好的产品,并让我们更好地了解哪些指标对客户的监控和可视化很重要。

你认为 ForgeRock 和 Prometheus 的未来会怎样?

ForgeRock 开始努力将其产品和解决方案作为一项服务提供。随着这一举措,监控和警报变得更加关键,当然,我们的监控基础设施是基于 Prometheus 的。我们目前有两个级别的监控,每个租户一个,我们使用 Prometheus 收集关于一个客户环境的数据,我们可以公开一组供该客户使用的指标。但我们也构建了一个中央 Prometheus 服务,所有已部署租户的指标都被推送到该服务,这样我们的 SRE 团队就可以很好地了解所有客户环境的运行情况。总的来说,我认为 Prometheus 已成为我们的主要监控服务,它既为我们的本地客户服务,也为我们自己运行作为服务的解决方案服务。

Hostinger 访谈

作为我们对 Prometheus 用户的访谈系列的延续,来自 Hostinger 的 Donatas Abraitis 谈论了他们的监控旅程。

你能告诉我们关于你自己的情况以及 Hostinger 做了什么?

我是 Donatas Abraitis,Hostinger 的系统工程师。正如名称所暗示的那样,Hostinger 是一家主机公司。自 2004 年以来,我们拥有约 3000 万客户,包括 000webhost.com 项目,这是一个免费的网站托管提供商。

您在使用 Prometheus 之前的监控体验是什么?

当 Hostinger 还是一家规模很小的公司时,当时市场上只有 Nagios、Cacti 和 Ganglia 这三种开源监控工具。这就像告诉年轻人什么是软盘驱动器一样,但 Nagios 和 Cacti 今天仍在开发周期中。

即使没有自动化工具,Bash + Perl 也能胜任。如果你想扩展你的团队和自己,自动化永远不能忽视。没有自动化 - 更多的人工工作。

当时大约有 150 台物理服务器。相比之下,到今天,我们大约有 2000 台服务器,包括虚拟机和物理机。

对于网络设备,SNMP 仍然被广泛使用。随着 "白盒" 交换机的兴起,SNMP 变得不那么必要了,因为可以安装常规工具。

你可以运行 node_exporter 或交换机内的任何其他导出器,以使用人类可读的格式公开你需要的任何指标。美丽胜于丑陋,对吧?

我们使用 CumulusOS,在我们的案例中主要使用 x86,因此运行任何类型的 Linux 软件都没有问题。

为什么您决定尝试 Prometheus?

在 2015 年,当我们开始自动化所有可以自动化的东西时,我们引入了 Prometheus 到生态系统中。起初,我们有一台单独的监控机器,运行着 Alertmanager、Pushgateway、Grafana、Graylog 和 rsyslogd。

我们也评估了 TICK(Telegraf/InfluxDB/Chronograf/Kapacitor)堆栈,但我们对它们并不满意,因为它们当时功能有限,而 Prometheus 在许多方面看起来更简单、更成熟。

你是如何过渡的?

在从旧的监控堆栈(NCG - Nagios/Cacti/Ganglia)过渡期间,我们同时使用这两个系统,最终,我们只依赖于 Prometheus。

我们拥有大约 25 个社区指标导出器 + 一些自定义编写的导出器,比如我们的舰队中的 lxc_exporter。我们主要使用文本文件收集器公开自定义的业务相关指标。

切换后你看到了哪些改进?

新的设置将我们的时间分辨率从 5 分钟提高到 15 秒,这使我们能够进行细粒度和非常深入的分析。即使平均检测时间 (MTTD) 也减少了 4 倍。

你认为 Hostinger 和 Prometheus 的未来会怎样?

自从 2015 年以来,我们的基础设施规模扩大了 N 倍,主要瓶颈变成了 Prometheus 和 Alertmanager。我们的 Prometheus 吞噬了大约 ~2TB 的磁盘空间。因此,如果我们重启或更改正在维护的节点,我们就会丢失一段时间内的监控数据。目前,我们运行的是 Prometheus 版本 2.4.2,但在不久的将来,我们计划升级到 2.6。我们特别感兴趣的是 性能 和 WAL 相关功能。Prometheus 重启大约需要 10-15 分钟。不可接受。另一个问题是,如果一个位置宕机,我们也会丢失监控数据。因此,我们决定通过实现高可用性监控基础设施来解决这个问题:两个 Prometheus 节点,两个 Alertmanager,分别位于不同的大陆。

我们的主要可视化工具是 Grafana。Grafana 能够在主节点宕机时查询备份 Prometheus 节点,这一点至关重要。这很简单 - 在前面放置 HAProxy,并在本地接受连接。

另一个问题:我们如何防止用户(开发人员和其他内部人员)滥用仪表盘,从而使 Prometheus 节点过载。

或者,如果主节点宕机,则备份节点也会过载 - 雷鸣般的羊群问题

为了达到预期的状态,我们给了 Trickster 一个机会。它极大地加快了仪表盘加载时间。它缓存时间序列。在我们的案例中,缓存位于内存中,但还有更多存储它的选择。即使主节点宕机,你刷新仪表盘时,Trickster 也不会查询第二个节点以获取它在内存中缓存的时间序列。Trickster 位于 Grafana 和 Prometheus 之间。它只与 Prometheus API 交谈。

Hostinger Graphing Architecture

Prometheus 节点是独立的,而 Alertmanager 节点则形成一个集群。如果两个 Alertmanager 都看到了同一个警报,它们会去重,只触发一次,而不是多次触发。

我们计划运行大量的 blackbox_exporters,并监控每个 Hostinger 客户端的网站,因为任何无法监控的东西都无法评估。

我们期待在未来实现更多 Prometheus 节点,以便将节点分片到多个 Prometheus 实例之间。这样,即使某个区域的某个实例宕机,也不会出现瓶颈。

子查询支持

简介

顾名思义,子查询是查询的一部分,允许你在查询中执行范围查询,这在以前是不可能的。这是一个长期存在的特性请求:prometheus/prometheus/1227

子查询支持的 拉取请求 最近合并到了 Prometheus 中,并将从 Prometheus 2.7 开始提供。让我们在下面了解更多信息。

动机

有时,你想使用 rate(分辨率/范围较低,例如 5m)发现问题,同时将这些数据聚合到更高的范围内(例如,max_over_time 用于 1h)。

以前,单个 PromQL 查询无法实现上述功能。如果你想对警报规则或绘图的查询进行范围选择,则需要基于该查询创建记录规则,并对记录规则创建的指标执行范围选择。示例:max_over_time(rate(my_counter_total[5m])[1h])

当你想要对跨越几天或几周的数据进行一些快速的结果时,可能需要等待一段时间才能在记录规则中拥有足够的数据才能使用它。忘记添加记录规则会让人沮丧。而且,为每个查询步骤创建记录规则会很乏味。

有了子查询支持,所有等待和挫折都将消除。

子查询

子查询类似于 /api/v1/query_range API 调用,但嵌入在即时查询中。子查询的结果是一个范围向量。

Prometheus 团队在慕尼黑举办的 Prometheus 开发者峰会 2018 上就子查询的语法达成了一致。这些是 峰会关于子查询支持的笔记,以及用于实现子查询支持的 语法设计文档 的简要说明。

<instant_query> '[' <range> ':' [ <resolution> ] ']' [ offset <duration> ]
  • <instant_query> 等同于 /query_range API 中的 query 字段。
  • <range>offset <duration> 类似于范围选择器。
  • <resolution> 是可选的,等同于 /query_range API 中的 step

当未指定分辨率时,全局评估间隔将作为子查询的默认分辨率。此外,子查询的步骤是独立对齐的,不依赖于父查询的评估时间。

示例

min_over_time 函数内的子查询返回过去 30 分钟内 http_requests_total 指标的 5 分钟速率,分辨率为 1 分钟。这将等同于一个 /query_range API 调用,其中 query=rate(http_requests_total[5m]), end=<now>, start=<now>-30m, step=1m,并获取所有接收到的值的最小值。

min_over_time( rate(http_requests_total[5m])[30m:1m] )

分解

  • rate(http_requests_total[5m])[30m:1m] 是子查询,其中 rate(http_requests_total[5m]) 是要执行的查询。
  • rate(http_requests_total[5m])start=<now>-30m 执行到 end=<now>,分辨率为 1m。注意,start 时间与 1m 的步骤独立对齐(对齐的步骤为 0m 1m 2m 3m ...)。
  • 最后,所有上述评估的结果都传递给 min_over_time()

下面是嵌套子查询和使用默认分辨率的示例。最里面的子查询获取一段时间范围内 distance_covered_meters_total 的速率。我们使用它获取速率的 deriv(),同样是针对一段时间范围。最后,获取所有导数的最大值。注意,最里面的子查询的 <now> 时间相对于 deriv() 上的外层子查询的评估时间。

max_over_time( deriv( rate(distance_covered_meters_total[1m])[5m:1m] )[10m:] )

在大多数情况下,您需要使用默认的评估间隔,即默认情况下规则评估的间隔。自定义分辨率在您希望更频繁/更不频繁地计算时非常有用,例如,您可能希望更不频繁地计算昂贵的查询。

结语

虽然子查询在替换记录规则方面非常方便,但无必要地使用它们会影响性能。为了提高效率,应最终将繁重的子查询转换为记录规则。

也不建议在记录规则中包含子查询。如果确实需要在记录规则中使用子查询,请创建更多记录规则。

与 Presslabs 的访谈

作为我们与 Prometheus 用户访谈系列的一部分,来自 Presslabs 的 Mile Rosu 谈论了他们的监控之旅。

您能告诉我们您自己以及 Presslabs 做了什么吗?

Presslabs 是一个面向发布者、企业品牌和数字机构的高性能托管 WordPress 托管平台,旨在为其网站访问者提供 100% 的无缝体验。

最近,我们为我们的核心产品开发了一个创新组件——WordPress 商业智能。用户现在可以在一个全面的仪表盘中获取实时、可操作的数据,以支持简短的从问题到部署的过程,并持续改进他们的网站。

我们支持每月最多 20 亿次页面浏览量的无缝交付,在一支由 100 台机器组成的机群上,这些机器完全致力于为苛刻的客户提供托管的 WordPress 托管服务。

我们目前正在努力为全球 WordPress 发布者提供最佳体验。在这段旅程中,Kubernetes 为我们在高可用性 WordPress 托管基础设施方面即将到来的标准铺平了道路。

您在使用 Prometheus 之前的监控体验是什么?

我们从 2009 年开始构建我们的 WordPress 托管平台。当时,我们使用 Munin,这是一个开源的系统、网络和基础设施监控系统,它执行了我们需要的全部操作:公开、收集、聚合、警报和可视化指标。虽然它的性能很好,但每分钟收集一次,每 5 分钟聚合一次对我们来说太慢了,因此它生成的输出不足以正确分析我们平台上的事件。

Graphite 是我们名单上的第二个选择,它解决了 Munin 解决的时间挑战。我们添加了 collectd 来公开指标,并使用 Graphite 来收集和聚合它。

然后我们创建了 Viz,这是一个我们用 JavaScript & Python 编写的工具,用于可视化和警报。但是,我们停止了积极使用这项服务,因为维护它需要大量的工作,而 Grafana 从其第一个版本开始就很好地替代了它。

Presslab's Viz

自 2017 年下半年以来,我们的 Presslabs 平台进入了大规模转型阶段。其中一项重大变化是我们迁移到 Kubernetes,这意味着需要一个高性能的监控系统。从那时起,我们就决定使用 Prometheus,我们一直在使用它,并计划将其作为提取和公开指标的核心部分,整合到我们新平台上的所有服务中。

为什么您决定尝试 Prometheus?

我们在 2014 年的巴塞罗那 Velocity Europe 会议上开始考虑 Prometheus,当时我们与 Soundcloud 的工程师团队进行了交谈。他们公开的好处足以让我们尝试一下 Prometheus。

你是如何过渡的?

我们仍在过渡过程中,因此我们并行运行两个系统——Prometheus 和 Graphite-collectd 组合。对于客户仪表盘和我们的核心服务,我们使用 Prometheus,但是,对于客户站点,我们仍然使用 Graphite-collectd。在两者之上都有一个 Grafana 用于可视化。

Presslab's Redis Grafana dashboards

Prometheus 文档、Github 问题和源代码是集成 Prometheus 的首选资源;当然,StackOverflow 为该过程增添了一些趣味,满足了我们很多的好奇心。

Prometheus 的唯一问题是我们无法获得某些指标的长期存储。我们的托管基础设施平台需要存储使用指标,例如页面浏览量,至少一年。然而,自从我们使用 Prometheus 以来,Prometheus 的环境已经有了很大的改善,我们仍然需要测试可能的解决方案。

切换后你看到了哪些改进?

自从切换到 Prometheus 以来,与我们之前使用的任何其他替代方案相比,我们已经注意到资源使用量显着下降。此外,它易于安装,因为与 Kubernetes 的自动集成节省了大量时间。

您认为 Presslabs 和 Prometheus 的未来会怎样?

我们对 Prometheus 有很大计划,因为我们正在努力用 Prometheus Operator 替换我们目前在新的基础设施中使用的 Prometheus Helm 图表。该实现将提供平台客户的隔离,因为我们将为有限数量的网站分配一个专门的 Prometheus 服务器。我们已经在努力将 WordPress 融入 Kubernetes 的一部分。

我们还在努力以 Prometheus 格式导出 WordPress 指标。Grafana 将继续存在,因为它与 Prometheus 协同工作,满足了可视化的需求。

Prometheus 在 CNCF 中毕业

我们很高兴地宣布,从今天开始,Prometheus 将在 CNCF 中毕业。

Prometheus 是第二个达到此级别的项目。通过让 Prometheus 毕业,CNCF 表明它对我们的代码和功能速度、成熟度和稳定性以及我们的治理和社区流程充满信心。这也作为对任何内部讨论围绕监控工具选择进行的质量外部验证。

自从达到孵化阶段以来,发生了很多事情;其中一些很突出

  • 我们完全重写了我们的存储后端,以支持服务中的高 churn
  • 我们在稳定性方面做了很大的努力,尤其是在 2.3.2 版本中
  • 我们开始进行文档推广,特别关注如何使 Prometheus 的采用和加入社区更容易

特别是最后一点非常重要,因为我们目前进入了采用的第四阶段。这些阶段是由以下人员采用

  1. 以监控为中心的,积极寻求最棒的监控的用户
  2. 面临着无法跟上其规模的监控环境的超大规模用户
  3. 从小型公司到财富 50 强公司的企业,重新设计了其监控基础设施
  4. 缺乏资金和/或资源专注于监控,但从各个地方听说过 Prometheus 好处的用户

展望未来,我们预计会更广泛地采用 Prometheus,并致力于处理明天的规模,今天。

实施自定义服务发现

实施自定义服务发现

Prometheus 包含针对许多服务发现 (SD) 系统(如 Consul、Kubernetes 和 Azure 等公共云提供商)的内置集成。但是,我们无法为所有服务发现选项提供集成实现。Prometheus 团队已经在支持当前的 SD 集成方面精疲力尽,因此维护每个可能的 SD 选项的集成是不可行的。在许多情况下,当前的 SD 实现是由团队外部的人员贡献的,然后没有得到很好的维护或测试。我们希望承诺只直接与我们知道可以维护的服务发现机制进行集成,并且可以按预期工作。出于这个原因,目前对新的 SD 集成实施了禁令。

但是,我们知道仍然有希望能够与其他 SD 机制(如 Docker Swarm)进行集成。最近,对代码进行了一次小的更改,并在 Prometheus 存储库中的文档 目录 中提交了一个示例,用于实施自定义服务发现集成,而无需将其合并到主要的 Prometheus 二进制文件中。代码更改使我们能够使用内部发现管理器代码来编写另一个可执行文件,该文件与新的 SD 机制交互并输出与 Prometheus 的 file_sd 兼容的文件。通过将 Prometheus 与我们的新可执行文件放在一起,我们可以配置 Prometheus 以读取我们可执行文件的 file_sd 兼容输出,因此可以从该服务发现机制抓取目标。将来,这将使我们能够将 SD 集成从主要的 Prometheus 二进制文件中移出,并将使用适配器的稳定 SD 集成移到 Prometheus 的 discovery 包中。

使用 file_sd 的集成(例如使用适配器代码实现的集成)列在 这里

让我们看一下示例代码。

适配器

首先,我们有文件 adapter.go。您可以将此文件复制到您的自定义 SD 实现中,但了解这里发生的事情很有用。

// Adapter runs an unknown service discovery implementation and converts its target groups
// to JSON and writes to a file for file_sd.
type Adapter struct {
    ctx     context.Context
    disc    discovery.Discoverer
    groups  map[string]*customSD
    manager *discovery.Manager
    output  string
    name    string
    logger  log.Logger
}

// Run starts a Discovery Manager and the custom service discovery implementation.
func (a *Adapter) Run() {
    go a.manager.Run()
    a.manager.StartCustomProvider(a.ctx, a.name, a.disc)
    go a.runCustomSD(a.ctx)
}

适配器使用 discovery.Manager 在 goroutine 中实际启动我们自定义 SD 提供程序的 Run 函数。Manager 有一个通道,我们的自定义 SD 将向该通道发送更新。这些更新包含 SD 目标。groups 字段包含我们自定义 SD 可执行文件从我们的 SD 机制中知道的全部目标和标签。

type customSD struct {
    Targets []string          `json:"targets"`
    Labels  map[string]string `json:"labels"`
}

customSD 结构主要存在是为了帮助我们将内部 Prometheus targetgroup.Group 结构转换为 file_sd 格式的 JSON。

运行时,适配器将在通道上侦听来自我们自定义 SD 实现的更新。收到更新后,它将解析 targetgroup.Groups 为另一个 map[string]*customSD,并将其与存储在 Adapter 的 groups 字段中的内容进行比较。如果两者不同,我们将新组分配给 Adapter 结构,并将它们以 JSON 格式写入输出文件。请注意,此实现假定 SD 实现向下通道发送的每个更新都包含 SD 知道的全部目标组的完整列表。

自定义 SD 实现

现在,我们要实际使用 Adapter 来实现我们自己的自定义 SD。完整的示例位于同一个 examples 目录 这里

在这里,您可以看到我们正在导入适配器代码 "github.com/prometheus/prometheus/documentation/examples/custom-sd/adapter" 以及其他一些 Prometheus 库。为了编写自定义 SD,我们需要实现 Discoverer 接口的实现。

// Discoverer provides information about target groups. It maintains a set
// of sources from which TargetGroups can originate. Whenever a discovery provider
// detects a potential change, it sends the TargetGroup through its channel.
//
// Discoverer does not know if an actual change happened.
// It does guarantee that it sends the new TargetGroup whenever a change happens.
//
// Discoverers should initially send a full set of all discoverable TargetGroups.
type Discoverer interface {
    // Run hands a channel to the discovery provider(consul,dns etc) through which it can send
    // updated target groups.
    // Must returns if the context gets canceled. It should not close the update
    // channel on returning.
    Run(ctx context.Context, up chan<- []*targetgroup.Group)
}

我们实际上只需要实现一个函数,Run(ctx context.Context, up chan<- []*targetgroup.Group)。这是 Adapter 代码中的管理器将在 goroutine 中调用的函数。Run 函数使用上下文来了解何时退出,并传递一个通道以发送其目标组更新。

查看提供的示例中的 Run 函数,我们可以看到几个需要在其他 SD 的实现中进行的操作。我们定期进行调用,在这种情况下调用 Consul(为了这个示例,假设没有现成的 Consul SD 实现),并将响应转换为一组 targetgroup.Group 结构。由于 Consul 的工作方式,我们必须首先进行一个调用来获取所有已知服务,然后对每个服务进行另一个调用来获取有关所有后端实例的信息。

请注意循环上方对每个服务的 Consul 的调用的注释

// Note that we treat errors when querying specific consul services as fatal for for this
// iteration of the time.Tick loop. It's better to have some stale targets than an incomplete
// list of targets simply because there may have been a timeout. If the service is actually
// gone as far as consul is concerned, that will be picked up during the next iteration of
// the outer loop.

有了它,我们就可以说,如果我们无法获取所有目标的信息,最好不要发送任何更新,而不是发送不完整的更新。我们宁愿在短时间内有一组陈旧的目标,并防止由于瞬时网络问题、进程重启或 HTTP 超时等原因导致的误报。如果我们确实从 Consul 获得了关于每个目标的响应,我们会在通道上发送所有这些目标。还有一个帮助函数 parseServiceNodes,它接受单个服务的 Consul 响应并从后端节点(带有标签)创建目标组。

使用当前示例

在开始编写您自己的自定义 SD 实现之前,建议您先运行当前示例,并查看代码。为了简单起见,我通常在使用示例代码时通过 docker-compose 以 Docker 容器形式运行 Consul 和 Prometheus。

docker-compose.yml

version: '2'
services:
consul:
    image: consul:latest
    container_name: consul
    ports:
    - 8300:8300
    - 8500:8500
    volumes:
    - ${PWD}/consul.json:/consul/config/consul.json
prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
    - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
    - 9090:9090

consul.json

{
"service": {
    "name": "prometheus",
    "port": 9090,
    "checks": [
    {
        "id": "metrics",
        "name": "Prometheus Server Metrics",
        "http": "http://prometheus:9090/metrics",
        "interval": "10s"
    }
    ]

}
}

如果我们通过 docker-compose 启动这两个容器,然后运行示例 main.go,我们将查询 Consul HTTP API 位于 localhost:8500,并且 filesd 兼容文件将被写入为 customsd.json。我们可以通过 file_sd 配置来配置 Prometheus 以获取此文件。

scrape_configs:
  - job_name: "custom-sd"
    scrape_interval: "15s"
    file_sd_configs:
    - files:
      - /path/to/custom_sd.json

Datawire 访谈

作为我们与 Prometheus 用户访谈系列的延续,Datawire 的 Richard Li 谈论了他们如何过渡到 Prometheus。

你能介绍一下你自己以及 Datawire 的工作吗?

在 Datawire,我们制作开源工具来帮助开发人员在 Kubernetes 上更快地编码。我们的项目包括 Telepresence,用于 Kubernetes 服务的本地开发;Ambassador,基于 Envoy Proxy 的 Kubernetes 原生 API 网关;以及 Forge,一个构建/部署系统。

我们在 AWS 中的 Kubernetes 中运行了许多关键任务云服务,以支持我们的开源工作。这些服务支持用例,例如每天动态配置数十个 Kubernetes 集群,这些集群随后被我们的自动化测试基础设施使用。

您在使用 Prometheus 之前的监控体验是什么?

我们使用 AWS CloudWatch。这很容易设置,但我们发现,当我们采用更分布式的开发模型(微服务)时,我们想要更多灵活性和控制权。例如,我们希望每个团队能够根据需要自定义他们的监控,而无需操作人员的帮助。

为什么您决定尝试 Prometheus?

我们有两个主要需求。首先,我们希望我们这里的所有工程师都能对其服务进行操作控制和可视化。我们的开发模型设计高度分散,我们试图避免出现工程师需要等待另一个工程师才能完成某项工作的情况。对于监控,我们希望我们的工程师能够对他们的指标基础设施拥有很大的灵活性和控制权。我们的第二个需求是强大的生态系统。强大的生态系统通常意味着已建立(和记录)的最佳实践、持续开发以及许多可以帮助你解决问题的人。

Prometheus,尤其是 Prometheus Operator,符合我们的需求。使用 Prometheus Operator,每个开发人员可以根据需要创建他们自己的 Prometheus 实例,无需操作人员的帮助(没有瓶颈!)。我们也是 CNCF 的成员,在 Kubernetes 和 Envoy 社区拥有丰富的经验,因此关注另一个 CNCF 社区 Prometheus 是很自然的事情。

Datawire's Ambassador dashboards

你是如何过渡的?

我们知道我们想从将 Prometheus 集成到我们的 API 网关开始。我们的 API 网关使用 Envoy 进行代理,Envoy 使用 statsd 协议自动发出指标。我们安装了 Prometheus Operator(一些详细的说明 在这里)并将其配置为开始收集来自 Envoy 的统计信息。我们还设置了 Grafana 仪表板 基于一些工作 从另一个大使贡献者。

切换后你看到了哪些改进?

我们的工程师现在可以查看 L7 流量。我们还可以使用 Prometheus 来比较金丝雀部署的延迟和吞吐量,从而让我们更有信心新版本的我们的服务不会导致性能下降。

您认为 Datawire 和 Prometheus 的未来会是什么?

使用 Prometheus Operator 仍然有点复杂。我们需要为我们的服务团队找出操作上的最佳实践(您什么时候部署 Prometheus?)。然后,我们需要教育我们的工程师了解这些最佳实践,并培训他们如何配置 Operator 来满足他们的需求。我们预计这将是一个实验领域,因为我们会在实践中找出哪些有效,哪些无效。

Scalefastr 访谈

作为我们与 Prometheus 用户访谈系列的延续,Scalefastr 的 Kevin Burton 谈论了他们如何使用 Prometheus。

你能介绍一下你自己以及 Scalefastr 的工作吗?

我的名字是 Kevin Burton,我是 Scalefastr 的 CEO。我的背景是分布式系统,我之前曾领导 Datastreamer,一家构建了 PB 级规模分布式社交媒体爬虫和搜索引擎的公司。

在 Datastreamer,我们遇到了基础设施的可扩展性问题,并构建了一个基于 Debian、Elasticsearch、Cassandra 和 Kubernetes 的高性能集群。

我们发现,我们的许多客户也在为基础设施而苦恼,我惊讶于他们在 AWS 和 Google Cloud 上托管大量内容所支付的费用。

我们不断评估在云端运行的成本,对于我们来说,我们的托管成本大约是目前支付成本的 5-10 倍。

我们决定推出一个基于开源和云原生技术的新的云平台,例如 Kubernetes、Prometheus、Elasticsearch、Cassandra、Grafana、Etcd 等。

我们目前在 PB 级规模上托管了几个客户,并将于本月对我们的新平台进行软发布。

您在使用 Prometheus 之前的监控体验是什么?

在 Datastreamer,我们发现指标是我们快速迭代的关键。平台的可观测性成为我们所接受的,我们集成了 Dropwizard Metrics 等工具,以简化我们平台的分析开发。

我们构建了一个基于 KairosDB、Grafana 和我们自己的(简单)可视化引擎的平台,它在相当长的一段时间内运行良好。

我们发现 KairosDB 的关键问题是 Prometheus 的采用率和客户需求。

此外,Prometheus 的好处是,它支持由项目本身或社区实现的导出器。

在 KairosDB 中,我们经常会努力构建自己的导出器。与 Prometheus 相比,KairosDB 导出器已经存在的可能性要低得多。

例如,KairosDB 支持 CollectD,但在 Debian 中支持得不是很好,并且 CollectD 存在实际的错误,阻止它在生产中可靠地工作。

使用 Prometheus,您可以快速启动和运行(该系统非常易于安装),并且您的平台准备好的导出器存在的可能性非常高。

此外,我们预计,一旦有像 Scalefastr 这样的托管平台将 Prometheus 集成作为标准化和支持的产品,客户应用程序将开始将 Prometheus 指标标准化。

能够查看应用程序性能至关重要,Prometheus 的高可扩展性是实现这一点的必要条件。

为什么您决定尝试 Prometheus?

我们最初很好奇其他人如何监控他们的 Kubernetes 和容器应用程序。

容器的主要挑战之一是,它们可以快速出现和消失,留下需要分析的日志和指标数据。

当我们看到人们在生产中成功使用 Prometheus 以及容器优先架构(以及对导出器和仪表板的支持)时,我们意识到应该将 Prometheus 作为我们的分析后端进行调查。

One of Scalefastr's Grafana dashboards

你是如何过渡的?

由于 Scalefastr 是一个 Greenfield 环境,因此过渡相对轻松。

架构在很大程度上是新的,限制因素很少。

我们的主要目标是在裸机上部署,但在现有和标准化硬件之上构建云功能。

我们的想法是将我们集群中的所有分析都由 Prometheus 支持。

我们为客户提供他们自己的“管理”基础设施,其中包括 Prometheus、Grafana、Elasticsearch 和 Kibana 以及 Kubernetes 控制平面。我们使用 Ansible 编排此系统,Ansible 处理初始机器设置(ssh、核心 Debian 包等)和基线配置。

然后,我们部署 Prometheus、客户配置所需的所有导出器,以及 Grafana 的额外仪表板。

我们发现有点问题的是,Grafana.com 上的几个仪表板是为 Prometheus 1.x 编写的,无法干净地移植到 2.x。事实证明,2.x 系列中只有一些函数不存在,其中许多函数只需要稍作调整。此外,一些仪表板是为早期版本的 Grafana 编写的。

为了帮助解决这个问题,我们本周宣布了一个项目,标准化和改进 Prometheus 的仪表板,用于 Cassandra、Elasticsearch、操作系统等工具,以及 Prometheus 本身。我们开源了这个项目并于上周 发布到了 Github

我们希望这能让其他人更容易迁移到 Prometheus。

我们想要改进的一件事是自动将其与我们的 Grafana 后端同步,并将这些仪表板上传到 Grafana.com。

我们还发布了我们的 Prometheus 配置,以便标签能够与我们的 Grafana 模板正确配合使用。这允许您使用下拉菜单选择更具体的指标,例如集群名称、实例名称等。

Using template variables in Grafana dashboards

切换后你看到了哪些改进?

易于部署、高性能和标准化的导出器让我们很容易切换。此外,后端非常易于配置(基本上,只需守护进程本身)并且没有太多活动部件,这让我们很容易做出决定。

您认为 Scalefastr 和 Prometheus 的未来会是什么?

现在,我们直接在裸机上部署 Elasticsearch 和 Cassandra。我们正在努力直接在 Kubernetes 之上运行这些容器,并努力使用容器存储接口 (CSI) 来实现这一点。

在我们做到这一点之前,我们需要让 Prometheus 服务发现正常工作,而这正是我们还没有尝试过的。目前,我们通过 Ansible 部署和配置 Prometheus,但显然这无法扩展(甚至无法在 Kubernetes 中工作),因为容器会随着工作负载的变化而出现和消失。

我们还在努力改进标准仪表板和警报。我们想添加的一项功能(可能作为容器)是基于 Holt-Winters 预测的警报支持。

这将实质上允许我们在问题发生之前预测严重的性能问题。而不是等到某些东西出现故障(例如磁盘空间不足)才采取措施进行纠正。

在一定程度上,Kubernetes 有助于解决这个问题,因为我们可以根据水位线向集群添加节点。一旦资源利用率过高,我们就可以自动扩展。

我们对 Prometheus 的未来非常兴奋,尤其是现在我们正在 2.x 系列上取得进展,以及 CNCF 合作似乎进展顺利。

2017 年 CloudNativeCon 上的 Prometheus

2017 年 CloudNativeCon 上的 Prometheus

12 月 6 日星期三是 CloudNativeCon 奥斯汀的普罗米修斯日,我们为您准备了精彩的演讲和活动阵容。前往普罗米修斯沙龙,亲身体验有关如何最佳监控 Kubernetes 的建议,参加一系列关于普罗米修斯各个方面的演讲,然后在 CNCF 展位与一些普罗米修斯开发者交流,所有这一切之后是普罗米修斯欢乐时光。继续阅读以了解更多详情...

宣布普罗米修斯 2.0

宣布普罗米修斯 2.0

大约一年半前,我们将普罗米修斯 1.0 发布到野外。这个版本标志着该项目的一个重要里程碑。我们已经实现了一套广泛的功能,构成了普罗米修斯简单但功能强大的监控理念。

从那时起,我们在各种服务发现集成方面进行了添加和改进,扩展了 PromQL,并尝试了第一代远程 API 以实现可插拔的长期存储解决方案。

但是,还有什么变化值得发布一个新的主要版本呢?

PromCon 2017 回顾

发生了什么

两周前,来自世界各地的普罗米修斯用户和开发者齐聚慕尼黑参加了 PromCon 2017,这是围绕普罗米修斯监控系统的第二届会议。本次活动的目的是交流知识和最佳实践,并围绕使用普罗米修斯进行监控建立专业联系。谷歌慕尼黑办公室今年为我们提供了一个更大的空间,这使我们能够从 80 人增加到 220 人,同时仍然售罄!

观看回顾视频,了解一下活动情况

普罗米修斯 2.0 Alpha.3,包含新规则格式

今天,我们发布了普罗米修斯 2.0 的第三个 alpha 版本。除了新存储层中的一些错误修复之外,它还包含一些计划中的重大更改。

标志更改

首先,我们迁移到一个新的标志库,它使用更常见的双短横线 -- 前缀表示标志,而不是普罗米修斯到目前为止使用的单短横线。部署必须相应地进行调整。此外,此 alpha 版本中已删除了一些标志。自普罗米修斯 1.0.0 以来的完整列表如下

  • web.telemetry-path
  • 所有 storage.remote.* 标志
  • 所有 storage.local.* 标志
  • query.staleness-delta
  • alertmanager.url

记录规则更改

警报规则和记录规则是普罗米修斯的重要功能之一。但它们也存在一些设计问题和缺少的功能,即

  • 所有规则都以相同的间隔运行。我们可以有一些较重的规则,最好以 10 分钟的间隔运行,而另一些规则则可以以 15 秒的间隔运行。

  • 所有规则都是并发评估的,这实际上是普罗米修斯最古老的 未解决的错误。这存在几个问题,最明显的是,如果你有很多规则,那么每次评估间隔的负载都会激增。另一个问题是,相互依赖的规则可能会被提供过时的数据。例如

instance:network_bytes:rate1m = sum by(instance) (rate(network_bytes_total[1m]))

ALERT HighNetworkTraffic
  IF instance:network_bytes:rate1m > 10e6
  FOR 5m

这里,我们针对 instance:network_bytes:rate1m 发出警报,但 instance:network_bytes:rate1m 本身是由另一个规则生成的。只有在记录 instance:network_bytes:rate1m 的当前值之后运行警报 HighNetworkTraffic,我们才能获得预期的结果。

  • 规则和警报要求用户学习另一种 DSL。

为了解决上述问题,规则分组 很久以前就提出了,但直到最近才 作为普罗米修斯 2.0 的一部分 实现。作为此实现的一部分,我们还将规则迁移到众所周知的 YAML 格式,这也使基于用户环境中的常见模式生成警报规则变得更加容易。

以下是新格式的外观

groups:
- name: my-group-name
  interval: 30s   # defaults to global interval
  rules:
  - record: instance:errors:rate5m
    expr: rate(errors_total[5m])
  - record: instance:requests:rate5m
    expr: rate(requests_total[5m])
  - alert: HighErrors
    # Expressions remain PromQL as before and can be spread over
    # multiple lines via YAML’s multi-line strings.
    expr: |
      sum without(instance) (instance:errors:rate5m)
      / 
      sum without(instance) (instance:requests:rate5m)
    for: 5m
    labels:
      severity: critical
    annotations:
      description: "stuff's happening with {{ $labels.service }}"      

每个组中的规则按顺序执行,你可以为每个组设置一个评估间隔。

由于此更改是重大更改,我们将在 2.0 版本中发布它,并且已为 promtool 添加了一个用于迁移的命令:promtool update rules <filenames> 转换后的文件将附加 .yml 后缀,并且必须调整 Prometheus 配置中的 rule_files 子句。

通过测试这个新的 alpha 版本,帮助我们向普罗米修斯 2.0 稳定版发布迈进!你可以在我们的 问题跟踪器 上报告错误,并通过我们的 社区频道 提供一般反馈。

L’Atelier Animation 访谈

我们继续与普罗米修斯用户进行访谈系列,来自 L’Atelier Animation 的 Philippe Panaite 和 Barthelemy Stevens 谈论他们如何将他们的动画工作室从 Nagios、Graphite 和 InfluxDB 的混合环境切换到普罗米修斯。

你能告诉我们关于你自己和 L’Atelier Animation 以及它所做的事情吗?

L’Atelier Animation 是一家位于加拿大蒙特利尔美丽的城市的三维动画工作室。我们的首部动画长片 "芭蕾舞女"(也称为“跳跃”)于 2017 年在全球上映,预计今年晚些时候在美国上映。

我们目前正在紧张地制作一部动画电视剧和我们的第二部动画长片。我们的基础设施由大约 300 台渲染刀片、150 台工作站和 20 台各种服务器组成。除了几台 Mac 之外,所有东西都在 Linux (CentOS) 上运行,没有一台 Windows 机器。 

 

您在使用 Prometheus 之前的监控体验是什么?

  最初,我们使用了 NagiosGraphiteInfluxDB 的组合。最初的设置“还可以”,但没什么特别之处,而且过于复杂(太多活动部件)。 

为什么您决定尝试 Prometheus?

  当我们将所有服务切换到 CentOS 7 时,我们考虑了新的监控解决方案,普罗米修斯出于很多原因浮出水面,但最重要的是

  • 节点导出器:凭借其定制功能,我们可以从客户端获取任何数据
  • SNMP 支持:无需第三方 SNMP 服务
  • 警报系统:告别 Nagios
  • Grafana 支持

你是如何过渡的?

当我们完成第一部电影时,我们经历了一段时间的停机时间,这对我们的 IT 部门来说是进行重大变革的绝佳时机。我们决定冲洗掉整个监控系统,因为它没有达到我们想要的效果。 

监控网络设备是最重要的部分之一,因此我们首先配置了 snmp_exporter 以从我们的一个交换机获取数据。导出器进行的 NetSNMP 调用在 CentOS 下有所不同,因此我们必须重新编译一些二进制文件,我们确实遇到了一些小问题,但在来自 Robust Perception 的 Brian Brazil 的帮助下,我们很快就解决了所有问题。一旦我们让 snmp_exporter 正常运行,我们就能轻松地添加新设备并获取 SNMP 数据。我们现在在 Grafana 中监控着我们的核心网络(包括 13 台交换机、10 个 VLAN)。

Switch metrics from SNMP data

之后,我们配置了 node_exporter,因为我们需要对工作站、渲染刀片和服务器进行分析。在我们这个领域,如果 CPU 没有达到 100%,那么就是一个问题,我们希望利用所有可用的资源,因此最终温度更加重要。此外,我们需要尽可能多的正常运行时间,因此我们所有的工作站都通过普罗米修斯的 Alertmanager 设置了电子邮件警报,以便在任何东西出现故障时我们都能获知。

Dashboard for one workstation

我们的特定需求要求我们监控来自客户端的自定义数据,这可以通过使用 node_exporter 的 textfile collector 功能轻松实现。一个 cron 作业将来自任何给定工具的特定数据输出到预先格式化的文本文件中,该文本文件采用普罗米修斯可读的格式。 

由于所有数据都通过 HTTP 协议提供,我们编写了一个 Python 脚本从普罗米修斯获取数据。我们将它存储在一个 MySQL 数据库中,该数据库可以通过一个 Web 应用程序访问,该应用程序创建一个实时楼层地图。这使我们能够简单地用鼠标悬停在某个用户身上,就知道该用户坐在哪里,使用的是哪种硬件。我们还创建了另一个页面,其中包含用户的照片和部门信息,这有助于新员工了解他们的邻居是谁。该网站仍然是一个正在进行的项目,所以请不要评判它的外观,毕竟我们是系统管理员,而不是 Web 设计师 :-)

Floormap with workstation detail

切换后你看到了哪些改进?

它给了我们一个机会来改变我们监控工作室中所有内容的方式,并激发了我们创建一个新的自定义楼层地图,其中包含最初由普罗米修斯获取的所有数据。这个设置非常简单,只有一个服务来管理所有事情。

你认为 L’Atelier Animation 和普罗米修斯未来会怎样?

我们目前正在将软件许可证使用情况与普罗米修斯集成。这些信息将让艺术家们清楚地了解谁在使用什么以及在哪里使用。

我们将根据用户的需求继续定制和添加新功能到普罗米修斯中,而且由于我们与艺术家合作,我们知道会有很多需求 :-) 凭借 SNMP 和 node_exporter 的自定义文本文件输入,可能性是无限的...

iAdvize 访谈

我们继续与普罗米修斯用户进行访谈系列,来自 iAdvize 的 Laurent COMMARIEU 谈论他们如何用普罗米修斯替换了他们的遗留 Nagios 和 Centreon 监控系统。

你能告诉我们 iAdvize 是做什么的吗?

我是 Laurent COMMARIEU,iAdvize 的系统工程师。我在由 5 名系统工程师组成的 60 人研发部门工作。我们的工作主要是确保应用程序、服务和底层系统正常运行。我们与开发人员合作,确保他们的代码以最简单的方式投入生产,并在每个步骤提供必要的反馈。这就是监控的重要性所在。

iAdvize 是一个全栈式对话式商务平台。我们提供了一种简便的方法,让品牌可以集中与他们的客户互动,无论使用哪种沟通渠道(聊天、通话、视频、Facebook 页面、Facebook Messenger、Twitter、Instagram、WhatsApp、短信等)。我们的客户在 电子商务、银行、旅游、时尚等领域,遍布 40 个国家。我们是一家拥有 200 名员工的跨国公司,在法国、英国、德国、西班牙和意大利设有办事处。我们于 2015 年筹集了 1600 万美元资金。

您在使用 Prometheus 之前的监控体验是什么?

我于 2016 年 2 月加入 iAdvize。之前,我在专门从事网络和应用程序监控的公司工作。我们使用过像 NagiosCactiCentreonZabbixOpenNMS 这样的开源软件,以及一些非免费软件,如 HP NNMIBM Netcool 套件BMC Patrol 等。

iAdvize 过去将监控外包给外部供应商。他们使用 Nagios 和 Centreon 来确保 24/7 监控。这个工具集在遗留的静态架构(基础服务器,没有虚拟机,没有容器)中运行良好。为了完成这个监控栈,我们还使用 Pingdom

随着我们把单体应用迁移到微服务架构(使用 Docker),以及我们希望将现有工作负载迁移到云基础设施提供商,我们需要在监控方面拥有更多控制权和灵活性。与此同时,iAdvize 招募了 3 名员工,使基础设施团队从 2 人增加到 5 人。使用旧系统,至少需要几天或一周才能在 Centreon 中添加一些新指标,而且需要付出真金白银(时间和金钱)。

为什么您决定尝试 Prometheus?

我们知道 Nagios 以及类似工具不是一个好的选择。当时,Prometheus 正在冉冉升起,我们决定进行概念验证。一开始,Sensu 也在候选名单中,但 Prometheus 似乎更适合我们的用例。

我们需要一个能够与 Consul(我们的服务发现系统)集成的工具。我们的微服务已经有了 /health 路由;添加 /metrics 端点非常简单。对于我们使用的几乎所有工具,都有一个可用的导出器(MySQL、Memcached、Redis、nginx、FPM 等)。

从理论上讲,它看起来不错。

One of iAdvize's Grafana dashboards

你是如何过渡的?

首先,我们必须说服开发团队(40 人)Prometheus 是这项工作的正确工具,并且他们必须在应用程序中添加一个导出器。因此,我们对 RabbitMQ 做了一个简单的演示,安装了 RabbitMQ 导出器,并构建了一个简单的 Grafana 仪表板来向开发人员展示使用情况指标。我们编写了一个 Python 脚本,用于创建一些队列并发布/消费消息。

他们对看到队列和消息实时显示感到非常惊讶。在此之前,开发人员无法访问任何监控数据。Centreon 受限于我们的基础设施提供商。如今,iAdvize 的每个人都可以使用 Grafana,使用 Google Auth 集成进行身份验证。它有 78 个活跃帐户(从开发团队到首席执行官)。

在使用 Consul 和 cAdvisor 开始监控现有服务后,我们监控了容器的实际存在。它们是使用 Pingdom 检查进行监控的,但这还不够。

我们使用 Go 开发了一些自定义导出器,从我们的数据库(MySQL 和 Redis)中抓取一些业务指标。

很快,我们就能用 Prometheus 替换所有遗留监控。

One of iAdvize's Grafana dashboards

切换后你看到了哪些改进?

业务指标变得非常受欢迎,在销售旺季,每个人都连接到 Grafana,看看我们是否能够打破一些记录。我们监控着同时对话数量、路由错误、连接的代理、加载 iAdvize 标签的访问者数量、我们 API 网关上的调用等。

我们花了一个月的时间,基于 Newrelic 导出器Percona Grafana 仪表板 对 MySQL 服务器进行优化。这是一次真正的成功,它让我们发现了低效之处,并执行了优化,将数据库大小减少了 45%,峰值延迟减少了 75%。

有很多话要说。我们知道如果 AMQP 队列没有消费者,或者它正在异常填充。我们知道何时容器重启。

可见性简直棒极了。

那仅仅是针对遗留平台。

越来越多的微服务将部署到云中,Prometheus 用于监控它们。我们使用 Consul 来注册服务,使用 Prometheus 来发现指标路由。一切都像魅力一样工作,我们能够使用 Grafana 仪表板构建许多关键的业务、应用程序和系统指标。

我们正在构建一个可扩展的架构,使用 Nomad 部署我们的服务。Nomad 在 Consul 中注册健康的服务,并且通过一些标签重标记,我们可以过滤那些带有标签名称“metrics=true”的服务。这为我们带来了巨大的时间优势,可以部署监控。我们什么都不用做 ^^。

我们还使用 EC2 服务发现。它对于自动扩展组非常有用。我们扩展和回收实例,它已经被监控。无需再等待外部基础设施提供商来注意到生产环境中发生了什么。

我们使用 alertmanager 通过短信或到我们的 Flowdock 发送一些警报。

你认为 iAdvize 和 Prometheus 的未来会是什么?

  • 我们正在等待一种简单的方法,为我们的容量规划添加长期可扩展存储。
  • 我们有一个梦想,有一天,我们的自动扩展将由 Prometheus 警报触发。我们希望建立一个基于响应时间和业务指标的自主系统。
  • 我以前使用过 Netuitive,它有一个很棒的异常检测功能,可以自动关联。如果 Prometheus 中有一些这样的功能,那就太好了。

Prometheus 2.0 的抢先看

2016 年 7 月,Prometheus 发布了 1.0 版本,达到了一个重要的里程碑。从那时起,添加了许多新功能,例如新的服务发现集成和我们实验性的远程 API。我们还意识到,基础设施领域的最新发展,特别是 Kubernetes,使得监控环境变得更加动态。不出所料,这也给 Prometheus 带来了新的挑战,我们在它的存储层发现了性能瓶颈。

在过去几个月里,我们一直在设计和实施一种新的存储概念,它解决了这些瓶颈,并且整体性能有了显着提高。它也为添加热备份等功能铺平了道路。

这些变化非常基础,将触发一个新的主要版本:Prometheus 2.0。
在它稳定发布之前,计划了许多重要功能和更改。然而,今天我们发布了 Prometheus 2.0 的早期 Alpha 版本,以启动新存储的稳定过程。

发行版 tarballsDocker 容器 现在已经可用。如果您对存储的新机制感兴趣,请务必阅读 深入了解博客文章,了解其内部机制。

此版本不适用于旧的存储数据,不应替换现有的生产部署。要运行它,数据目录必须为空,并且除了 -storage.local.retention 之外,所有现有的存储标志都必须删除。

例如;之前

./prometheus -storage.local.retention=200h -storage.local.memory-chunks=1000000 -storage.local.max-chunks-to-persist=500000 -storage.local.chunk-encoding=2 -config.file=/etc/prometheus.yaml

之后

./prometheus -storage.local.retention=200h -config.file=/etc/prometheus.yaml

这是一个非常早期的版本,可能会出现崩溃、数据损坏和一般的错误。通过将它们提交到 我们的问题跟踪器,帮助我们走向稳定版本。

实验性的远程存储 API 在此 Alpha 版本中被禁用。抓取暴露时间戳的目标,例如联合 Prometheus 服务器,目前还无法工作。存储格式正在破坏,并且将在后续 Alpha 版本之间再次破坏。我们计划在接近稳定版本时记录从 1.0 升级到 2.0 的路径。

与 Europace 的访谈

在我们对 Prometheus 用户进行的一系列采访中,Europace 的 Tobias Gesellchen 讲述了他们是如何发现 Prometheus 的。

你能告诉我们 Europace 是做什么的吗?

Europace AG 开发和运营基于网络的 EUROPACE 金融市场,它是德国最大的抵押贷款、建筑融资产品和个人贷款平台。一个完全集成的系统连接了大约 400 个合作伙伴——银行、保险公司和金融产品分销商。数千名用户每月在 EUROPACE 上执行大约 35,000 笔交易,总价值高达 40 亿欧元。我们的工程师定期在 http://tech.europace.de/@EuropaceTech 上发表博客文章。

您在使用 Prometheus 之前的监控体验是什么?

Nagios/Icinga 仍在用于其他项目,但随着服务数量的增长和对灵活性的更高需求,我们寻求其他解决方案。由于 Nagios 和 Icinga 维护更加集中,Prometheus 符合我们的目标,即让我们的团队拥有完整的 DevOps 堆栈,并将特定的职责从我们的基础设施团队转移到项目成员。

为什么您决定尝试 Prometheus?

通过我们在 Docker Berlin 社区 中的活动,我们一直与 SoundCloudJulius Volz 保持联系,他们给了我们一个很好的概述。灵活的 Docker 容器与高度灵活的基于标签的概念相结合,让我们决定尝试一下 Prometheus。Prometheus 的设置非常容易,Alertmanager 满足了我们的需求,因此我们没有看到尝试其他替代方案的理由。即使我们为了改进 Docker 环境和消息工具的集成而做出的微不足道的拉取请求也很快被合并。随着时间的推移,我们在堆栈中添加了几个导出器和 Grafana。我们从未回头,也从未寻找过替代方案。

Grafana dashboard for Docker Registry

你是如何过渡的?

我们的团队在一个新项目中引入了 Prometheus,因此过渡并没有发生在我们的团队中。其他团队开始将 Prometheus 并行添加到现有解决方案中,然后逐步迁移指标收集器。自定义导出器和其他临时服务在迁移过程中提供帮助。Grafana 已经存在,所以我们不必考虑其他仪表板。一些项目仍然同时使用 Icinga 和 Prometheus。

切换后你看到了哪些改进?

我们使用 Icinga 时遇到了可扩展性问题——多个团队维护一个集中管理的解决方案效果不佳。使用 Prometheus 堆栈以及 Alertmanager 使我们的团队和项目分离。Alertmanager 现在能够以 高可用性模式 部署,这是对我们监控基础设施核心的一项重大改进。

你认为 Europace 和 Prometheus 的未来会是什么?

我们公司中的其他团队已在其项目中逐步采用 Prometheus。我们预计更多项目将引入 Prometheus 以及 Alertmanager,并逐渐替换 Icinga。借助 Prometheus 固有的灵活性,我们预计它将随着我们的需求而扩展,并且我们不会遇到将其适应未来需求的问题。

与 Weaveworks 的访谈

在我们对 Prometheus 用户进行的一系列采访中,Weaveworks 的 Tom Wilkie 讲述了他们是如何选择 Prometheus 的,以及现在如何基于它进行构建。

你能告诉我们 Weaveworks 是做什么的吗?

Weaveworks 提供 Weave Cloud,这是一项“运行”微服务的服务,它结合了开源项目和软件即服务。

Weave Cloud 包括

您可以 免费试用 Weave Cloud 60 天。有关我们产品的最新信息,请查看我们的 博客TwitterSlack (邀请)。

您在使用 Prometheus 之前的监控体验是什么?

Weave Cloud 是一个全新实现,因此没有以前的监控系统。在之前的生活中,团队使用过 Munin 和 Nagios 等典型工具。Weave Cloud 最初是一个多租户的 Scope 托管版本。Scope 包括对 CPU 和内存使用情况等的基本监控,所以我想你可以说我们使用了它。但我们需要一些东西来监控 Scope 本身...

为什么您决定尝试 Prometheus?

我们团队有许多前 Google SRE,因此拥有丰富的 Borgmon 使用经验,还拥有一位前 SoundCloud 员工,拥有 Prometheus 的使用经验。我们使用 Kubernetes 构建了服务,并一直在寻找能够与其动态调度特性相匹配的监控工具。因此,Prometheus 是不二之选。我们甚至写了一系列博客文章,其中第一篇是 关于 Prometheus 和 Kubernetes 为什么如此契合

你是如何过渡的?

当我们开始使用 Prometheus 时,Kubernetes 服务发现还只是一个 PR,因此文档很少。我们运行了一个自定义版本一段时间,并努力摸索着解决问题。最终我们在 伦敦 Prometheus 聚会 上分享了我们的经验 演讲,并发布了一系列 博客 文章 文章

我们尝试过几乎所有运行 Prometheus 的不同方案。我们最初构建了自己的带有嵌入式配置的容器镜像,将它们全部一起运行在一个 Pod 中,与 Grafana 和 Alert Manager 并排。我们使用短暂的、Pod 内的存储来存放时间序列数据。然后我们将它们分解成不同的 Pod,这样我们就不必在更改仪表板时重新启动 Prometheus(并丢失历史数据)。最近,我们开始使用上游镜像,并将配置存储在 Kubernetes 配置映射中,当我们更改配置时,CI 系统会更新它。我们在 Prometheus Pod 中使用了一个小的 sidecar 容器来监视配置文件,并在配置文件更改时 ping Prometheus。这意味着我们不必经常重新启动 Prometheus,可以避免使用任何花哨的存储方式,并且不会丢失历史数据。

然而,周期性地丢失 Prometheus 历史数据的问题仍然困扰着我们,现有的解决方案,如 Kubernetes 卷或定期 S3 备份,都有其缺点。再加上我们使用 Prometheus 监控 Scope 服务的绝佳体验,这促使我们构建了一个云原生、分布式的 Prometheus 版本——一个可以在升级、重新分配和主机故障的情况下,不会丢失历史数据的版本。这就是 Weave Cortex 的诞生。

切换后你看到了哪些改进?

暂时不考虑 Cortex,我们对 HA Alert Manager 的引入特别兴奋;主要是因为它是 第一个使用 Weave Mesh 的非 Weaveworks 项目,而 Weave Mesh 是我们的八卦和协调层。

我还特别关注 Fabian 做的第二版 Kubernetes 服务发现的更改——它解决了一个我们监控 Consul Pod 时遇到的严重问题,我们当时需要在同一个 Pod 上抓取多个端口。

如果我不提远程写入功能(我亲自参与开发的),那就太失职了。有了它,Prometheus 成为 Weave Cortex 本身的一个关键组件,它抓取目标并向我们发送样本。

你觉得 Weaveworks 和 Prometheus 的未来会怎样?

对我来说,近期目标是 Weave Cortex,Weaveworks 的 Prometheus 作为一项服务。我们在内部广泛使用它,并且已经开始实现相当不错的查询性能。它现在正在生产环境中运行,并拥有真正的用户。不久之后,我们将引入对警报的支持,并实现与上游 Prometheus 的功能一致。在此之后,我们将进入一个稳定性测试阶段,然后再在年中全面发布。

作为 Cortex 的一部分,我们开发了一个智能的 Prometheus 表达式浏览器,它具有 PromQL 的自动补全功能,以及类似 Jupyter 的笔记本功能。我们期待让更多人使用它,并最终将其开源。

我还有一个名为 Loki 的小型副项目,它将 Prometheus 的服务发现和抓取功能引入 OpenTracing,并使分布式跟踪变得容易和可靠。我将在 3 月底的 KubeCon/CNCFCon 柏林会议 上做一个关于这个项目的演讲。

Canonical 访谈

继续我们的 Prometheus 用户访谈系列,Canonical 谈论了他们是如何过渡到 Prometheus 的。

你能谈谈你自己以及 Canonical 在做什么吗?

Canonical 可能最出名的是赞助 Ubuntu Linux 的公司。我们还制作或贡献了许多其他开源项目,包括 MAAS、Juju 和 OpenStack,并为这些产品提供商业支持。Ubuntu 为大多数 OpenStack 部署提供支持,在生产云中占 55%,在大型云部署中占 58%

我的团队 BootStack 是我们的全托管私有云服务。我们为 Canonical 客户构建和运营 OpenStack 云。

您在使用 Prometheus 之前的监控体验是什么?

我们曾经使用过 NagiosGraphite/statsd 和内部 Django 应用程序的组合。它们不能在我们的内部和客户云环境中提供我们所需的灵活性和报告功能。

为什么您决定尝试 Prometheus?

我们评估了一些替代方案,包括 InfluxDB 和扩展我们对 Graphite 的使用,但我们对 Prometheus 的第一印象表明它具有我们所寻找的简单性和强大性。我们尤其欣赏标签的便捷性、简单的 HTTP 协议和开箱即用的 时间序列警报。Prometheus 有潜力用一个工具取代两个不同的工具(警报和趋势),这特别吸引人。

此外,我们的一些员工在 Google 工作期间有使用 Borgmon 的经验,这极大地增加了我们对 Prometheus 的兴趣!

你是如何过渡的?

我们仍在过渡过程中,预计这将需要一些时间,因为我们当前系统中使用的自定义检查数量众多,需要在 Prometheus 中重新实现。最有用的资源是 prometheus.io 网站文档。

我们花了一段时间才选择一个导出器。我们最初选择的是 collectd,但遇到了限制。我们现在正在编写一个 openstack-exporter,并且有点惊讶地发现没有好的、可用的、从头开始编写导出器的示例。

我们遇到的挑战包括:没有下采样支持、没有长期存储解决方案(尚未),并且我们对默认的 2 周保留期感到惊讶。目前没有与 Juju 的集成,但 我们正在努力实现它

切换后你看到了哪些改进?

一旦我们掌握了导出器的窍门,我们发现它们非常容易编写,并为我们提供了非常有用的指标。例如,我们正在为我们的云环境开发一个 openstack-exporter。我们还看到了 DevOps 和 WebOps 团队以及开发人员的快速跨团队采用。我们还没有实现警报,但预计一旦进入过渡阶段的这个阶段,我们将看到更多警报。

你觉得 Canonical 和 Prometheus 的未来会怎样?

我们预计 Prometheus 将成为我们监控和报告基础架构的重要组成部分,为众多当前和未来的系统提供指标收集和存储。我们认为它有可能取代 Nagios,成为警报工具。

JustWatch 访谈

继续我们的 Prometheus 用户访谈系列,JustWatch 谈论了他们是如何建立监控系统的。

你能谈谈你自己以及 JustWatch 在做什么吗?

对于消费者来说,JustWatch 是一个流媒体搜索引擎,可以帮助用户找到在网上和影院合法观看电影和电视剧的地方。你可以在 17 个国家/地区搜索所有主要流媒体提供商(如 Netflix、HBO、亚马逊视频、iTunes、Google Play 等)的电影内容。

对于我们的客户(如电影制片厂或视频点播提供商),我们是一家国际电影营销公司,从我们的消费者应用程序中收集有关全球影迷的购买行为和电影品味的匿名数据。我们帮助制片厂将他们的内容广告投放到合适的受众,并使数字视频广告更有效地减少浪费覆盖面。

JustWatch logo

自从我们在 2014 年推出以来,我们从零发展成为国际上 20,000 个最大网站之一,并且没有花费一分钱的营销费用,在不到两年的时间里成为全球最大的流媒体搜索引擎。目前,我们拥有一个只有 10 人的工程团队,构建并运营着大约 50 个微服务和宏服务的全容器化栈,大部分运行在 Kubernetes 上。

您在使用 Prometheus 之前的监控体验是什么?

在我们之前工作的公司,我们中的许多人都使用过大多数开源监控产品。我们在使用 NagiosIcingaZabbixMonitMuninGraphite 和一些其他系统方面拥有相当丰富的经验。在一家人公司,我帮助使用 Puppet 构建了一个分布式 Nagios 设置。这个设置很好,因为新服务会自动出现在系统中,但将实例移除仍然很痛苦。一旦你的系统中出现了一些差异,基于主机和服务的监控套件就不太适合了。Prometheus 采用的基于标签的方法是我一直想要拥有的,但之前没有找到。

为什么您决定尝试 Prometheus?

在 JustWatch,Prometheus 的公开发布恰逢其时。我们在公司成立的头几个月里主要进行黑盒监控——CloudWatch 用于一些最重要的内部指标,加上 Pingdom 等外部服务来检测全站范围的故障。此外,没有一个经典的基于主机的解决方案让我们满意。在一个容器和微服务的世界里,像 Icinga、Thruk 或 Zabbix 这样的基于主机的工具感觉过时了,无法胜任这项工作。当我们开始调查白盒监控时,我们中的一些人幸运地参加了 Golang 聚会,Julius 和 Björn 在聚会上宣布了 Prometheus。我们很快设置了一个 Prometheus 服务器,并开始为我们的 Go 服务(我们几乎只使用 Go 作为后端)添加监控。这非常容易——设计感觉像是从一开始就面向云和服务,而且从来没有妨碍我们。

你是如何过渡的?

过渡并不难,因为时间上,我们很幸运地直接从没有相关的监控过渡到 Prometheus。

过渡到 Prometheus 主要包括在我们的应用程序中包含 Go 客户端,以及包装 HTTP 处理程序。我们还编写并部署了几个导出器,包括 node_exporter 和几个云提供商 API 的导出器。根据我们的经验,监控和警报是一个永远无法完成的项目,但大部分工作作为一项副项目在几周内就完成了。

自从部署了 Prometheus 以来,我们倾向于在错过某些东西时,或者在从头开始设计新服务时,查看指标。

我们花了一些时间才完全理解 PromQL 和标签概念的优雅之处,但付出的努力确实得到了回报。

切换后你看到了哪些改进?

Prometheus 通过使白盒监控和基于标签的金丝雀部署的收益变得极其容易,为我们带来了启迪。许多 Golang 方面的开箱即用指标(HTTP 处理程序、Go 运行时)帮助我们快速获得投资回报 - 仅 goroutine 指标就多次拯救了我们。我们之前唯一真正喜欢的监控组件 - Grafana - 与 Prometheus 非常契合,并允许我们创建一些非常有用的仪表盘。我们很欣赏 Prometheus 没有试图重新发明轮子,而是完美地融入到最好的解决方案中。与之前系统相比的另一个重大改进是 Prometheus 关注实际的数学计算(百分位数等)。在其他系统中,我们从未确定提供的操作是否有意义。尤其是百分位数,作为一种关于微服务性能的自然且必要的推理方式,它们得到了一流的待遇,这让我们感觉很棒。

Database Dashboard

集成的服务发现使管理抓取目标变得超级容易。对于 Kubernetes,一切都开箱即用。对于一些尚未运行在 Kubernetes 上的其他系统,我们使用 基于 Consul 的 方法。要让 Prometheus 监控应用程序,只需添加客户端,公开 /metrics 并对容器/Pod 设置一个简单的注释。这种低耦合消除了开发和运维之间的很多摩擦 - 很多服务从一开始就构建得井井有条,因为这很简单且很有趣。

时间序列和巧妙的功能的结合造就了令人惊叹的警报超能力。在服务器上运行的聚合,以及将时间序列、它们的组合,甚至这些组合上的函数作为一等公民来对待,使警报变得轻而易举 - 通常是在事后。

您认为 JustWatch 和 Prometheus 的未来会怎样?

虽然我们非常重视 Prometheus 不专注于光鲜亮丽,而是专注于实际工作和交付价值,同时易于部署和操作 - 尤其是 Alertmanager 还需要改进很多。只需一些简单的改进,例如简化前端的交互式警报构建和编辑,就能大大简化警报的处理。

我们非常期待存储层面的持续改进,包括远程存储。我们也希望 Project PrismVulcan 中采用的某些方法能够回移植到核心 Prometheus。目前对我们来说最有趣的话题是 GCE 服务发现、更轻松的扩展和更长的保留期限(即使是以较冷的存储和对较旧事件的更长查询时间为代价)。

我们也期待将 Prometheus 用于更多非技术部门。我们希望用 Prometheus 覆盖我们的大部分 KPI,让每个人都能创建漂亮的仪表盘,以及警报。我们甚至正在计划滥用强大的警报引擎来开发一个新的内部业务项目 - 请拭目以待!

与 Compose 的访谈

在我们的 Prometheus 用户访谈系列中,Compose 谈论了他们从 Graphite 和 InfluxDB 到 Prometheus 的监控之旅。

您能告诉我们关于您自己和 Compose 的情况吗?

Compose 为全球的开发者提供生产就绪的数据库集群作为服务。应用程序开发者可以来到我们这里,只需点击几下鼠标,即可在几分钟内获得一个多主机、高可用、自动备份且安全的数据库。这些数据库部署会随着需求的增加而自动扩展,因此开发者可以将时间花在构建伟大的应用程序上,而不是运行数据库上。

我们在 AWS、Google Cloud Platform 和 SoftLayer 中的每个地区都有数十个主机集群。每个集群跨越支持的可用区,拥有大约 1000 个高可用数据库部署,这些部署都在自己的私有网络中。更多地区和提供商正在筹备中。

您在使用 Prometheus 之前的监控体验是什么?

在 Prometheus 之前,我们尝试过许多不同的指标系统。我们尝试的第一个系统是 Graphite,它最初工作得很好,但我们必须存储的各种指标的巨大数量,加上 Whisper 文件在磁盘上的存储和访问方式,很快让我们的系统不堪重负。虽然我们知道 Graphite 可以相对容易地横向扩展,但这将是一个昂贵的集群。InfluxDB 看起来更有前景,所以我们开始尝试使用早期的版本,它似乎工作了一段时间。再见 Graphite。

早期的 InfluxDB 版本偶尔会出现数据损坏问题。我们经常不得不清除所有指标。对于我们来说,这通常不是毁灭性的损失,但它很烦人。对始终没有实现的功能的持续承诺,坦率地说,让我们感到厌烦。

为什么您决定尝试 Prometheus?

它似乎将更高的效率与更简单的操作结合在一起,优于其他选项。

最初,基于拉取的指标收集让我们感到困惑,但我们很快意识到了它的优势。最初,它似乎在我们的环境中很难扩展,因为我们经常在每个主机上拥有数百个容器,每个容器都有自己的指标,但通过将它与 Telegraf 结合起来,我们可以安排每个主机通过一个 Prometheus 抓取目标来导出所有容器的指标(以及其整体资源指标)。

你是如何过渡的?

我们是一家 Chef 公司,所以我们启动了一个大型实例,并使用了一个大型 EBS 卷,然后直接使用 社区 Chef 食谱 来运行 Prometheus。

在 Prometheus 在主机上启动后,我们编写了一个小型 Ruby 脚本,该脚本使用 Chef API 查询所有主机,并写入一个 Prometheus 目标配置文件。我们使用该文件与 file_sd_config 确保所有主机在注册到 Chef 后立即被发现和抓取。由于 Prometheus 的开放生态系统,我们可以开箱即用 Telegraf,并使用简单的配置直接导出主机级指标。

我们正在测试单个 Prometheus 的扩展能力,并等待它崩溃。它没有!实际上,它处理了约 450 个主机上每 15 秒抓取一次主机级指标的负载,而我们的新基础设施的资源使用量非常少。

每个主机上都有很多容器,所以我们预计在添加了所有这些容器的内存使用指标后,我们将不得不开始对 Prometheus 进行分片,但 Prometheus 继续运行,没有任何问题,而且还没有接近资源饱和。我们目前每 15 秒监控超过 400,000 个不同的指标,这些指标来自约 40,000 个容器,分布在 450 个主机上,而这一切都由一个 m4.xlarge Prometheus 实例完成,该实例拥有 1TB 的存储空间。您可以看到下方关于此主机的主机仪表盘。1TB gp2 SSD EBS 卷的磁盘 IO 可能是最终的限制因素。我们最初的猜测是现在过度配置了,但我们监控的指标和主机/容器数量都在快速增长。

Prometheus Host Dashboard

此时,我们用来测试的 Prometheus 服务器比之前使用 InfluxDB 集群执行相同任务的服务器可靠得多,所以我们做了一些基础工作,使其不再那么容易成为单点故障。我们添加了另一个相同的节点来抓取所有相同的目标,然后添加了一个简单的故障转移方案,该方案使用 keepalived + DNS 更新。现在,它比之前系统更高可用,因此我们切换了面向客户的图表以使用 Prometheus,并拆除了旧系统。

Prometheus-powered memory metrics for PostgresSQL containers in our app

切换后你看到了哪些改进?

我们之前的监控设置不可靠,难以管理。使用 Prometheus,我们拥有一个系统,该系统可以很好地绘制大量指标,并且我们的团队成员对使用 Prometheus 的新方法感到兴奋,而不是对我们之前使用的指标系统感到担忧。

集群也更简单,只有两个相同的节点。随着我们的增长,我们知道我们将不得不在更多 Prometheus 主机上对工作进行分片,并且已经考虑了几种方法来实现这一点。

您认为 Compose 和 Prometheus 的未来会怎样?

现在,我们只复制了之前系统中已经收集的指标 - 客户容器的基本内存使用量,以及我们自己操作的主机级资源使用量。下一步是让数据库团队将指标从 DB 容器内部推送到本地 Telegraf 实例,这样我们就可以记录数据库级别的统计信息,而不会增加抓取目标的数量。

我们还有几个其他系统,我们希望将其纳入 Prometheus 中,以获得更好的可视性。我们在 Mesos 上运行应用程序,并且已经集成了基本的 Docker 容器指标,这比以前更好,但我们还想让 Mesos 集群中的更多基础设施组件记录到中央 Prometheus 中,这样我们就可以拥有集中化的仪表盘,显示从负载均衡器到应用程序指标的所有支持系统运行状况元素。

最终,我们将不得不对 Prometheus 进行分片。我们已经出于各种原因将客户部署拆分到许多较小的集群中,所以一个合乎逻辑的选择是迁移到每个集群使用更小的 Prometheus 服务器(或一对用于冗余),而不是单个全局服务器。

对于大多数报告需求来说,这不是什么大问题,因为我们通常不需要在同一个仪表盘中显示来自不同集群的主机/容器,但我们可能会保留一个小型全局集群,该集群具有更长的保留时间,并且只包含来自每个集群 Prometheus 的少量下采样和聚合指标,使用 Recording Rules。

与 DigitalOcean 的访谈

在我们的 Prometheus 用户访谈系列中,DigitalOcean 谈论了他们如何使用 Prometheus。Carlos Amedee 也在 PromCon 2016 上谈论了 部署的社会方面

您能告诉我们关于您自己和 DigitalOcean 的情况吗?

我的名字是 Ian Hansen,我在平台指标团队工作。DigitalOcean 提供简单的云计算。到目前为止,我们在 13 个地区创建了 2000 万个 Droplet(SSD 云服务器)。我们最近还发布了一个新的块存储产品。

DigitalOcean logo

您在使用 Prometheus 之前的监控体验是什么?

在 Prometheus 之前,我们运行着 GraphiteOpenTSDB。Graphite 用于更小规模的应用程序,OpenTSDB 用于通过 Collectd 收集来自我们所有物理服务器的指标。Nagios 会拉取这些数据库以触发警报。我们仍然使用 Graphite,但我们不再运行 OpenTSDB。

为什么您决定尝试 Prometheus?

我对 OpenTSDB 感到沮丧,因为我负责让集群保持在线状态,但发现很难防范指标风暴。有时,一个团队会启动一个新的(非常健谈的)服务,这会影响集群的总容量,并影响我的 SLA。

我们能够将进入 OpenTSDB 的新指标列入黑名单/白名单,但除了组织流程(很难改变/执行)之外,没有很好的方法来防范健谈的服务。其他团队对当时的查询语言和可视化工具感到沮丧。我和 Julius Volz 聊了关于推拉式指标系统,当我看到我真的可以控制自己的 SLA 时,我决定尝试使用 Prometheus,因为我可以确定要拉取的内容以及拉取的频率。此外,我真的很喜欢它的查询语言。

你是如何过渡的?

我们通过 Collectd 收集指标,并将其发送到 OpenTSDB。与我们已经运行的 Collectd 设置并行安装 Node Exporter 使我们能够开始试验 Prometheus。我们还创建了一个自定义导出器来公开 Droplet 指标。很快,我们就拥有了与 OpenTSDB 服务功能相同的服务,并开始关闭 Collectd,然后关闭了 OpenTSDB 集群。

人们非常喜欢 Prometheus 以及它附带的可视化工具。突然之间,我们小型指标团队积压了大量工作,我们无法快速完成以使大家满意,于是我们没有为人们的服务提供和维护 Prometheus,而是考虑创建工具,让其他团队尽可能轻松地运行他们自己的 Prometheus 服务器,以及运行我们在公司使用的通用导出器。

一些团队已经开始使用 Alertmanager,但我们仍然保留从现有监控工具中提取 Prometheus 的概念。

切换后你看到了哪些改进?

我们改进了对虚拟机监控的见解。从 Collectd 和 Node Exporter 获取的数据大致相同,但对于我们 Golang 开发人员团队来说,创建新的自定义导出器更容易,可以公开我们在每个虚拟机上运行的服务的特定数据。

我们正在公开更好的应用程序指标。学习和教授如何创建 Prometheus 指标更容易,这样指标以后可以正确地聚合。使用 Graphite,很容易创建出一个指标,以后无法以某种方式聚合,因为点分隔名称的结构不正确。

创建警报比以前快得多,也简单得多,而且使用熟悉的语言。这使团队能够为他们了解和理解的服务创建更好的警报,因为他们可以快速迭代。

你认为 DigitalOcean 和 Prometheus 的未来会怎样?

我们一直在寻找如何使 DigitalOcean 团队尽可能轻松地收集指标。现在,团队正在为他们关心的内容运行他们自己的 Prometheus 服务器,这使我们能够获得我们原本不会很快获得的可观察性。但是,并非每个团队都应该知道如何运行 Prometheus。我们正在研究可以做些什么,使 Prometheus 尽可能自动化,这样团队就可以专注于他们希望对服务和数据库进行哪些查询和警报。

我们还创建了 Vulcan,以便我们拥有长期数据存储,同时保留了 Prometheus 查询语言,我们围绕它构建了工具,并培训了人们如何使用它。

ShuttleCloud 访谈

继续我们与 Prometheus 用户的系列访谈,ShuttleCloud 谈论了他们如何开始使用 Prometheus。来自 ShuttleCloud 的 Ignacio 也解释了 Prometheus 对你的小型创业公司有益 在 PromCon 2016 上。

ShuttleCloud 做什么?

ShuttleCloud 是全球最可扩展的电子邮件和联系人数据导入系统。我们帮助一些领先的电子邮件和通讯录提供商(包括 Google 和 Comcast)通过数据导入自动化切换体验,从而提高用户增长和参与度。

通过将我们的 API 集成到他们的产品中,我们的客户允许他们的用户轻松地将他们的电子邮件和联系人从一个参与提供商迁移到另一个提供商,减少了用户在切换到新提供商时面临的阻力。支持的 24/7 电子邮件提供商包括所有主要的美国互联网服务提供商:Comcast、时代华纳有线、AT&T、Verizon 等。

通过为最终用户提供一个简单的电子邮件迁移路径(同时完全控制导入工具的 UI),我们的客户显着改善了用户激活和入门体验。

ShuttleCloud's integration with Gmail ShuttleCloud 与 Google 的 Gmail 平台 集成 Gmail 通过我们的 API 为 300 万用户导入了数据。

ShuttleCloud 的技术对所有用于处理导入所需的数据进行加密,此外还遵循最安全标准(SSL、oAuth),以确保 API 请求的机密性和完整性。我们的技术使我们能够保证我们平台的高可用性,并提供高达 99.5% 的正常运行时间保证。

ShuttleCloud by Numbers

您在使用 Prometheus 之前的监控体验是什么?

起初,一个合适的基础设施监控系统并不是我们的主要优先事项。我们没有现在这么多项目和实例,所以我们使用其他简单的系统来提醒我们,如果任何东西运行不正常,并将其控制起来。

  • 我们有一套自动脚本用于监控机器的大部分运行指标。这些脚本基于 cron 并在集中式机器上使用 Ansible 执行。警报是直接发送给整个开发团队的电子邮件。
  • 我们信任 Pingdom 进行外部黑盒监控,并检查我们所有前端是否正常运行。如果我们的任何外部服务不可达,它们提供了简便的界面和警报系统。

幸运的是,大客户来了,SLA 开始变得更加苛刻。因此,我们需要其他东西来衡量我们的表现,并确保我们遵守所有 SLA。我们需要的功能之一是获得有关我们性能和业务指标的准确统计数据(例如,有多少次迁移成功完成),因此报告比监控更受关注。

我们开发了以下系统

Initial Shuttlecloud System

  • 所有必要数据的来源是 CouchDB 中的状态数据库。在那里,每个文档代表一次操作的状态。这些信息由状态导入器处理,并以关系方式存储在 MySQL 数据库中。

  • 一个组件从该数据库收集数据,并将信息聚合并后处理到几个视图中。

    • 其中一个视图是电子邮件报告,这是我们出于报告目的所需的。它是通过电子邮件发送的。
    • 另一个视图将数据推送到仪表盘,在那里可以轻松控制它。我们使用的仪表盘服务是外部的。我们信任 Ducksboard,不仅因为它很容易设置仪表盘,看起来也很漂亮,而且因为它们在达到阈值时提供自动警报。

有了这一切,我们很快意识到,随着项目数量的增加,我们将需要一个合适的指标、监控和警报系统。

我们当时使用的系统的缺点有

  • 没有集中式监控系统。每种指标类型都有一个不同的监控系统
    • 系统指标 → 由 Ansible 运行的脚本。
    • 业务指标 → Ducksboard 和电子邮件报告。
    • 黑盒指标 → Pingdom。
  • 没有标准的警报系统。每种指标类型都有不同的警报(电子邮件、推送通知等)。
  • 有些业务指标没有警报。这些是手动审查的。

为什么您决定尝试 Prometheus?

我们分析了几个监控和警报系统。我们渴望亲自动手,看看解决方案是成功还是失败。我们决定进行测试的系统是 Prometheus,原因如下

  • 首先,你不需要定义一个固定的指标系统来开始使用它;以后可以添加或更改指标。当你还不知道想要监控的所有指标时,这提供了宝贵的灵活性。
  • 如果你了解 Prometheus,你就会知道指标可以有标签,使我们不必关心不同的时间序列是如何被考虑的。这与它的查询语言一起,提供了更大的灵活性,并成为一个强大的工具。例如,我们可以为不同的环境或项目定义相同的指标,并获得特定时间序列,或使用合适的标签聚合某些指标
    • http_requests_total{job="my_super_app_1",environment="staging"} - 对应于应用程序 "my_super_app_1" 的暂存环境的时间序列。
    • http_requests_total{job="my_super_app_1"} - 应用程序 "my_super_app_1" 所有环境的时间序列。
    • http_requests_total{environment="staging"} - 所有作业的所有暂存环境的时间序列。
  • Prometheus 支持用于服务发现的 DNS 服务。碰巧我们已经拥有一个内部 DNS 服务。
  • 无需安装任何外部服务(例如,与 Sensu 不同,Sensu 需要像 Redis 这样的数据存储服务和像 RabbitMQ 这样的消息总线)。这可能不是一个决定性因素,但它确实使测试更容易执行、部署和维护。
  • Prometheus 很容易安装,你只需要下载一个可执行的 Go 文件。Docker 容器也运行良好,易于启动。

你是如何使用 Prometheus 的?

最初我们只使用 node_exporter 开箱即用的某些指标,包括

  • 硬盘使用情况。
  • 内存使用情况。
  • 实例是否正常运行。

我们的内部 DNS 服务被集成到用于服务发现,因此每个新实例都会自动监控。

我们使用了一些 node_exporter 默认情况下未提供的指标,这些指标是使用 node_exporter 文本文件收集器 功能导出的。我们在 Prometheus Alertmanager 上声明的第一个警报主要与上述运行指标有关。

我们后来开发了一个操作导出器,使我们能够几乎实时地了解系统的状态。它公开了业务指标,即所有操作的状态、传入迁移的数量、完成的迁移的数量和错误的数量。我们可以在 Prometheus 侧对这些指标进行聚合,并让它计算不同的速率。

我们决定导出和监控以下指标

  • operation_requests_total
  • operation_statuses_total
  • operation_errors_total

Shuttlecloud Prometheus System

我们的大多数服务都在两个 Google Cloud Platform 可用区中进行了复制。这包括监控系统。在两个或多个不同区域中拥有多个操作导出器非常简单,因为 Prometheus 可以聚合所有区域的数据,并生成一个指标(例如,所有区域中的最大值)。我们目前没有将 Prometheus 或 Alertmanager 设为高可用性 — 只有一个元监控实例 — 但我们正在努力实现它。

对于外部黑盒监控,我们使用 Prometheus 黑盒导出器。除了检查我们的外部前端是否正常运行之外,它对于获取 SSL 证书过期日期的指标特别有用。它甚至检查证书的整个链。感谢 Robust Perception 在他们的 博文中 对此进行了完美的解释。

我们在 Grafana 中设置了一些图表,以便在一些仪表盘中进行可视监控,而与 Prometheus 的集成非常简单。用于定义图表的查询语言与 Prometheus 中的相同,这简化了它们的创建过程。

我们还将 Prometheus 与 Pagerduty 集成,并为关键警报创建了一个人员值班安排表。对于那些不被视为关键的警报,我们只发送电子邮件。

Prometheus 如何让你的工作变得更好?

我们无法将 Prometheus 与我们之前的解决方案进行比较,因为我们没有一个,但我们可以谈谈 Prometheus 的哪些功能是我们关注的重点

  • 它几乎不需要维护。
  • 它效率很高:一台机器可以处理整个集群的监控。
  • 社区很友好 — 开发人员和用户都很友好。此外,Brian 的博客 也是一个很好的资源。
  • 它没有第三方依赖关系;它只是服务器和导出器。(不需要维护 RabbitMQ 或 Redis。)
  • Go 应用程序的部署非常简单。

你认为 ShuttleCloud 和 Prometheus 的未来会怎样?

我们对 Prometheus 非常满意,但始终欢迎新的导出器(例如 Celery 或 Spark)。

我们每次添加新警报时都会遇到一个问题:我们如何测试警报按预期工作?最好有一种方法可以注入虚假指标,以便触发警报并对其进行测试。

PromCon 2016 - 圆满结束!

发生了什么

上周,来自世界各地的八十位 Prometheus 用户和开发者齐聚柏林,参加了首届关于 Prometheus 监控系统的会议:PromCon 2016。此次会议的目标是交流知识、最佳实践和使用 Prometheus 获得的经验。我们还希望扩大社区,帮助人们建立围绕服务监控的专业联系。以下是一些来自第一个上午的印象。

拉取不扩展 - 还是可以扩展?

让我们谈谈一个特别持久的误解。每当讨论监控系统时,Prometheus 的基于拉取的指标收集方法就会出现,有人不可避免地会插话,说基于拉取的方法“从根本上来说不扩展”。给出的理由往往含糊不清,或者只适用于与 Prometheus 本质上不同的系统。事实上,在最大规模下使用基于拉取的监控,这种说法与我们自己的运营经验相悖。

我们已经有关于为什么 Prometheus 选择拉取而不是推送的常见问题解答条目,但它没有特别关注扩展方面。让我们仔细看看围绕这种说法通常的误解,并分析它们是否以及如何应用于 Prometheus。

Prometheus 不是 Nagios

当人们想到一个主动拉取的监控系统时,他们往往会想到 Nagios。Nagios 的声誉不太好,部分原因是它为主动检查生成子进程,这些子进程可以在 Nagios 主机上执行任意操作以确定某个主机或服务的运行状况。这种检查架构确实扩展性不好,因为中心 Nagios 主机很快就会不堪重负。因此,人们通常将检查配置为每隔几分钟执行一次,或者他们会遇到更严重的问题。

然而,Prometheus 的方法从根本上来说完全不同。它不是执行检查脚本,而是只从网络上的一组已监控的目标收集时间序列数据。对于每个目标,Prometheus 服务器只是通过 HTTP 获取该目标所有指标的当前状态(以高度并行的方式,使用 goroutines),并且没有其他与拉取相关的执行开销。这让我们引出了下一个要点。

谁发起连接并不重要

出于扩展目的,谁发起 TCP 连接来传输指标并不重要。无论哪种方式,建立连接的努力都比指标有效负载和其他所需工作要小。

但是基于推送的方法可以使用 UDP 并完全避免建立连接,你说!没错,但 Prometheus 中的 TCP/HTTP 开销与 Prometheus 服务器执行的其他工作相比仍然可以忽略不计(尤其是将时间序列数据持久化到磁盘)。为了说明这一点,一台大型 Prometheus 服务器可以轻松存储数百万个时间序列,每秒接收 800,000 个样本(根据 SoundCloud 上实际生产指标数据测量得出)。假设 10 秒的抓取间隔和每台主机 700 个时间序列,这允许您从一台 Prometheus 服务器监控超过 10,000 台机器。这里的扩展瓶颈从来与拉取指标无关,通常与 Prometheus 服务器将数据摄取到内存以及可持续地将数据持久化和过期到磁盘/SSD 的速度有关。

此外,虽然网络现在非常可靠,但使用基于 TCP 的拉取方法可以确保指标数据可靠到达,或者至少监控系统能够立即知道何时指标传输由于网络故障而失败。

Prometheus 不是基于事件的系统

有些监控系统是基于事件的。也就是说,它们在每个事件(HTTP 请求、异常等等)发生时立即向中心监控系统报告该事件。然后,中心系统要么将事件聚合成指标(StatsD 是这种方法的主要例子),要么单独存储事件以供以后处理(ELK 堆栈就是一个例子)。在这种系统中,拉取确实会有问题:已监控服务必须在拉取之间缓冲事件,并且拉取必须非常频繁才能模拟基于推送方法的相同“活性”并且不使事件缓冲区不堪重负。

然而,同样,Prometheus 不是基于事件的监控系统。您不会向 Prometheus 发送原始事件,它也不能存储它们。Prometheus 的职责是收集聚合的时间序列数据。这意味着它只对定期收集给定指标集的当前状态感兴趣,而不是导致这些指标生成的底层事件。例如,已监控服务不会在处理每个 HTTP 请求时向 Prometheus 发送消息,而是简单地将这些请求在内存中计数。这每秒可以发生数十万次,而不会产生任何监控流量。然后,Prometheus 只需每隔 15 秒或 30 秒(或您配置的任何时间间隔)向服务实例询问当前计数器的值,并将该值与抓取时间戳一起存储为样本。其他指标类型(如 gauge、histogram 和 summary)的处理方式类似。产生的监控流量很低,在这种情况下,基于拉取的方法也不会造成问题。

但现在我的监控需要了解我的服务实例!

使用基于拉取的方法,您的监控系统需要知道哪些服务实例存在以及如何连接到它们。有些人担心这会在监控系统方面需要额外的配置,并将此视为运营扩展性问题。

我们认为,在任何情况下,您都无法逃避严肃的监控设置的这种配置工作:如果您的监控系统不知道世界应该是什么样子,以及哪些已监控服务实例应该存在,那么它如何才能知道某个实例从未报告、由于中断而宕机,或者确实不再需要存在?只有在您永远不在乎单个实例的运行状况时,这种情况才是可以接受的,就像您只运行临时工作者时一样,只要有足够多的工作者报告了一些结果就足够了。大多数环境并非完全如此。

如果监控系统无论如何都需要知道世界的期望状态,那么基于推送的方法实际上需要更多的配置。您的监控系统不仅需要知道哪些服务实例应该存在,而且您的服务实例现在也需要知道如何访问您的监控系统。拉取方法不仅需要更少的配置,而且使您的监控设置更灵活。使用拉取,您只需在笔记本电脑上运行生产监控的副本即可进行实验。它还允许您使用其他工具获取指标,或者手动检查指标端点。为了获得高可用性,拉取允许您并行运行两个配置相同的 Prometheus 服务器。最后,如果您必须移动监控可访问的端点,拉取方法不需要您重新配置所有指标源。

在实际方面,Prometheus 通过其内置的广泛服务发现机制支持(用于云提供商和容器调度系统:Consul、Marathon、Kubernetes、EC2、基于 DNS 的 SD、Azure、Zookeeper Serversets 等等)简化了对世界期望状态的配置。如果需要,Prometheus 还允许您插入自己的自定义机制。在微服务世界或任何多层架构中,如果您的监控系统使用与服务实例用来发现其后端相同的方法来发现要监控的目标,这从根本上来说也是一种优势。这样,您可以确保您监控的是与服务生产流量相同的目标,并且您只需维护一个发现机制。

意外地对您的监控进行 DDoS 攻击

无论您是拉取还是推送,任何时间序列数据库在您发送的样本数量超过其处理能力时都会崩溃。然而,根据我们的经验,基于推送的方法更容易意外地使您的监控崩溃。如果对从哪些实例中摄取哪些指标的控制权不集中(在您的监控系统中),那么您就会面临实验性或恶意作业突然将大量垃圾数据推送到您的生产监控中并使其崩溃的风险。对于基于拉取的方法(它只控制从哪里拉取指标,但不控制指标有效负载的大小和性质),仍然有许多方法可以做到这一点,但风险较低。更重要的是,此类事件可以在中心点进行缓解。

现实世界的证明

除了 Prometheus 已经被用于监控现实世界中非常大的设置(比如使用它在 DigitalOcean 监控数百万台机器)之外,还有其他突出的例子表明基于拉取的监控在最大的环境中得到成功使用。Prometheus 的灵感来自 Google 的 Borgmon,Borgmon 在 Google 内部(并且部分仍然在使用)用于监控所有关键生产服务,使用的是基于拉取的方法。我们在 Google 遇到过 Borgmon 的任何扩展性问题,都不是由于它的拉取方法造成的。如果基于拉取的方法可以扩展到拥有数十个数据中心和数百万台机器的全球环境,那么您几乎可以说拉取不能扩展。

但拉取还有其他问题!

确实有一些设置很难使用基于拉取的方法进行监控。一个突出的例子是,当您有很多端点散布在世界各地,由于防火墙或复杂的网络设置,无法直接访问,并且在每个网络段中直接运行 Prometheus 服务器是不可行的。这不是 Prometheus 的构建环境,尽管通常可以采取变通方法(通过 Pushgateway 或重新构建您的设置)。无论如何,这些关于基于拉取的监控的剩余问题通常与扩展无关,而是由于打开 TCP 连接的网络操作问题造成的。

那么一切都好吗?

本文解决了关于基于拉取的监控方法最常见的扩展性问题。由于 Prometheus 和其他基于拉取的系统已在非常大的环境中成功使用,并且拉取方面在现实中没有成为瓶颈,因此结果应该很清楚:“拉取不扩展”的说法并不是一个真正的问题。我们希望未来的辩论将重点关注比这个误导性问题更重要的方面。

Prometheus 达到 1.0 版本

在 1 月份,我们发布了一篇关于Prometheus 公开发布的第一年的博文,总结了对我们来说这是一段令人惊叹的旅程,并且对您来说可能是一个创新且实用的监控解决方案。从那以后,Prometheus 也加入了云原生计算基金会,在那里,作为继Kubernetes之后的第二个创始项目,我们与志同道合者为伍。

我们最近的工作重点是交付稳定的 API 和用户界面,这以 Prometheus 1.0 版本为标志。我们很高兴地宣布,我们已经实现了这一目标,并且Prometheus 1.0 今天已经发布.

1.0 对您意味着什么?

如果您已经使用 Prometheus 一段时间了,您可能已经注意到,在过去的一年里,重大更改的比率和影响显着降低。本着同样的精神,达到 1.0 版本意味着随后的 1.x 版本将保持 API 稳定。升级不会破坏构建在 Prometheus API 之上的程序,更新也不需要存储重新初始化或部署更改。自定义仪表板和警报在 1.x 版本更新中也将保持完整。我们相信 Prometheus 1.0 是一个可靠的监控解决方案。现在 Prometheus 服务器已经达到稳定的 API 状态,其他模块将随着时间的推移,逐步发布自己的稳定 1.0 版本。

细则

那么 API 稳定性意味着什么呢?Prometheus 有一个很大的表面积,其中一些部分肯定比其他部分更成熟。有两个简单的类别,*稳定* 和 *不稳定*

从 v1.0 开始,贯穿整个 1.x 系列保持稳定

  • 查询语言和数据模型
  • 警报和记录规则
  • 摄取暴露格式
  • 配置标志名称
  • HTTP API(由仪表板和 UI 使用)
  • 配置文件格式(减去不稳定的服务发现集成,见下文)
  • 在可预见的未来,与 Alertmanager 0.1+ 的警报集成
  • 控制台模板语法和语义

不稳定,可能会在 1.x 中更改

  • 远程存储集成(InfluxDB、OpenTSDB、Graphite)仍处于实验阶段,将在某个时候被一个通用的、更复杂的 API 替代,该 API 允许将样本存储在任意存储系统中。
  • 几个服务发现集成是新的,需要跟上快速发展的系统。因此,与 Kubernetes、Marathon、Azure 和 EC2 的集成仍处于测试版状态,可能会发生变化。但是,更改将明确公布。
  • 确切的标志含义可能会根据需要进行更改。但是,更改绝不会导致服务器无法使用以前的标志配置启动。
  • 服务器一部分的包的 Go API。
  • Web UI 生成的 HTML。
  • Prometheus 本身 `/metrics` 端点的指标。
  • 确切的磁盘格式。但是,潜在的更改将是向前兼容的,并由 Prometheus 透明地处理。

所以 Prometheus 现在已经完整了吗?

绝对不是。我们还有很长的路线图,充满了要实现的伟大功能。Prometheus 不会在未来几年一直停留在 1.x 版本中。基础设施领域正在快速发展,我们完全希望 Prometheus 与之同步发展。这意味着我们将继续愿意质疑我们过去所做的,并愿意放弃失去相关性的事物。将会有 Prometheus 的新主要版本来促进未来的计划,如持久性长期存储、Alertmanager 的新迭代、内部存储改进,以及我们甚至还不知道的许多事情。

结语

我们要感谢我们出色的社区,他们在现场测试新版本、提交错误报告、贡献代码、帮助其他社区成员,以及通过参与无数富有成效的讨论来塑造 Prometheus。最终,是你们让 Prometheus 成功。

谢谢,并继续努力!

Prometheus 将加入云原生计算基金会

自从 Prometheus 诞生以来,我们一直在为该项目寻找一个可持续的治理模式,该模式独立于任何单一公司。最近,我们一直在与新成立的 云原生计算基金会 (CNCF) 进行讨论,该基金会得到了 Google、CoreOS、Docker、Weaveworks、Mesosphere 和 其他领先的基础设施公司 的支持。

今天,我们很高兴地宣布,CNCF 的技术监督委员会 一致投票 接受 Prometheus 作为 Kubernetes 之后第二个托管项目!您可以在 CNCF 发布的官方新闻稿 中找到有关这些计划的更多信息。

通过加入 CNCF,我们希望建立一个明确且可持续的项目治理模式,并从该独立基金会为其成员提供的资源、基础设施和建议中获益。

我们认为 CNCF 和 Prometheus 是一个理想的主题匹配,因为两者都专注于实现云的现代愿景。

在接下来的几个月里,我们将与 CNCF 合作,最终确定项目治理结构。我们将在有更多细节宣布时向大家汇报。

何时(不)使用 varbit 块

Prometheus 服务器的嵌入式时间序列数据库 (TSDB) 将每个时间序列的原始样本数据组织成大小恒定为 1024 字节的块。除了原始样本数据之外,块还包含一些元数据,允许为每个块选择不同的编码。最根本的区别是编码版本。您通过命令行标志 -storage.local.chunk-encoding-version 为新创建的块选择版本。到目前为止,只有两个支持的版本:0 代表原始的增量编码,1 代表改进的双增量编码。在版本 0.18.0 中,我们添加了版本 2,它是双增量编码的另一种变体。我们称之为 *varbit 编码*,因为它涉及块中每个样本的变长位宽。虽然版本 1 在几乎所有方面都优于版本 0,但版本 1 和 2 之间存在真正的权衡。这篇博文将帮助您做出决定。版本 1 仍然是默认编码,因此如果您想在阅读本文后尝试版本 2,则必须通过命令行标志显式选择它。在版本之间切换不会造成任何损害,但请注意,现有块在其创建后不会更改其编码版本。但是,这些块将根据配置的保留时间逐渐被淘汰,因此将被使用命令行标志中指定的编码的块替换。

ShowMax 访谈

这是对 Prometheus 用户进行的一系列访谈中的第二篇,让用户分享他们评估和使用 Prometheus 的经验。

您能告诉我们您自己以及 ShowMax 是做什么的吗?

我是 Antonin Kral,我负责 ShowMax 的研究和架构。在此之前,我担任了 12 年的架构师和 CTO 角色。

ShowMax 是一家按需视频订阅服务,于 2015 年在南非推出。我们拥有广泛的内容目录,包含超过 20,000 集电视剧和电影。我们的服务目前在全球 65 个国家/地区提供。虽然更知名的竞争对手在美国和欧洲展开竞争,但 ShowMax 正在努力解决一个更困难的问题:如何在撒哈拉以南非洲的几乎没有网络连接的村庄里进行狂看?全球 35% 的视频已经通过流媒体播放,但仍有许多地方尚未触及这场革命。

ShowMax logo

我们管理着大约 50 个服务,这些服务主要运行在围绕 CoreOS 构建的私有集群上。它们主要处理来自我们客户端(Android、iOS、AppleTV、JavaScript、三星电视、LG 电视等)的 API 请求,而其中一些用于内部。最大的内部管道之一是视频编码,它在处理大型摄取批次时会占用 400 多台物理服务器。

我们大多数后端服务是用 Ruby、Go 或 Python 编写的。我们在用 Ruby 编写应用程序时使用 EventMachine(在 MRI 上使用 Goliath,在 JRuby 上使用 Puma)。Go 通常用于需要高吞吐量且没有太多业务逻辑的应用程序。我们对用 Python 编写的服务使用 Falcon 感到非常满意。数据存储在 PostgreSQL 和 ElasticSearch 集群中。我们使用 etcd 和自定义工具来配置 Varnishes 以路由请求。

Life360 访谈

这是对 Prometheus 用户进行的一系列访谈中的第一篇,让用户分享他们评估和使用 Prometheus 的经验。我们的第一次访谈是与 Life360 的 Daniel 进行的。

您能告诉我们您自己以及 Life360 是做什么的吗?

我是 Daniel Ben Yosef,也称 dby,我是 Life360 的基础设施工程师,在此之前,我担任了 9 年的系统工程师角色。

Life360 创建的技术可以帮助家庭保持联系,我们是家庭的家庭网络应用程序。我们非常忙碌地处理这些家庭——在高峰期,我们每分钟为 7000 万个注册家庭提供 70 万次请求。

我们在生产中管理着大约 20 个服务,这些服务主要处理来自移动客户端(Android、iOS 和 Windows Phone)的位置请求,在高峰期覆盖了 150 多个实例。冗余和高可用性是我们的目标,我们努力在任何时候都保持 100% 的正常运行时间,因为家庭信赖我们能够提供服务。

我们在 MySQL 多主集群和 12 节点 Cassandra 环中保存用户数据,Cassandra 环在任何给定时间都保存着大约 4TB 的数据。我们拥有用 Go、Python、PHP 编写的服务,以及将 Java 引入我们堆栈的计划。我们使用 Consul 进行服务发现,当然我们的 Prometheus 设置也与其集成在一起。

自定义 Alertmanager 模板

Alertmanager 处理由 Prometheus 服务器发送的警报,并根据警报的标签将有关警报的通知发送给不同的接收者。

接收者可以是多种不同的集成之一,例如 PagerDuty、Slack、电子邮件,或者通过通用 Webhook 接口进行自定义集成(例如 JIRA)。

模板

发送给接收者的消息通过模板构建。Alertmanager 带有默认模板,但也允许定义自定义模板。

在这篇博文中,我们将逐步了解 Slack 通知的一个简单定制示例。

我们使用这个简单的 Alertmanager 配置,将所有警报发送到 Slack

global:
  slack_api_url: '<slack_webhook_url>'

route:
  receiver: 'slack-notifications'
  # All alerts in a notification have the same value for these labels.
  group_by: [alertname, datacenter, app]

receivers:
- name: 'slack-notifications'
  slack_configs:
  - channel: '#alerts'

默认情况下,Alertmanager 发送的 Slack 消息如下所示

它向我们展示了一个正在触发的警报,后面跟着警报分组的标签值(alertname、datacenter、app),以及警报共有的其他标签值(critical)。

Prometheus 开源开发一周年

开始

一年前的今天,我们正式向全世界宣布了 Prometheus。这是一个很好的机会,让我们回顾一下,分享自那以后发生在这个项目的一些美妙的事情。但首先,让我们从头开始。

尽管我们在 2012 年就已经在 GitHub 上将 Prometheus 作为开源项目启动,但我们一开始并没有大肆宣传。我们希望给项目一些时间来成熟,并在没有摩擦的情况下进行实验。Prometheus 在 2013 年逐渐被引入到 SoundCloud 的生产监控中,然后在公司内部得到了越来越多的使用,并在 2014 年被我们 Docker 和 Boxever 的朋友们早期采用。多年来,Prometheus 越来越成熟,虽然它已经解决了人们的监控问题,但它仍然为公众所知。

使用 etcd 进行自定义服务发现

在之前的文章中,我们介绍了在 Prometheus 中进行服务发现的多种新方法。从那时起,发生了很多事情。我们改进了内部实现,并从社区获得了宝贵的贡献,增加了对 Kubernetes 和 Marathon 的服务发现支持。它们将在 0.16 版本发布时提供。

我们还谈到了自定义服务发现 的主题。

并非每种服务发现都通用到可以被直接包含在 Prometheus 中。很有可能你的组织已经有了专有的系统,你只需要让它与 Prometheus 协同工作。这并不意味着你不能享受自动发现新的监控目标的益处。

在这篇文章中,我们将实现一个小实用程序,它将基于 etcd(高度一致的分布式键值存储)的自定义服务发现方法连接到 Prometheus。

监控 DreamHack - 世界上最大的数字节日

编者注:这篇文章是由 Prometheus 用户撰写的客座文章。

如果你为数万名苛刻的游戏玩家运营着网络,你需要真正了解你的网络内部发生了什么。哦,所有的一切都需要在仅仅五天内从头开始构建。

如果你以前从未听说过 DreamHack,这里给你介绍一下:聚集 20,000 人,其中大部分人自带电脑。再加上职业游戏(电子竞技)、编程比赛和现场音乐会。结果是世界上最大的专门致力于一切数字化的节日。

为了使这样的活动成为可能,需要大量的基础设施。这种规模的普通基础设施需要几个月的时间才能建立,但 DreamHack 的团队在短短五天内就从头开始构建了一切。当然,这包括配置网络交换机之类的东西,也包括构建电力分配系统,为食品和饮料设置商店,甚至建造实际的桌子。

负责构建和运营与网络相关的一切的团队正式名称为网络团队,但我们通常称自己为techdhtech。这篇文章将重点介绍 dhtech 的工作以及我们在 2015 年 DreamHack Summer 中如何使用 Prometheus 来尝试将我们的监控提升到一个新的高度。

实用的异常检测

在 John Allspaw 的致监控/指标/报警公司的公开信中,他断言尝试“完美地、在正确的时间检测异常是不可能的”。

我见过许多才华横溢的工程师试图构建系统,根据时间序列数据自动检测和诊断问题。虽然让演示正常工作当然是可能的,但数据总是太嘈杂,无法让这种方法适用于除了最简单的现实世界系统之外的任何东西。

不过,并非所有希望都破灭了。你可以使用自定义构建的规则检测和处理许多常见的异常。Prometheus 的 查询语言 为你提供了发现这些异常并避免误报的工具。

Prometheus 0.14.0 中的高级服务发现

本周我们发布了 Prometheus v0.14.0 - 一个包含许多期待已久的新增功能和改进的版本。

在用户方面,Prometheus 现在支持新的服务发现机制。除了 DNS-SRV 记录之外,它现在还支持 Consul,并且基于文件的接口允许你连接自己的发现机制。随着时间的推移,我们计划将其他常见的服务发现机制添加到 Prometheus 中。

除了许多较小的修复和改进之外,你现在还可以通过向 Prometheus 进程发送 SIGHUP 来在运行时重新加载你的配置。有关更改的完整列表,请查看此版本的变更日志

在这篇博文中,我们将更仔细地研究内置的服务发现机制,并提供一些实际示例。作为额外的资源,请参阅 Prometheus 的配置文档

Prometheus 监控在互联网上普及

自从我们公开宣布 Prometheus 0.10.0 版本以来,已经快三个月了,我们现在已经到了 0.13.1 版本。

SoundCloud 的公告博文仍然是 Prometheus 关键组件的最佳概述,但围绕 Prometheus 的其他在线活动也很多。这篇文章将让你了解你错过的任何东西。

将来,我们将使用此博客发布更多文章和公告,帮助你充分利用 Prometheus。