YACE 加入 Prometheus 社区

Yet Another Cloudwatch Exporter (YACE) 已正式加入 Prometheus 社区!此举将使其更易于用户使用,并为贡献者提供增强和维护项目的新机会。您也可以阅读Cristian Greco 的观点撰写的博文。

早期时光

当我第一次启动 YACE 时,我完全没想到它会发展到如此规模。当时,我正在 Invision AG(与设计应用无关)工作,这是一家专注于劳动力管理软件的公司。他们完全支持我开源该工具,在我队友 Kai Forsthövel 的帮助下,YACE 诞生了。

我们的第一次提交是在 2018 年,我们的主要目标之一是使 CloudWatch 指标易于扩展并自动检测要衡量的内容,同时保持用户体验简单直观。InVision AG 由于机器学习工作负载会上下扩展其基础设施,我们需要一种能轻松检测新基础设施的工具。这种对简单性的关注一直是核心优先事项。从那时起,YACE 开始找到其受众。

Yace 势头正盛

随着 YACE 的扩展,对其的支持也随之增加。一个关键时刻是 Grafana Labs 的Cristian Greco主动联系我。我当时感到力不从心,几乎无法跟上进度,这时 Cristian 介入,只是简单地问他能提供什么帮助。他很快成为主要的发布者,并领导了 Grafana Labs 对 YACE 的贡献,这是一个对项目产生巨大影响的转折点。与来自世界各地的众多令人难以置信的贡献者一起,他们将 YACE 提升到了我独自无法达到的高度,将其塑造成一个真正的全球性工具。YACE 不再只是我的项目或 Invision 的项目——它属于社区。

感激与未来愿景

我非常感谢为 YACE 成功做出贡献的每一位开发者、测试人员和用户。这段旅程向我展示了社区和开源协作的力量。但我们还没有结束。

是时候让 Yace 更进一步——进入 Prometheus 生态系统的核心了。将 Yace 打造成 Prometheus 的官方 Amazon CloudWatch 导出器,将使其对每个人来说更简单、更易于访问。有了 Grafana Labs 的持续支持以及我致力于优化用户体验的承诺,我们将确保 YACE 成为一个任何人都可以轻松使用的直观工具。

亲自试用 YACE

按照我们的分步安装指南,亲自试用 YACE (Yet Another CloudWatch Exporter)

您可以在此处查看各种配置示例,开始监控特定的 AWS 服务。

我们的目标是实现所有 AWS 服务的轻松自动发现,从而简化对任何动态基础设施的监控。

宣布 Prometheus 3.0 发布

继最近在柏林 PromCon 大会上发布Prometheus 3.0 beta之后,Prometheus 团队很高兴宣布 Prometheus 3.0 版本现已正式可用!

这个最新版本标志着一个重要的里程碑,因为它是 7 年来的首个主要版本。Prometheus 在此期间取得了长足的进步,从一个早期采用者的项目发展成为云原生监控堆栈的标准组成部分。Prometheus 3.0 旨在通过添加一些令人兴奋的新功能来延续这一旅程,同时在很大程度上保持与先前版本的稳定性和兼容性。

完整的 3.0 版本在测试版的基础上增加了一些新功能,还引入了一些额外的重大变更,我们将在本文中进行描述。

新特性

以下是作为测试版一部分发布的令人兴奋的变更摘要,以及之后添加的内容:

新的 UI

Prometheus 3.0 的亮点之一是其全新的 UI,该 UI 默认启用

New UI query page

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

Julius 在 PromLabs 博客上发表的详细文章中了解更多关于新 UI 的信息。用户可以使用 old-ui 功能标志临时启用旧 UI。

由于新的 UI 尚未经过实战检验,因此很可能仍然存在错误。如果您发现任何错误,请在 GitHub 上报告

自测试版发布以来,用户界面已更新以支持 UTF-8 指标和标签名称。

New UTF-8 UI

Remote Write 2.0

Remote-Write 2.0 在先前协议版本的基础上进行了迭代,增加了对许多新元素的本地支持,包括元数据、示例、创建时间戳和原生直方图。它还使用字符串驻留来减少压缩和解压时的负载大小和 CPU 使用。对部分写入的处理也得到了改进,以便在此发生时向客户端提供更多详细信息。更多详细信息可以在此处找到。

UTF-8 支持

Prometheus 现在默认允许在指标和标签名称中使用所有有效的 UTF-8 字符,标签值也与 2.x 版本一样支持 UTF-8。

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

目前只有 Go 客户端库更新以支持 UTF-8,但对其他语言的支持将很快添加。

OTLP 支持

为了与我们对 OpenTelemetry 的承诺保持一致,Prometheus 3.0 提供了几个新功能,以改善与 OpenTelemetry 的互操作性。

OTLP 摄取

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

请参阅我们的指南,了解将 OTLP 指标流量导入 Prometheus 的最佳实践。

UTF-8 标准化

借助于 Prometheus 3.0 的UTF-8 支持,用户可以在 Prometheus 中存储和查询 OpenTelemetry 指标,而无需像将点更改为下划线那样对指标和标签名称进行令人烦恼的更改。

值得注意的是,这减少了用户和工具在 OpenTelemetry 语义约定或 SDK 中定义的内容与实际可查询内容之间的差异所造成的困惑

为了在 OTLP 摄取方面实现这一点,Prometheus 3.0 提供了对不同翻译策略的实验性支持。有关详细信息,请参阅Prometheus 配置中的 otlp 部分

注意:虽然“NoUTF8EscapingWithSuffixes”策略允许使用特殊字符,但为了获得最佳体验,它仍然会添加必要的后缀。有关在 Prometheus 中启用无后缀的未来工作提案,请参阅此链接。

原生直方图

原生直方图是 Prometheus 的一种指标类型,与传统直方图相比,它具有更高的效率和更低的成本。原生直方图无需根据数据集选择(并可能需要更新)桶边界,而是根据指数增长具有预设的桶边界。

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

重大变更

Prometheus 社区致力于在主要版本发布时不破坏现有功能。借此新的主要版本发布之际,我们利用这个机会清理了一些长期存在但规模不大的问题。换句话说,Prometheus 3.0 包含一些重大变更。这包括对功能标志、配置文件、PromQL 和抓取协议的更改。

请阅读迁移指南,以了解您的设置是否受到影响以及应采取的措施。

性能

自从 Prometheus 2.0 发布以来,社区取得的成就令人印象深刻。我们都喜欢数字,所以让我们一起庆祝我们在 TSDB 模式下对 CPU 和内存使用效率进行的改进。下面您可以看到在具有 8 个 CPU 和 49 GB 可分配内存的节点上,3 个 Prometheus 版本之间的性能数据。

  • 2.0.0(7 年前)
  • 2.18.0(4 年前)
  • 3.0.0(现在)

Memory bytes

CPU seconds

更令人印象深刻的是,这些数据是使用我们的 prombench 宏基准测试获得的,该测试使用了相同的 PromQL 查询、配置和环境——这突出了即使是 3.0 版本,核心功能也保持了向后兼容性和稳定性。

下一步

在 Prometheus 和生态系统中,我们还有大量令人兴奋的功能和改进可以进行。以下是一个非穷举列表,希望能让您感到兴奋……并希望激励您做出贡献并加入我们!

  • 新的、更具包容性的治理
  • 更多 OpenTelemetry 兼容性和功能
  • OpenMetrics 2.0,现由 Prometheus 治理!
  • 原生直方图稳定性(以及自定义桶!)
  • 更多优化!
  • 更多 SDK 和工具中的 UTF-8 支持覆盖

试一试!

您可以通过下载我们的官方二进制文件容器镜像来试用 Prometheus 3.0。

如果您正在从 Prometheus 2.x 升级,请查阅迁移指南,了解您需要进行的任何调整的更多信息。请注意,我们强烈建议在升级到 v3.0 之前先升级到 v2.55。可以从 v3.0 回滚到 v2.55,但不能回滚到更早的版本。

一如既往,我们欢迎社区的反馈和贡献!

Prometheus 3.0 测试版发布

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

总体而言,唯一的重大变更是删除了已弃用的功能标志。Prometheus 团队努力工作以确保向后兼容性,并且不破坏现有安装,因此下面描述的所有新功能都基于现有功能构建。大多数用户应该无需进行任何配置更改即可直接试用 Prometheus 3.0。

新特性

自 Prometheus 2.0 发布以来的 7 年里,共有超过 7500 次提交,有太多新的独立功能和修复无法一一列出,但有一些重要的、引人注目的和重大变更我们想特别指出。我们需要社区中的每个人都试用它们并报告您可能发现的任何问题。我们获得的反馈越多,最终的 3.0 版本就会越稳定。

新的 UI

Prometheus 3.0 的亮点之一是其全新的 UI,该 UI 默认启用

New UI query page

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

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

Remote Write 2.0

Remote-Write 2.0 在先前协议版本的基础上进行了迭代,增加了对许多新元素的本地支持,包括元数据、示例、创建时间戳和原生直方图。它还使用字符串驻留来减少压缩和解压时的负载大小和 CPU 使用。更多详细信息可以在此处找到。

OpenTelemetry 支持

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

UTF-8

默认情况下,Prometheus 将允许在指标和标签名称中使用所有有效的 UTF-8 字符,标签值也与 2.x 版本一样支持 UTF-8。

用户需要确保其指标生产者配置为传递 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

范围选择现在是左开右闭,这将避免在操作中意外包含比预期更多点的情况。

Agent 模式现在已稳定,并有其自己的配置标志而不是功能标志

我们对 OpenTelemetry 的承诺

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

回顾 2023

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

自那时以来,我们花费了大量时间来理解 OpenTelemetry 用户在将指标存储在 Prometheus 中时面临的挑战,并在此基础上探讨了如何解决这些挑战。提出的一些变更需要仔细考虑,以避免破坏任何一方的运行承诺,例如同时支持 push 和 pull。在 2023 年柏林 PromCon 大会上,我们试图在一次演讲中总结我们的想法。

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

我们已经组建了一个核心开发者团队来领导这项倡议,我们将在 2024 年发布 Prometheus 3.0,其中 OTel 支持是其更重要的功能之一。以下是 2024 年即将推出的一些功能预览。

未来一年

OTLP 摄取 GA

在 2023 年 9 月 6 日发布的Prometheus v2.47.0中,我们为 Prometheus 添加了 OTLP 摄取的实验性支持。我们正在不断改进此功能,并计划添加对陈旧性的支持并使其成为稳定功能。我们还将把对乱序摄取的支持标记为稳定。这还包括正式发布(GA)对原生/指数直方图的支持。

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

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

这导致了不必要的差异,我们正在通过为所有标签和指标名称添加 UTF-8 支持来消除这一限制。进展情况可以在此处跟踪。

原生支持资源属性

OpenTelemetry 区分指标属性(用于识别指标本身的标签,例如 http.status_code)和资源属性(用于识别指标来源的标签,例如 k8s.pod.name),而 Prometheus 具有更扁平的标签 schema。这导致了许多可用性问题,详细信息可以在此处找到。

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

生态系统中的 OTLP 导出

Prometheus remote write 已经得到了大多数领先的可观测性项目和供应商的支持。然而,OpenTelemetry Protocol (OTLP) 正在获得普及,我们希望在整个 Prometheus 生态系统中支持它。

我们希望将其支持添加到 Prometheus 服务器、SDK 和导出器中。这意味着使用 Prometheus SDK 进行 instrument 的任何服务也将能够推送 OTLP,这将为 OpenTelemetry 用户解锁丰富的 Prometheus 导出器生态系统。

然而,我们打算保留并开发 OpenMetrics 暴露格式,作为 Prometheus 和基于 pull 的用例的优化/简化格式。

Delta temporality

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

我们希望在 Prometheus 服务器中支持 OpenTelemetry 的 Delta temporality,并正在为此努力

呼吁贡献!

如您所见,许多令人兴奋的新事物即将来到 Prometheus!如果您对在可观测性领域两个最相关的开源项目交集处工作感到具有挑战性和趣味性,我们欢迎您加入!

今年治理结构也在进行改革,这将使成为维护者的过程比以往任何时候都更容易!如果您曾经想对 Prometheus 产生影响,现在是开始的最佳时机。

我们的首要关注点始终是在组织上述所有工作时尽可能保持开放和透明,以便您也能做出贡献。我们正在寻找贡献者来支持这项倡议并帮助实现这些功能。请查阅Prometheus 3.0 公开看板Prometheus OTel 支持里程碑,以跟踪功能开发的进度,并了解您如何贡献

结论

提出的一些变更规模较大且具有侵入性,或者涉及与 Prometheus 原始数据模型的根本性背离。然而,我们计划优雅地引入这些变更,以便 Prometheus 3.0 不会带来重大的重大变更,并且大多数用户可以在不受影响的情况下进行升级。

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

PromCon Europe 2023 日程已发布

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

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

PromCon 现已进入第八届,它汇聚了来自世界各地的 Prometheus 用户和开发者,交流通过使用 Prometheus 获得的知识、最佳实践和经验。项目委员会审查了 66 份投稿,这些投稿将对当前围绕 Prometheus 的最紧迫主题提供新的、有价值的视角。

“我们对 PromCon 回到柏林感到非常兴奋。Prometheus 于 2012 年在 Soundcloud 的柏林启动。第一届 PromCon 在柏林举办,期间移至慕尼黑。今年,我们将在柏林 Friedrichshain 的 Radialsystem 迎接约 300 名与会者。柏林拥有充满活力的 Prometheus 社区,许多 Prometheus 团队成员就住在附近。这是一个与热爱系统和服务监控的 Prometheus 大家庭建立联系的绝佳机会,”Polar Signals 的高级软件工程师、Prometheus 团队成员、今年 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 - The Linux Foundation - [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 镜像。

stringlabels 优化不包含在这些默认二进制文件中。要使用此优化,用户需要专门下载 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 Operator)的语义版本控制检查。

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

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

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

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

Introducing Prometheus Agent Mode,一种高效且云原生的指标转发方式

Bartłomiej Płotka 自 2019 年以来一直是 Prometheus 维护者,也是 Red Hat 的首席软件工程师。CNCF Thanos 项目的合著者。CNCF 大使和 CNCF TAG Observability 的技术负责人。业余时间,他与 O'Reilly 合作撰写了一本名为《Efficient Go》的书。观点为我个人所有!

我个人喜欢 Prometheus 项目的一点,也是我加入团队的众多原因之一,就是它对项目目标的专注。Prometheus 始终致力于在提供实用、可靠、廉价但极具价值的基于指标的监控方面突破界限。Prometheus 超级稳定且强大的 API、查询语言和集成协议(例如 Remote Write 和 OpenMetrics)使得云原生计算基金会 (CNCF) 指标生态系统能够在这些坚实的基础上发展。结果发生了许多令人惊叹的事情:

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

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

Prometheus 社区的强大专注力也使得其他开源项目得以发展,将 Prometheus 部署模型扩展到单个节点之外(例如 CortexThanos 等)。更不用说云供应商采用了 Prometheus 的 API 和数据模型(例如 Amazon Managed PrometheusGoogle Cloud Managed PrometheusGrafana Cloud 等)。如果您正在寻找 Prometheus 项目如此成功的唯一原因,那就是这个:将监控社区的精力集中在重要的事情上

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

转发用例的历史

Prometheus 的核心设计在整个项目生命周期内保持不变。受到Google 的 Borgmon 监控系统的启发,您可以将 Prometheus 服务器与要监控的应用程序一起部署,告诉 Prometheus 如何访问它们,并允许以固定间隔抓取其指标的当前值。这种收集方法通常被称为“pull 模型”,是使 Prometheus 轻量且可靠的核心原则。此外,它使得应用程序的 instrument 和导出器变得异常简单,因为它们只需要提供一个简单的人类可读的 HTTP 端点,其中包含所有跟踪指标的当前值(以 OpenMetrics 格式)。所有这些都无需复杂的 push 基础设施和非简单的客户端库。总体而言,典型的 Prometheus 监控简化部署如下所示:

Prometheus high-level view

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

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

Yoda

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

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

天真地想,我们可以通过将 Prometheus 放在全局级别并跨远程网络抓取指标,或者直接从应用程序将指标推送到中心位置进行监控来实现这一点。让我解释一下为什么这两种做法通常都非常糟糕:

🔥 跨网络边界抓取指标可能带来挑战,因为它在监控流水线中增加了新的未知因素。本地 pull 模型允许 Prometheus 知道指标目标出现问题的确切原因和时间。也许它已宕机、配置错误、重启、太慢无法提供指标(例如 CPU 饱和)、无法通过服务发现发现、我们没有访问凭据,或者只是 DNS、网络或整个集群已宕机。通过将抓取器放在网络外部,我们可能会因为引入与单个目标无关的抓取不可靠性而丢失部分信息。最重要的是,如果网络暂时中断,我们可能会完全失去重要的可见性。请不要这样做。这不值得。(

🔥 直接从应用程序将指标推送到某个中心位置同样糟糕。特别是当您监控大量实例时,如果看不到来自远程应用程序的指标,您几乎一无所知。应用程序宕机了吗?我的接收端流水线宕机了吗?也许应用程序授权失败了?也许它未能获取到我的远程集群的 IP 地址?也许它太慢了?也许网络中断了?更糟的是,您甚至可能不知道某些应用程序目标的数据丢失了。而且您也没有获得太多收益,因为您需要跟踪所有应该发送数据的目标的状态。这种设计需要仔细分析,因为它太容易导致失败了。

注意:无服务器函数和短生命周期容器通常是我们需要考虑从应用程序推送指标作为解决方案的情况。然而,在这一点上,我们讨论的是事件或指标片段,我们可能希望将其聚合到更长时间的序列中。这个问题在此处进行了讨论,欢迎您贡献并帮助我们更好地支持这些情况!

Prometheus 引入了三种支持全局视图的方式,每种方式都有其优缺点。让我们简要介绍一下。它们在下图中使用橙色表示:

Prometheus global view

  • Federation 作为第一个用于聚合的功能被引入。它允许全局级别的 Prometheus 服务器从叶节点 Prometheus 抓取一部分指标。这种“联合”抓取减少了跨网络的一些未知因素,因为联合端点暴露的指标包含原始样本的时间戳。然而,它通常存在无法联合所有指标以及在较长时间网络分区(分钟)期间丢失数据的缺点。
  • Prometheus Remote Read 允许从远程 Prometheus 服务器的数据库中选择原始指标,而无需直接的 PromQL 查询。您可以在全局级别部署 Prometheus 或其他解决方案(例如 Thanos),对这些数据执行 PromQL 查询,同时从多个远程位置获取所需的指标。这非常强大,因为它允许您“本地”存储数据,并在需要时才访问它。不幸的是,也有缺点。如果没有像Query Pushdown这样的功能,在极端情况下,为了回答单个查询,我们会拉取 GB 级的压缩指标数据。此外,如果发生网络分区,我们会暂时“失明”。最后但同样重要的是,某些安全指南不允许入口流量,只允许出口流量。
  • 最后,我们有Prometheus Remote Write,它似乎是目前最流行的选择。由于 Agent 模式专注于远程写入用例,让我们更详细地解释一下。

Remote Write

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

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

Prometheus 项目还提供了其 API 的官方一致性测试,例如针对提供 Remote Write 客户端功能的解决方案的remote-write sender compliance。这是一种快速判断您是否正确实现此协议的绝佳方式。

从这样的抓取器流式传输数据,通过将指标数据存储在中心位置,实现了全局视图的用例。这还实现了关注点的分离,当应用程序由不同于可观测性或监控流水线的团队管理时,这非常有用。此外,这也是供应商选择 Remote Write 的原因,他们希望尽可能地减轻客户的工作负担。

等一下,Bartek。你刚才提到直接从应用程序推送指标不是最好的主意!

当然,但令人惊叹的部分在于,即使使用 Remote Write,Prometheus 仍然使用 pull 模型从应用程序收集指标,这使我们能够理解那些不同的故障模式。之后,我们将样本和时间序列批量处理并导出,复制(推送)数据到 Remote Write 端点,从而限制了中心点需要处理的监控未知因素的数量!

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

Remote Write 实操示例:Katacoda 教程

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

如果您想亲身体验远程写入功能,我们推荐Thanos Katacoda 的从 Prometheus 远程写入指标教程,该教程解释了 Prometheus 将所有指标转发到远程位置所需的所有步骤。它是免费的,只需注册一个帐户即可享受教程!🤗

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

那么如果远程写入运行良好,为什么我们还要在 Prometheus 中添加一个特殊的 Agent 模式呢?

Prometheus Agent 模式

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

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

Prometheus agent

Prometheus Agent 最好的地方在于它内置在 Prometheus 中。具有相同的抓取 API、相同的语义、相同的配置和发现机制。

如果您不打算在本地查询或告警数据,而是将指标流式传输到外部,使用 Agent 模式有什么好处?有以下几点:

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

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

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

其次,新 Agent 模式的好处在于它能够更容易地实现摄取的水平扩展性。这是我最兴奋的一点。让我解释一下原因。

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

一个真正的可自动扩展的抓取解决方案需要基于指标目标的数量和它们暴露的指标数量。需要抓取的数据越多,我们自动部署的 Prometheus 实例就越多。如果目标的数量或其指标数量减少,我们可以缩减并移除一些实例。这将消除手动调整 Prometheus 大小的负担,并避免在集群暂时很小时过度分配 Prometheus 的需求。

仅使用服务器模式的 Prometheus 很难实现这一点。这是因为服务器模式下的 Prometheus 是有状态的。收集到的数据会原封不动地保存在一个位置。这意味着缩减程序需要在终止之前将收集到的数据备份到现有实例。然后我们将面临抓取重叠、误导性陈旧标记等问题。

此外,我们需要一些全局视图查询,能够聚合所有实例的样本(例如 Thanos Query 或 Promxy)。最后但同样重要的是,服务器模式下 Prometheus 的资源使用不仅取决于摄取。还有告警、记录、查询、压缩、远程写入等,这些可能需要更多或更少资源,且独立于指标目标的数量。

Agent 模式本质上将发现、抓取和远程写入功能移至单独的微服务。这使得操作模型专注于摄取。因此,Agent 模式下的 Prometheus 或多或少是无状态的。是的,为了避免指标丢失,我们需要部署一对高可用 Agent,并为其附加持久化磁盘。但从技术上讲,如果我们有数千个指标目标(例如容器),我们可以部署多个 Prometheus Agent,并安全地更改哪个副本抓取哪些目标。这是因为,最终所有样本都将被推送到同一个中心存储。

总而言之,Agent 模式下的 Prometheus 实现了 Prometheus 基于抓取的易于水平自动扩展能力,可以响应指标目标的动态变化。这绝对是我们未来将与 Prometheus Kubernetes Operator 社区共同探讨的内容。

现在让我们看看 Prometheus 中 Agent 模式当前实现的状况。它准备好使用了吗?

Agent 模式已在大规模应用中得到验证

Prometheus 的下一个版本将包含 Agent 模式作为实验性功能。标志、API 和磁盘上的 WAL 格式可能会改变。但由于Grafana Labs 的开源工作,该实现的性能已经久经考验。

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

捐赠过程非常顺利。由于一些 Prometheus 维护者之前在 Grafana Agent 中也为此代码做出了贡献,并且新的 WAL 受 Prometheus 自己的 WAL 启发,因此当前的 Prometheus TSDB 维护者很容易就接管了完整的维护工作!此外,Robert 加入 Prometheus 团队成为 TSDB 维护者也大有裨益(恭喜!)。

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

如何详细使用 Agent 模式

从现在开始,如果您查看 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.

正如之前提到的,由于 Agent 模式位于功能标志后面,请使用 --enable-feature=agent 标志在 Agent 模式下运行 Prometheus。现在,其余的标志要么适用于服务器和 Agent 模式,要么只适用于特定模式。您可以通过检查标志帮助字符串的最后一句来查看哪个标志适用于哪种模式。“Use with server mode only”表示它仅适用于服务器模式。如果您没有看到类似的说明,则表示该标志是共享的。

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

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

Prometheus Agent 实操示例:Katacoda 教程

类似于 Prometheus 远程写入教程,如果您想亲身体验 Prometheus Agent 的能力,我们推荐Thanos Katacoda 的 Prometheus Agent 教程,该教程解释了运行 Prometheus Agent 是多么容易。

总结

希望您觉得这很有趣!在本文中,我们探讨了出现的新用例,例如:

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

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

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

这篇博文是 CNCF、Grafana 和 Prometheus 协同发布的一部分。您还可以阅读CNCF 的公告以及关于作为 Prometheus Agent 基础的 Grafana Agent 的不同视角。

Prometheus 一致性计划:第一轮结果

今天,我们启动了Prometheus 一致性计划,旨在确保 Prometheus 监控领域不同项目和供应商之间的互操作性。虽然法律文件仍在最终确定中,但我们已经进行了测试,并将以下内容视为我们的第一轮结果。作为此次启动的一部分,Julius Volz 更新了他的 PromQL 测试结果

快速提醒:该计划称为 Prometheus 一致性 (Conformance),软件可以针对特定测试做到兼容 (compliant),从而获得兼容性 (compatibility) 评级。术语可能看起来很复杂,但这使我们能够轻松地讨论这个主题。

前言

新类别

我们发现很难理清什么应该应用于什么软件。为了帮助整理思绪,我们创建了一份概述,引入了四种新的软件类别:

  • 指标暴露器
  • Agent/收集器
  • Prometheus 存储后端
  • 完全 Prometheus 兼容性

行动呼吁

非常欢迎反馈。也许与直觉相反,我们希望由社区而非仅仅是 Prometheus 团队来塑造这项工作。为此,我们将在 Prometheus 内部成立一个 WG Conformance 工作组。就像 WG DocsWG Storage 一样,这些工作组将是公开的,我们积极邀请参与。

正如我们最近提到的,Prometheus 的维护者/采用者比例出人意料地低,甚至令人震惊。换句话说,我们希望围绕 Prometheus 兼容性的经济激励将吸引供应商投入资源与我们一起构建测试。如果您一直想在工作时间为 Prometheus 做贡献,这可能是一个途径;并且这个途径将使您接触到 Prometheus 许多高度相关的方面。有多种方式可以与我们联系

注册接受测试

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

测试结果

完全 Prometheus 兼容性

我们知道要构建哪些测试,但目前尚未完成。如先前宣布的,以此来评判项目或供应商是不公平的。因此,测试填充程序被定义为通过。目前例如 Julius 本周运行的 PromQL 测试 的半手动性质意味着 Julius 在大多数情况下通过 Prometheus Remote Write 发送数据作为 PromQL 测试的一部分。我们在此以多种方式重复使用了他的结果。这种情况很快就会理顺,来自不同角度的更多测试将不断提高要求,从而增强最终用户的信心。

将项目和 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 Managed Service for Prometheus
  • Google Cloud Managed Service for Prometheus
  • New Relic
  • Sysdig Monitor

注:由于 Amazon Managed Service for Prometheus 与 Grafana Cloud 一样基于 Cortex,我们预计它们将在下一个更新周期后通过测试。

Agent/收集器

通过

  • Grafana Agent 0.19.0
  • OpenTelemetry Collector 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 一致性计划:Remote Write 兼容性测试结果

正如 CNCF 宣布的以及我们自己宣布的,我们正在启动一个 Prometheus 一致性计划。

为了在正式运行测试之前让大家了解生态系统的现状,我们想展示一下我们快乐的小测试套件家族的最新成员:Prometheus Remote Write 兼容性测试套件根据我们的规范测试 Remote Write 协议的发送方部分。

在周一的PromCon大会上,Prometheus 维护者 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 项目在 CNCF 的帮助下推出了 Prometheus 合规性计划,以认证组件的合规性和 Prometheus 的兼容性。

CNCF 指导委员会预计将在下次会议上正式审查和批准该计划。我们邀请更广泛的社区在此加速阶段帮助改进我们的测试。

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

发布时,我们提供针对三个组件的合规性测试

  • PromQL(需要手动解释,部分完成)
  • 远程读写(完全自动化,进行中)
  • OpenMetrics(部分自动化,部分完成,将需要问卷)

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

Prometheus 合规性计划工作流程如下

对于每个组件,都会有一个标记,例如"foo YYYY-MM compliant",例如"OpenMetrics 2021-05 compliant"、"PromQL 2021-05 compliant"和"Prometheus Remote Write 2021-05 compliant"。任何项目或供应商都可以提交其合规性文档。达到 100% 后,将授予该标记。

对于任何完整的软件,都会有一个标记,例如"Prometheus x.y compatible",例如"Prometheus 2.26 compatible"。相关的组件合规性得分将被相乘。达到 100% 后,将授予该标记。

例如,Prometheus Agent 同时支持 OpenMetrics 和 Prometheus Remote Write,但不支持 PromQL。因此,只有 OpenMetrics 和 Prometheus Remote Write 的合规性得分会被相乘。

合规和兼容标记均在 2 个次要版本或 12 周(以较长者为准)内有效。

介绍 '@' 修饰符

你是否曾经为某个指标选择前 10 个时间序列,结果却得到 100 个?如果是,那么这篇文章就是为你准备的。让我为你讲解潜在的问题以及我是如何修复它的。

目前,topk() 查询只有作为即时查询(instant query)时才有意义,它可以精确地返回 k 个结果,但当你将其作为范围查询(range query)运行时,由于每个步骤都独立评估,你可能会得到远多于 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_total 中,那些在过去 1h 内速率排在前 5 的时间序列的 1m 速率。因此,现在即使作为范围查询,你也可以理解 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 的重大破坏性变更,它将保持禁用状态直到下一个主要版本。

请在每个版本发布时关注此列表,并务必尝试它们!

Remote Read 遇见 Streaming

新的 Prometheus 2.13.0 版本已经发布,一如既往,它包含了许多修复和改进。你可以在此处阅读变更内容。然而,有一个特性是某些项目和用户一直在期待的:分块、流式的 remote read API 版本

在本文中,我将深入探讨我们在远程协议中做了哪些更改、为什么要更改以及如何有效使用它。

Remote APIs

自 1.x 版本以来,Prometheus 就具有使用 remote API 直接与其存储交互的能力。

该 API 允许第三方系统通过两种方式与指标数据交互

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

Remote read and write architecture

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

Remote Write

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

Remote write 最近在三月通过基于 WAL 的 remote write 得到了大幅改进,提高了可靠性和资源消耗。值得注意的是,此处提到的几乎所有第三方集成都支持 remote write。

Remote Read

读取方法不太常见。它于 2017 年 3 月(服务器端)添加,自那时以来没有重大发展。

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

remote read 的核心思想是允许直接查询 Prometheus 存储(TSDB)而无需进行 PromQL 评估。它类似于 PromQL 引擎用于从存储中检索数据的 Querier 接口。

这实质上允许读取 Prometheus 收集的 TSDB 中的时间序列。remote read 的主要用例是

remote read 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;
}

Remote read 返回匹配的时间序列,包含值和时间戳的原始样本。

问题陈述

对于如此简单的 remote read,存在两个关键问题。它易于使用和理解,但对于我们定义的 protobuf 格式,在单个 HTTP 请求中没有流式传输能力。其次,响应包含原始样本(float64 值和 int64 时间戳),而不是用于在 TSDB 中存储指标的编码、压缩的样本批次,称为“块”(chunks)。

没有流式传输的 remote read 的服务器算法是

  1. 解析请求。
  2. 从 TSDB 中选择指标。
  3. 对于所有解码的时间序列
    • 对于所有样本
      • 添加到响应 protobuf 中
  4. 序列化响应。
  5. 使用 snappy 压缩。
  6. 发送 HTTP 响应。

整个 remote read 的响应必须以原始的、未压缩的格式进行缓冲,以便在发送给客户端之前将其序列化为可能巨大的 protobuf 消息。然后客户端必须再次完全缓冲整个响应,才能从接收到的 protobuf 中反序列化。只有在那之后,客户端才能使用原始样本。

这是什么意思?这意味着,例如,仅请求匹配 10,000 个时间序列的 8 小时数据,客户端和服务器都需要分配高达 2.5GB 的内存!

下面是 Prometheus 和 Thanos Sidecar(remote read 客户端)在进行 remote read 请求时的内存使用指标

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

值得注意的是,查询 10,000 个时间序列不是一个好主意,即使对于 Prometheus 原生的 HTTP query_range 端点也是如此,因为你的浏览器简单地无法高兴地获取、存储和渲染数百兆字节的数据。此外,对于仪表盘和渲染目的来说,拥有如此大量的数据是不切实际的,因为人类无法阅读它。这就是为什么我们通常会精心编写查询,使其返回不超过 20 个时间序列。

这很棒,但一个非常常见的技术是这样组合查询:查询返回聚合后的 20 个时间序列,然而在底层,查询引擎必须触及可能数千个时间序列来评估响应(例如在使用聚合操作符时)。这就是为什么像 Thanos 这样的系统(它除了其他数据外,还使用来自 remote read 的 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 的方式是从文件系统中存储的块中逐个最优地获取时间序列,从而最大限度地减少分配。

这对 remote read API 很重要,因为我们可以通过将单个时间序列的一块响应以少量块的形式发送给客户端,来重用使用迭代器的流式传输模式。由于 protobuf 没有原生的分隔逻辑,我们扩展了 proto 定义,允许发送一组小的协议缓冲区消息,而不是单个巨大的消息。我们将这种模式称为 STREAMED_XOR_CHUNKS remote read,而旧模式称为 SAMPLES。扩展协议意味着 Prometheus 不再需要缓冲整个响应。相反,它可以按顺序处理每个时间序列,并在每次 SeriesSet.Next 或一批 SeriesIterator.Next 迭代时发送一个帧,潜在地为下一个时间序列重用相同的内存页!

现在,STREAMED_XOR_CHUNKS remote read 的响应是一组 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];
}

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

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

  1. 解析请求。
  2. 从 TSDB 中选择指标。
  3. 对于所有时间序列
    • 对于所有样本
      • 编码成块
        • 如果帧 >= 1MB,则中断
    • 序列化 ChunkedReadResponse 消息。
    • 使用 snappy 压缩
    • 发送消息

你可以在此处找到完整的设计文档。

性能基准

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

让我们比较 Prometheus 2.12.02.13.0 之间的 remote read 特性。正如本文开头所示的初步结果,我使用 Prometheus 作为服务器,Thanos sidecar 作为 remote read 客户端。我通过使用 grpcurl 对 Thanos sidecar 运行 gRPC 调用来触发测试 remote read 请求。测试是在我的笔记本电脑(Lenovo X1 16GB,i7 8th)上进行的,使用 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 内存,而不是分配数 GB 内存,而 Thanos 只使用了微不足道的内存。由于流式的 Thanos gRPC StoreAPI,sidecar 现在是一个非常简单的代理。

此外,我尝试了不同的时间范围和时间序列数量,但正如预期的那样,Prometheus 的分配内存最大保持在 50MB,而 Thanos 则几乎没有可见的内存使用。这证明我们的 remote read 无论你请求多少样本,每个请求使用的内存都是恒定的。每个请求分配的内存也比以前受到数据基数(即获取的时间序列数量)的影响大大减少。

这有助于更容易地根据用户流量进行容量规划,并辅以并发限制。

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 倍。

延迟

由于流式传输和减少编码,我们也成功降低了 remote read 请求的延迟。

请求 8 小时范围和 10,000 个时间序列的 remote read 延迟

2.12.0: 平均时间 2.13.0: 平均时间
real 0m34.701s 0m8.164s
user 0m7.324s 0m8.181s
sys 0m1.172s 0m0.749s

以及 2 小时时间范围

2.12.0: 平均时间 2.13.0: 平均时间
real 0m10.904s 0m4.145s
user 0m6.236s 0m4.322s
sys 0m0.973s 0m0.536s

除了延迟降低约 2.5 倍之外,响应可以立即流式传输,而相比之下,非流式传输版本中,仅在 Prometheus 和 Thanos 端处理和序列化就导致客户端延迟为 27 秒(real 减去 user 时间)。

兼容性

远程读功能得到了扩展,这是一种向后和向前兼容的方式。这得益于 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 大小和固定大小的大端 uint32 格式,用于 CRC32 Castagnoli 校验和。

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

请注意,storage.remote.read-sample-limit 标志对于 STREAMED_XOR_CHUNKS 不再起作用。storage.remote.read-concurrent-limit 标志像以前一样工作。

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

如前所述,Thanos 从这项改进中获益良多。流式远程读功能已在 v0.7.0 中添加,因此,此版本或其后的任何版本,只要使用 Prometheus 2.13.0 或更新版本配合 Thanos sidecar,将自动使用流式远程读功能。

后续步骤

2.13.0 版本引入了扩展的远程读功能和 Prometheus 服务端实现,然而,截至撰写本文时,仍有少数事项需要完成以充分利用扩展的远程读协议。

  • 支持 Prometheus 远程读的客户端实现:进行中
  • 避免在远程读期间对块的 chunk 进行重新编码:进行中

总结

总之,分块、流式远程读的主要好处是

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

和往常一样,如果您有任何问题或反馈,欢迎在 GitHub 上提交 issue 或在邮件列表中提问。

ForgeRock 访谈

继续我们的 Prometheus 用户访谈系列,ForgeRock 的 Ludovic Poitou 讲述了他们的监控历程。

您能介绍一下您自己和 ForgeRock 的业务吗?

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

在 使用 Prometheus 之前的监控经验是怎样的?

ForgeRock Identity Platform 一直提供监控接口。但该平台由 4 个主要产品组成,每个产品都有不同的选项。例如,Directory Services 产品通过 SNMP、JMX 或 LDAP 提供监控信息,甚至在最新版本中还提供了基于 HTTP 的 RESTful API。其他产品只有 REST 或 JMX 接口。因此,监控整个平台非常复杂,并且需要能够集成这些协议的工具。

为什么决定考虑使用 Prometheus?

我们需要拥有一个用于监控我们所有产品的单一通用接口,同时保留现有接口以实现向后兼容。

我们开始使用 DropWizard 在所有产品中收集指标。同时,我们开始将这些产品迁移到云端,并在 Docker 和 Kubernetes 中运行它们。因此,Prometheus 成为了显而易见的选择,因为它与 Kubernetes 的集成、部署简单以及与 Grafana 的集成。我们也考察了 Graphite,虽然我们也在产品中添加了对其的支持,但我们的客户几乎不使用它。

你们是如何过渡的?

我们的一些产品已经在使用 DropWizard 库,并且我们决定在所有产品中使用一个通用库,因此 DropWizard 是编写检测代码的自然选择。但很快,我们遇到了数据模型的问题。Prometheus 接口使用维度(dimensions),而我们倾向于使用分层(hierarchical)模型来表示指标。我们也开始使用 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 的必要性降低了,因为可以安装常规工具。

替代 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。大部分情况下,我们通过 textfile collector 暴露自定义的业务相关指标。

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

新的设置将我们的时间分辨率从 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。至关重要的是,当主 Prometheus 节点宕机时,Grafana 能够查询备份节点。这很简单——在前面放置 HAProxy 并在本地接受连接。

另一个问题是:如何防止用户(开发者及其他内部员工)滥用仪表盘导致 Prometheus 节点过载。

或者在主节点宕机时,备份节点过载——(惊群问题)

为了达到期望的状态,我们尝试了 Trickster。这极大地加快了仪表盘加载速度。它缓存时间序列数据。在我们的场景中,缓存驻留在内存中,但还有其他存储选项。即使当主节点宕机并且你刷新仪表盘时,Trickster 不会向第二个节点查询它已经在内存中缓存的时间序列数据。Trickster 位于 Grafana 和 Prometheus 之间。它只与 Prometheus API 通信。

Hostinger Graphing Architecture

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

我们计划运行大量的 blackbox_exporter 并监控 Hostinger 的每一个客户网站,因为无法监控的东西就无法评估。

我们期待未来部署更多的 Prometheus 节点,将节点分片到多个 Prometheus 实例之间。这使得如果每个区域有一个实例宕机,我们也不会产生瓶颈。

子查询支持

简介

正如标题所示,子查询是查询的一部分,并允许您在查询中执行范围查询,这是以前不可能实现的。这是一个长期以来的功能请求:prometheus/prometheus/1227

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

动机

有时会遇到这样的情况:您希望使用较低分辨率/范围(例如 5m)的 rate 来发现问题,同时对这些数据进行更高范围(例如 1hmax_over_time)的聚合。

以前,对于单个 PromQL 查询,上述操作是不可能实现的。如果您想对查询进行范围选择,用于告警规则或绘图,这将需要您基于该查询创建一个记录规则,并对记录规则创建的指标执行范围选择。示例:max_over_time(rate(my_counter_total[5m])[1h])

当您希望快速获得跨越数天或数周的数据结果时,可能需要等待相当长的时间,直到您的记录规则中有了足够的数据才能使用。忘记添加记录规则可能会令人沮丧。为查询的每个步骤创建记录规则也会很繁琐。

有了子查询支持,所有等待和沮丧都得到了解决。

子查询

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

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

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

如果未指定 resolution,全局评估间隔将被用作子查询的默认 resolution。此外,子查询的 step 是独立对齐的,并且不依赖于父查询的评估时间。

示例

min_over_time 函数内部的子查询返回 http_requests_total 指标在过去 30 分钟内以 1 分钟 resolution 计算的 5 分钟 rate。这等同于一次 /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>-30mend=<now>,以 1m 的 resolution。请注意,start 时间是独立于 1m 的步长对齐的(对齐的步长是 0m 1m 2m 3m ...)。
  • 最后,上述所有评估的结果被传递给 min_over_time()

下面是一个嵌套子查询的示例,以及默认 resolution 的用法。最内层子查询获取 distance_covered_meters_total 在一个时间范围内的 rate。我们利用它来获取 rate 的 deriv(),同样在一个时间范围内。最后取所有导数中的最大值。请注意,最内层子查询的 <now> 时间是相对于外层子查询对 deriv() 的评估时间。

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

在大多数情况下,您需要使用默认评估间隔,这是规则默认被评估的间隔。自定义 resolution 会有所帮助,在您希望计算频率较低/较高的情况下,例如您可能希望计算频率较低的昂贵查询。

结语

虽然子查询替代记录规则使用起来非常方便,但不必要地使用它们会影响性能。复杂的子查询最终应该转换为记录规则以提高效率。

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

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 会议上,与 Soundcloud 的工程师团队交流后,开始考虑使用 Prometheus 的。他们阐述的优点足以说服我们尝试使用 Prometheus。

你们是如何过渡的?

我们仍处于过渡过程中,因此我们并行运行两个系统——Prometheus 和 Graphite-collectd 组合。对于客户端仪表盘和我们的核心服务,我们使用 Prometheus,然而,对于客户网站,我们仍然使用 Graphite-collectd。在这两个系统之上,使用 Grafana 进行可视化。

Presslab's Redis Grafana dashboards

Prometheus 文档、Github issue 和源代码是我们集成 Prometheus 的首选资源;当然,StackOverflow 也为这个过程增添了一些调味品,解决了我们很多疑问。

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

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

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

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

我们对 Prometheus 抱有很大的计划,目前正在努力用 Prometheus Operator 替换我们新的基础设施上使用的 Prometheus Helm chart。这项实现将提供平台客户的隔离,因为我们将为有限数量的网站分配一个专用的 Prometheus 服务器。作为我们将 WordPress Kubernetize 化的一部分,我们已经在进行这项工作。

我们还在努力以 Prometheus 格式导出 WordPress 指标。Grafana 将继续存在,因为它与 Prometheus 密切配合,以解决可视化需求。

Prometheus 在 CNCF 中毕业

我们很高兴地宣布,自今天起,Prometheus 在 CNCF 中正式毕业。

Prometheus 是有史以来第二个达到此层级的项目。通过让 Prometheus 毕业,CNCF 表明其对我们的代码和功能速度、成熟度和稳定性以及治理和社区流程充满信心。这对于任何内部讨论选择监控工具的人来说,也是一种外部质量验证。

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

  • 我们完全重写了存储后端,以支持服务中的高流失率
  • 我们大力推动稳定性,尤其是在 2.3.2 版本
  • 我们开始大力推动文档工作,特别注重让 Prometheus 的采用和加入社区变得更容易

尤其是最后一点很重要,因为我们目前进入了第四个采用阶段。这些阶段包括由以下用户采用:

  1. 积极寻找最佳监控解决方案的以监控为中心的用户
  2. 面临监控系统无法跟上其规模的超大规模用户
  3. 从小型到财富 500 强公司正在重做其监控基础设施
  4. 缺乏资金和/或资源专注于监控,但从各种渠道听说 Prometheus 益处的用户

展望未来,我们预计采用范围将进一步扩大,并始终致力于今天应对明天的规模。

实现自定义服务发现

实现自定义服务发现

Prometheus 内置了许多服务发现 (SD) 系统的集成,例如 Consul、Kubernetes 以及 Azure 等公共云提供商。然而,我们无法为市面上的每一种服务发现选项提供集成实现。Prometheus 团队在支持当前集成集方面已经人手紧张,因此维护针对所有可能的 SD 选项的集成是不可行的。在许多情况下,当前的 SD 实现是由团队外部人员贡献的,然后没有得到很好的维护或测试。我们承诺只直接集成我们知道可以维护且能按预期工作的服务发现机制。因此,目前暂停接受新的 SD 集成。

然而,我们知道仍然有集成其他 SD 机制(例如 Docker Swarm)的需求。最近,为了在不将其合并到主 Prometheus 二进制文件中的情况下实现自定义服务发现集成,一些代码更改和一个示例已提交到 Prometheus 仓库中的文档目录。这些代码更改允许我们利用内部的 Discovery Manager 代码来编写另一个可执行文件,该文件与新的 SD 机制交互并输出一个与 Prometheus 的 file_sd 兼容的文件。通过将 Prometheus 和我们的新可执行文件并置,我们可以配置 Prometheus 读取我们可执行文件的 file_sd 兼容输出,从而从该服务发现机制抓取目标。未来,这将使我们能够将 SD 集成移出主 Prometheus 二进制文件,并将使用适配器的稳定 SD 集成移到 Prometheus 的发现包中。

使用 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 结构体转换为 JSON,以便用于 file_sd 格式。

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

自定义 SD 实现

现在我们想实际使用适配器来实现我们自己的自定义 SD。一个完整的可用示例位于同一示例目录此处

在这里你可以看到我们正在导入适配器代码 "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)。这是适配器代码中的管理器将在 goroutine 中调用的函数。Run 函数使用 context 来知道何时退出,并通过通道传递其目标组更新。

查看提供的示例中的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 获取了关于每个目标的响应,我们将所有这些目标发送到通道。还有一个 helper 函数 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,我们将查询 localhost:8500 的 Consul HTTP API,并且 file_sd 兼容文件将被写入 custom_sd.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 上更快地编写代码。我们的项目包括用于 Kubernetes 服务本地开发的 Telepresence;基于 Envoy Proxy 构建的 Kubernetes 原生 API 网关 Ambassador;以及构建/部署系统 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 的统计数据。我们还基于另一位 Ambassador 贡献者的工作设置了一个 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 的一个优点是支持由项目本身或社区实现的 exporter。

使用 KairosDB,我们经常难以构建自己的 exporter。与 Prometheus 相比,已经存在 KairosDB exporter 的几率相当低。

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

使用 Prometheus,你可以很快地启动并运行(系统相当容易安装),并且为你的平台找到现有的 exporter 的几率相当高。

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

对应用程序性能的可见性至关重要,而 Prometheus 的高可伸缩性是实现这一目标所必需的。

为什么决定考虑使用 Prometheus?

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

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

一旦我们看到人们在生产环境中成功地将 Prometheus 与容器优先的架构一起使用,并且看到对 exporter 和面板的支持,很明显我们应该将 Prometheus 作为我们的分析后端进行调查。

One of Scalefastr's Grafana dashboards

你们是如何过渡的?

对我们来说,过渡相当顺利,因为 Scalefastr 是一个全新的环境(greenfield environment)。

架构大部分是新的,限制因素很少。

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

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

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

然后我们部署 Prometheus、客户配置所需的所有 exporter,以及 Grafana 的面板。

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

为了帮助解决这个问题,我们本周宣布了一个项目,旨在为 Cassandra、Elasticsearch、OS 以及 Prometheus 本身等工具标准化和改进 Prometheus 面板。我们将其开源并于上周发布到 Github

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

我们还想改进与 Grafana 后端自动同步,并上传这些面板到 Grafana.com。

我们还发布了我们的 Prometheus 配置,以便标签与我们的 Grafana 模板正确配合工作。这使得你可以通过下拉菜单选择更具体的指标,例如集群名称、实例名称等。

Using template variables in Grafana dashboards

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

易于部署、高性能和标准化的 exporter 使我们很容易切换。此外,后端配置相当简单(基本上只有守护程序本身),并且没有太多活动部件,这使得这是一个容易的决定。

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

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

在此之前,我们需要让 Prometheus 服务发现工作起来,这是我们尚未尝试过的。目前我们通过 Ansible 部署和配置 Prometheus,但这显然无法扩展(甚至无法工作),因为容器会随着我们的工作负载变化而出现和消失。

我们还在努力改进标准面板和报警功能。我们希望添加的一个功能(也许作为一个容器)是基于 holts winters 预测的报警支持。

这本质上可以让我们在严重性能问题发生之前进行预测。而不是等到出现故障(例如磁盘空间不足)后才采取行动进行纠正。

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

我们对 Prometheus 的未来感到非常兴奋,尤其现在我们正在推进 2.x 系列,并且 CNCF 合作似乎进展顺利。

Prometheus 在 CloudNativeCon 2017

Prometheus 在 CloudNativeCon 2017

12月6日星期三是 CloudNativeCon Austin 的 Prometheus 日,我们为您准备了精彩的演讲和活动阵容。您可以前往 Prometheus 沙龙获取关于如何最佳监控 Kubernetes 的实践建议,参加一系列关于 Prometheus 各个方面的演讲,然后在 CNCF 展位与一些 Prometheus 开发者交流,所有活动结束后是 Prometheus 欢乐时光。请继续阅读以了解更多详情...

宣布 Prometheus 2.0

宣布 Prometheus 2.0

大约一年半以前,我们发布了 Prometheus 1.0 版本。该版本标志着项目的一个重要里程碑。我们已经达到了一系列广泛的功能,构成了 Prometheus 简单而极其强大的监控理念。

自那时以来,我们添加并改进了各种服务发现集成,扩展了 PromQL,并尝试了远程 API 的初步迭代,以支持可插拔的长期存储解决方案。

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

PromCon 2017 回顾

发生了什么

两周前,来自世界各地的 Prometheus 用户和开发者齐聚慕尼黑参加PromCon 2017,这是关于 Prometheus 监控系统的第二次会议。这次活动旨在围绕 Prometheus 监控进行知识交流、分享最佳实践并建立专业联系。谷歌的慕尼黑办公室今年为我们提供了更大的场地,这使我们的参会人数从 80 人增加到 220 人,并且仍然售罄!

观看回顾视频了解活动印象

带有新规则格式的 Prometheus 2.0 Alpha.3

今天我们发布 Prometheus 2.0 的第三个 Alpha 版本。除了新存储层中的各种错误修复外,它还包含一些计划中的破坏性更改。

Flag 更改

首先,我们迁移到了新的 flag 库,该库使用更常见的双破折号 -- 前缀作为 flag,而不是 Prometheus 之前使用的单破折号。部署需要相应地进行调整。此外,此 Alpha 版本中删除了一些 flag。自 Prometheus 1.0.0 以来的完整列表如下:

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

记录规则更改

报警和记录规则是 Prometheus 的关键功能之一。但它们也存在一些设计问题和缺失的功能,即:

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

  • 所有规则并发评估,这实际上是 Prometheus 最老的开放 bug。这带来了一些问题,最明显的问题是如果你有很多规则,每次评估间隔负载都会飙升。另一个问题是相互依赖的规则可能会被提供过时的数据。例如:

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。

为了解决上述问题,很久以前就有人提议进行规则分组,但直到最近才作为 Prometheus 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 版本来帮助我们迈向 Prometheus 2.0 的稳定版本!你可以在我们的issue tracker上报告错误,并通过我们的社区渠道提供一般反馈。

L’Atelier Animation 访谈

继续我们的 Prometheus 用户系列访谈,L’Atelier Animation 的 Philippe Panaite 和 Barthelemy Stevens 谈论了他们如何将其动画工作室从混合使用 Nagios、Graphite 和 InfluxDB 切换到 Prometheus。

您能介绍一下您自己和 L’Atelier Animation 是做什么的吗?

L’Atelier Animation 是一家位于加拿大美丽城市蒙特利尔的 3D 动画工作室。我们的第一部故事长片《芭蕾奇缘》(也称为《Leap》)于 2017 年全球上映,预计今年晚些时候在美国上映。

我们目前正在努力制作一部动画电视剧和我们的第二部故事长片。我们的基础设施包括大约 300 台渲染刀片、150 台工作站和二十台各种服务器。除了一对 Mac 外,所有设备都运行在 Linux (CentOS) 上,没有一台 Windows 机器。

 

在 使用 Prometheus 之前的监控经验是怎样的?

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

为什么决定考虑使用 Prometheus?

当我们把所有服务切换到 CentOS 7 时,我们寻找新的监控解决方案,Prometheus 因为许多原因而出现,但最重要的是:

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

你们是如何过渡的?

我们完成第一部电影后,有一段时间的停工期,这为我们的 IT 部门提供了做出重大改变的绝佳机会。我们决定彻底更换我们的整个监控系统,因为它不如我们期望的好。

最重要的部分之一是监控网络设备,所以我们首先配置了 snmp_exporter 来从我们的一个交换机获取数据。exporter 对 NetSNMP 的调用在 CentOS 下是不同的,所以我们不得不重新编译一些二进制文件,我们在过程中确实遇到了一些小问题,但在 Robust Perception 的 Brian Brazil 的帮助下,我们很快解决了所有问题。一旦 snmp_exporter 工作起来,我们就能轻松添加新设备并获取 SNMP 数据。我们现在在 Grafana 中监控我们的核心网络(包括 13 个交换机,10 个 VLAN)。

Switch metrics from SNMP data

之后,我们配置了 node_exporter,因为我们需要对工作站、渲染刀片和服务器进行分析。在我们的领域,当 CPU 没有达到 100% 时,这就是一个问题,我们希望尽可能地利用所有算力,所以最终温度更加关键。此外,我们需要尽可能长的正常运行时间,所以我们所有工作站都通过 Prometheus 的 Alertmanager 设置了电子邮件报警,以便在任何设备宕机时我们都能知道。

Dashboard for one workstation

我们的特殊需求要求我们监控客户端的自定义数据,这通过使用 node_exporter 的 textfile collector 功能变得很容易。一个 cronjob 将来自任何给定工具的特定数据输出到一个预先格式化的文本文件中,格式可被 Prometheus 读取。

由于所有数据都通过 HTTP 协议可用,我们编写了一个 Python 脚本从 Prometheus 获取数据。我们将其存储在 MySQL 数据库中,通过一个创建实时楼层地图的 Web 应用程序访问。这使得我们可以通过简单的鼠标悬停知道哪个用户坐在哪里,使用什么类型的硬件。我们还创建了另一页,包含用户照片和部门信息,这有助于新员工了解他们的邻居是谁。该网站仍在开发中,所以请不要评价其外观,我们毕竟是系统管理员,不是 Web 设计师 :-)

Floormap with workstation detail

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

这给了我们改变工作室所有监控方式的机会,并启发我们创建一个新的自定义楼层地图,其中包含最初由 Prometheus 获取的所有数据。设置变得简单得多,一个服务就能管理一切。

您认为 L’Atelier Animation 和 Prometheus 的未来会怎样?

我们目前正在将软件许可证使用情况与 Prometheus 集成。这些信息将帮助艺术家们清楚了解谁在使用什么以及在哪里使用。

我们将继续根据用户需求定制和添加新内容,由于我们与艺术家合作,我们知道会有很多 :-) 使用 SNMP 和 node_exporter 的自定义文本文件输入,可能性是无限的...

iAdvize 访谈

继续我们的 Prometheus 用户系列访谈,iAdvize 的 Laurent COMMARIEU 谈论了他们如何用 Prometheus 替换旧有的 Nagios 和 Centreon 监控系统。

您能介绍一下 iAdvize 是做什么的吗?

我是 Laurent COMMARIEU,iAdvize 的一名系统工程师。我在 60 人的研发部门工作,团队有 5 名系统工程师。我们的主要工作是确保应用程序、服务和底层系统的正常运行。我们与开发者合作,确保他们的代码能最顺畅地投入生产环境,并在每个阶段提供必要的反馈。这就是监控的重要性所在。

iAdvize 是一个全栈对话商务平台。我们为品牌提供了一种便捷的方式,让他们能够集中地与客户互动,无论通过何种沟通渠道(聊天、通话、视频、Facebook 主页、Facebook Messenger、Twitter、Instagram、WhatsApp、SMS 等)。我们的客户遍布电商、银行、旅游、时尚等行业,在 40 个国家开展业务。我们是一家拥有 200 名员工的国际公司,在法国、英国、德国、西班牙和意大利设有办事处。我们在 2015 年融资 1600 万美元。

在 使用 Prometheus 之前的监控经验是怎样的?

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

iAdvize 过去将监控委托给外部提供商。他们使用 Nagios 和 Centreon 提供 24/7 监控。这套工具对于旧的静态架构(裸机服务器,无虚拟机,无容器)运行良好。为了补充这个监控栈,我们还使用了 Pingdom

随着我们将单体应用程序转向微服务架构(使用 Docker)以及我们将当前工作负载迁移到基础设施云提供商的愿望,我们需要在监控方面拥有更多的控制权和灵活性。与此同时,iAdvize 招聘了 3 个人,基础设施团队从 2 人增加到 5 人。使用旧系统,向 Centreon 添加一些新指标至少需要几天或一周的时间,并且成本高昂(时间和金钱)。

为什么决定考虑使用 Prometheus?

我们知道 Nagios 之类的工具不是一个好的选择。Prometheus 当时是冉冉升起的新星,我们决定进行概念验证。最初也考虑了 Sensu,但 Prometheus 似乎更适合我们的用例。

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

从纸面上看,它很不错。

One of iAdvize's Grafana dashboards

你们是如何过渡的?

首先,我们必须说服开发者团队(40 人)Prometheus 是这项工作的正确工具,并且他们必须为他们的应用程序添加一个 exporter。所以我们做了一个关于 RabbitMQ 的小演示,我们安装了一个 RabbitMQ exporter,并构建了一个简单的 Grafana 面板来向开发者展示使用情况指标。编写了一个 Python 脚本来创建一些队列并发布/消费消息。

他们对队列和消息实时出现印象深刻。在此之前,开发者无法访问任何监控数据。Centreon 受限于我们的基础设施提供商。今天,Grafana 对 iAdvize 的每个人都可用,使用 Google Auth 集成进行身份验证。上面有 78 个活跃账户(从开发团队到 CEO)。

在我们开始使用 Consul 和 cAdvisor 监控现有服务后,我们监控了容器的实际存在情况。过去使用 Pingdom 检查来监控,但这不够。

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

很快,我们就用 Prometheus 替换了所有旧的监控系统。

One of iAdvize's Grafana dashboards

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

业务指标变得非常受欢迎,销售期间每个人都连接到 Grafana,看看我们是否会打破记录。我们监控并发对话数、路由错误、在线客服数、加载 iAdvize 标签的访客数、我们 API 网关上的调用次数等。

我们花了一个月的时间,基于 Newrelic exporterPercona 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 版本,以启动新存储的稳定化进程。

现已提供发行版 tarballDocker 容器。如果你对新存储的机制感兴趣,请务必阅读深入探讨的博客文章,了解其内部原理。

此版本无法处理旧的存储数据,不应替换现有的生产部署。要运行它,数据目录必须为空,并且除了 -storage.local.retention 之外的所有现有存储 flag 都必须移除。

例如;之前

./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

这是一个非常早期的版本,应预料到崩溃、数据损坏和一般性 bug。请将它们提交到我们的issue tracker,帮助我们迈向稳定版本。

此 Alpha 版本中禁用了实验性远程存储 API。抓取暴露时间戳的目标(例如联合的 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 环境和消息工具的集成而提出的小型拉取请求也很快被合并。随着时间的推移,我们在栈中添加了几个 exporter 和 Grafana。我们从未回头或寻找替代方案。

Grafana dashboard for Docker Registry

你们是如何过渡的?

我们的团队在新项目中引入了 Prometheus,所以我们团队没有发生过渡。其他团队开始时将 Prometheus 与现有解决方案并行添加,然后逐步迁移指标收集器。自定义 exporter 和其他临时服务在迁移过程中提供了帮助。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 meetup 上做了一次关于我们经验的演讲,并发布了一系列博客文章

我们尝试了几乎所有不同的运行 Prometheus 的选项。我们开始时构建自己的容器镜像,嵌入配置,并将它们全部一起运行在单个 Pod 中,与 Grafana 和 Alert Manager 并列。我们使用临时的 Pod 内存储来存储时间序列数据。然后我们将其分解到不同的 Pod 中,这样我们就不用在每次更改面板时重启 Prometheus(并丢失历史记录)了。最近,我们已经转向使用上游镜像并将配置存储在 Kubernetes ConfigMap 中——ConfigMap 会在我们更改它时由 CI 系统更新。我们在 Prometheus Pod 中使用了一个小型 sidecar 容器来监视配置文件并在文件更改时 ping Prometheus。这意味着我们不需要经常重启 Prometheus,可以不用为存储做任何复杂的事情,也不会丢失历史记录。

然而,周期性丢失 Prometheus 历史记录的问题一直困扰着我们,而可用的解决方案(如 Kubernetes volume 或定期 S3 备份)都有其缺点。再加上我们使用 Prometheus 监控 Scope 服务的绝佳经验,这促使我们构建一个云原生、分布式的 Prometheus 版本——一个可以在不丢失历史记录的情况下进行升级、重新调度和在主机故障中幸存的版本。这就是 Weave Cortex 的诞生方式。

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

暂时撇开 Cortex 不谈,我们特别高兴地看到 HA Alert Manager 的引入;尽管主要是因为它成为了第一个使用 Weave Mesh(我们的 gossip 和协调层)的非 Weaveworks 项目。

我还特别喜欢 Fabian 对 2.0 Kubernetes SD 所做的更改——这解决了我们在监控 Consul Pod 时遇到的一个棘手问题,我们需要抓取同一 Pod 上的多个端口。

此外,如果我不提及远程写入功能(我自己参与开发的功能)就太失职了。有了这个功能,Prometheus 本身就成为了 Weave Cortex 的一个关键组成部分,负责抓取目标并将样本发送给我们。

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

对我来说,眼前的未来是 Weave Cortex,它是 Weaveworks 的 Prometheus 即服务。我们在内部大量使用它,并且已经取得了相当不错的查询性能。它目前正在生产环境中与真实用户一起运行,很快我们将引入报警支持,并实现与上游 Prometheus 的功能对等。之后我们将进入 beta 稳定化阶段,然后在年中全面上市。

作为 Cortex 的一部分,我们开发了一个智能的 Prometheus 表达式浏览器,支持 PromQL 自动补全和类似 Jupyter 的笔记本。我们期待着将它展示给更多人,并最终将其开源。

我还有一个小型副项目叫做 Loki,它将 Prometheus 服务发现和抓取功能引入 OpenTracing,并使分布式追踪变得简单而可靠。我将在三月底的 KubeCon/CNCFCon Berlin 上发表关于此主题的演讲

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.io 网站文档是最有用的资源。

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

我们遇到的一些挑战是:没有下采样支持,没有长期存储解决方案(目前还没有),我们对默认的 2 周保留期感到惊讶。目前与 Juju 没有关联,但我们正在努力

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

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

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

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

JustWatch 访谈

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

您能介绍一下您自己和 JustWatch 是做什么的吗?

对于消费者而言,JustWatch 是一个流媒体搜索引擎,帮助用户查找在哪里合法在线观看电影和电视剧,以及影院放映信息。您可以在 17 个国家/地区搜索所有主要流媒体提供商(如 Netflix、HBO、Amazon Video、iTunes、Google Play 等)的电影内容。

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

JustWatch logo

自 2014 年推出以来,我们在没有花费一美元用于营销的情况下,从零成长为国际排名前 2 万的网站之一,并在不到两年的时间里成为全球最大的流媒体搜索引擎。目前,我们的工程团队只有 10 人,我们构建并运营一个完全容器化的堆栈,包含大约 50 个微服务和宏服务,主要运行在 Kubernetes 上。

在 使用 Prometheus 之前的监控经验是怎样的?

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

为什么决定考虑使用 Prometheus?

在 JustWatch,Prometheus 的公开宣布正逢其时。公司成立的头几个月,我们主要使用黑盒监控——CloudWatch 负责一些最重要的内部指标,并结合 Pingdom 等外部服务来检测全站故障。此外,没有任何传统的基于主机的解决方案令我们满意。在一个容器和微服务的世界里,Icinga、Thruk 或 Zabbix 等基于主机的工具感觉过时了,无法胜任这项工作。当我们开始调查白盒监控时,我们中的一些人幸运地参加了 Julius 和 Björn 宣布 Prometheus 的 Golang Meetup。我们很快搭建了一个 Prometheus 服务器,并开始为我们的 Go 服务(我们的后端几乎只使用 Go)进行仪表化。这真是太容易了——它的设计感觉上是第一性原理就是面向云和服务,从未成为障碍。

你们是如何过渡的?

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

过渡到 Prometheus 主要涉及在我们的应用程序中包含 Go 客户端,并暴露 /metrics。我们还编写和部署了几个 exporter,包括 node_exporter 和几个用于云提供商 API 的 exporter。根据我们的经验,监控和报警是一个永远不会完成的项目,但大部分工作在几周内作为副项目完成。

自部署 Prometheus 以来,每当我们遗漏了什么或设计新服务时,我们都会查看指标。

花了一些时间才完全理解 PromQL 和标签概念的精妙之处,但努力确实得到了回报。

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

Prometheus 通过使白盒监控和基于标签的金丝雀部署变得异常容易而启发了我们。许多 Golang 方面的开箱即用指标(HTTP Handler、Go Runtime)帮助我们很快获得了投资回报——仅 goroutine 指标就多次拯救了我们。我们之前唯一真正喜欢的监控组件——Grafana——感觉与 Prometheus 是天作之合,并使我们能够创建一些非常有用的面板。我们赞赏 Prometheus 没有试图重新发明轮子,而是与最佳解决方案完美契合。另一个相对于前辈的巨大改进是 Prometheus 对“把数学弄对”(百分位数等)的关注。在其他系统中,我们从来都不确定提供的操作是否有意义。特别是百分位数是推理微服务性能的一种如此自然和必要的方式,以至于它们得到一流待遇让人感觉很棒。

Database Dashboard

集成的服务发现使得管理抓取目标变得超级容易。对于 Kubernetes,一切都是开箱即用的。对于尚未运行在 Kubernetes 上的其他系统,我们使用基于 Consul 的方法。要使应用程序被 Prometheus 监控,只需添加客户端,暴露 /metrics,并在 Container/Pod 上设置一个简单的 annotation。这种低耦合大大减少了开发和运维之间的摩擦——许多服务从一开始就精心编排,因为这既简单又有趣。

时间序列和巧妙功能的结合使得报警功能异常强大。在服务器端运行的聚合,并将时间序列、它们的组合以及对这些组合的函数作为一流公民对待,使得报警变得轻而易举——通常是事后才发现如此简单。

您认为 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 cookbook 来安装 Prometheus。

在主机上启动 Prometheus 后,我们编写了一个小型 Ruby 脚本,它使用 Chef API 查询所有主机,并生成一个 Prometheus 目标配置文件。我们将此文件与 file_sd_config 一起使用,以确保所有主机在注册 Chef 后立即被发现和抓取。得益于 Prometheus 的开放生态系统,我们能够通过简单的配置直接使用 Telegraf,从而导出主机级别的指标。

我们正在测试单个 Prometheus 的扩展能力,并等着它崩溃。结果它没有!事实上,它以极少的资源消耗处理了新基础设施中大约 450 台主机每 15 秒抓取一次主机级别指标的负载。

每台主机上都有很多容器,所以我们曾预计在添加所有容器的内存使用指标后,就需要开始对 Prometheus 进行分片,但 Prometheus 却毫不费力地持续运行,资源利用率也未接近饱和。目前,我们使用一台带 1TB 存储的 m4.xlarge Prometheus 实例,每 15 秒监控大约 40,000 个容器(分布在 450 台主机上)的超过 400,000 个不同的指标。您可以在下方看到该主机的仪表盘。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 主机上,并且已经考虑了几种实现方法。

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

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

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

最终,我们需要对 Prometheus 进行分片。由于多种原因,我们已经将客户部署分散到许多较小的集群中,因此一个合理的选择是每个集群迁移到一个较小的 Prometheus 服务器(或一对用于冗余),而不是一个单一的全局服务器。

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

DigitalOcean 访谈

作为我们与 Prometheus 用户访谈系列的下一篇,DigitalOcean 谈论了他们如何使用 Prometheus。Carlos Amedee 还在 2016 年 PromCon 大会上谈到了推广的社会方面

您能介绍一下您自己以及 DigitalOcean 是做什么的吗?

我叫 Ian Hansen,在平台指标团队工作。DigitalOcean 提供简单的云计算服务。迄今为止,我们已在 13 个区域创建了 2000 万个 Droplets(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。我们还创建了一个自定义 Exporter 来暴露 Droplet 指标。很快,我们就实现了与 OpenTSDB 服务的特性对等,并开始关闭 Collectd,然后关闭了 OpenTSDB 集群。

人们非常喜欢 Prometheus 及其附带的可视化工具。突然之间,我们的小指标团队堆积了大量待办事项,无法足够快地完成以满足大家的需求。因此,我们没有为人们的服务提供和维护 Prometheus,而是着手创建工具,让其他团队尽可能轻松地运行自己的 Prometheus 服务器,并运行我们在公司中使用的通用 Exporter。

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

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

我们改进了对虚拟机管理程序机器的洞察力。我们从 Collectd 和 Node Exporter 获取的数据大致相同,但对于我们的 golang 开发团队来说,创建一个新的自定义 Exporter 来暴露特定于我们在每个虚拟机管理程序上运行的服务的数据要容易得多。

我们正在暴露更好的应用程序指标。学习和教授如何创建 Prometheus 指标以便后续正确聚合变得更容易了。使用 Graphite 时,很容易创建一个指标,但由于点分隔的名称结构不正确,导致后续无法以某种方式进行聚合。

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

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

我们一直在研究如何让 DigitalOcean 的团队尽可能轻松地收集指标。目前,各个团队正在运行他们自己的 Prometheus 服务器来监控他们关心的事情,这使我们能够快速获得原本无法实现的可见性。但是,并非所有团队都需要知道如何运行 Prometheus。我们正在研究如何使 Prometheus 尽可能自动化,以便团队只需专注于他们希望在其服务和数据库上设置的查询和警报。

我们还创建了 Vulcan,以便进行长期数据存储,同时保留了我们已经围绕其构建工具并培训人员使用的 Prometheus 查询语言。

ShuttleCloud 访谈

继续我们的 Prometheus 用户访谈系列,ShuttleCloud 讲述了他们是如何开始使用 Prometheus 的。来自 ShuttleCloud 的 Ignacio 还在 2016 年 PromCon 大会上解释了Prometheus 如何有利于您的小型创业公司

ShuttleCloud 是做什么的?

ShuttleCloud 是世界上最具可扩展性的电子邮件和联系人数据导入系统。我们通过数据导入自动化切换体验,帮助包括 Google 和 Comcast 在内的一些主要电子邮件和地址簿提供商提高用户增长和参与度。

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

通过为最终用户提供迁移电子邮件的简单途径(同时完全控制导入工具的用户界面),我们的客户显著提高了用户激活率和新用户引导效率。

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 中的一个状态数据库。在那里,每个文档代表一个操作的一种状态。这些信息由状态导入器(Status Importer)处理,并以关系方式存储在 MySQL 数据库中。

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

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

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

当时我们系统的缺点包括:

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

为什么决定考虑使用 Prometheus?

我们分析了几种监控和警报系统。我们迫不及待地想亲自动手测试一下某个解决方案是否会成功。我们决定测试的系统是 Prometheus,原因如下:

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

您如何使用 Prometheus?

最初,我们只使用了 node_exporter 开箱即用提供的部分指标,包括:

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

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

我们使用的一些指标,默认情况下并非由 node_exporter 提供,是利用 node_exporter textfile collector 功能导出的。我们在 Prometheus Alertmanager 上声明的首批警报主要与上述运维指标相关。

后来我们开发了一个操作 exporter,它使我们能够近乎实时地了解系统的状态。它暴露了业务指标,即所有操作的状态、传入迁移的数量、完成迁移的数量以及错误数量。我们可以在 Prometheus 端聚合这些指标,并让它计算不同的比率。

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

  • operation_requests_total
  • operation_statuses_total
  • operation_errors_total

Shuttlecloud Prometheus System

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

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

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

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

Prometheus 如何改善您的工作?

我们无法将 Prometheus 与我们之前的解决方案进行比较,因为我们之前没有一个完整的解决方案,但我们可以谈谈 Prometheus 对我们而言有哪些突出特性:

  • 维护要求非常少。
  • 效率很高:一台机器就可以监控整个集群。
  • 社区很友好——开发者和用户都是。此外,Brian 的博客是一个非常好的资源。
  • 没有第三方依赖;只需要服务器和 exporter。(无需维护 RabbitMQ 或 Redis。)
  • 部署 Go 应用程序轻而易举。

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

我们对 Prometheus 非常满意,但新的 exporter 总是受欢迎的(例如 Celery 或 Spark)。

我们每次添加新警报时都会面临一个问题:我们如何测试警报是否按预期工作?如果有一种方法可以注入虚假指标以触发警报,以便进行测试,那就太好了。

PromCon 2016 - 圆满结束!

发生了什么

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

拉取无法扩展——是真的吗?

让我们来谈谈一个特别顽固的迷思。每当讨论监控系统并提到 Prometheus 基于拉取(pull-based)的指标收集方法时,总会有人不可避免地插话说,基于拉取的方法“根本无法扩展”。给出的理由往往含糊不清,或者只适用于与 Prometheus 本质上不同的系统。事实上,我们已经在最大规模的环境中使用过基于拉取的监控系统,这一说法与我们自己的运维经验背道而驰。

我们已经有一篇 FAQ 条目解释了为什么 Prometheus 选择拉取而非推送,但这篇没有特别关注扩展性方面。让我们仔细看看围绕这一说法的一些常见误解,并分析它们是否适用于 Prometheus,以及如何适用。

Prometheus 不是 Nagios

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

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

谁发起连接并不重要

对于扩展性而言,通过 TCP 连接传输指标数据时,谁发起连接并不重要。无论采用哪种方式,建立连接的开销与指标负载及其他所需工作相比都很小。

您可能会说,推拉式方法可以使用 UDP,从而完全避免连接建立的开销!确实如此,但 Prometheus 中的 TCP/HTTP 开销与 Prometheus 服务器处理数据(尤其是将时间序列数据持久化到磁盘)的其他工作相比仍然微不足道。用一些数字来支持这一点:一个大型 Prometheus 服务器可以轻松存储数百万个时间序列,每秒可处理 80 万个传入样本(这是 SoundCloud 在实际生产指标数据上测得的)。假设抓取间隔为 10 秒,每台主机有 700 个时间序列,这意味着您可以使用单个 Prometheus 服务器监控超过 1 万台机器。这里的扩展瓶颈从未与拉取指标有关,通常是与 Prometheus 服务器将数据摄取到内存中,然后持续地将数据持久化到磁盘/SSD 并过期数据的速度有关。

此外,尽管现在的网络相当可靠,但使用基于 TCP 的拉取方法可以确保指标数据可靠到达,或者至少在网络中断导致指标传输失败时,监控系统能够立即知道。

Prometheus 不是基于事件的系统

一些监控系统是基于事件的。也就是说,它们在每个独立事件发生时(例如 HTTP 请求、异常等)立即将其报告给中央监控系统。然后,该中央系统要么将事件聚合成指标(StatsD 是一个典型的例子),要么单独存储事件以供后续处理(ELK Stack 是一个例子)。在这样的系统中,拉取确实会带来问题:被检测的服务必须在拉取之间缓冲事件,而且拉取必须发生得非常频繁,才能模拟基于推送方法相同的“实时性”,并且不让事件缓冲区溢出。

然而,再次强调,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,Google 过去(部分至今仍)使用 Borgmon 以基于拉取的方法监控其所有关键生产服务。我们在 Google 使用 Borgmon 遇到的任何扩展性问题也并非源于其拉取方法。如果基于拉取的方法能够扩展到拥有数十个数据中心和数百万台机器的全球环境,那么您很难说拉取无法扩展。

但拉取还有其他问题!

确实存在一些难以使用基于拉取的方法进行监控的设置。一个突出的例子是,您在全球各地有许多端点,这些端点由于防火墙或复杂的网络设置而无法直接访问,并且在每个网络段中直接运行 Prometheus 服务器是不可行的。这并非 Prometheus 最初构建所针对的环境,尽管通常可以通过变通方法解决(例如通过 Pushgateway 或重构您的设置)。无论如何,这些关于基于拉取监控的剩余担忧通常与扩展性无关,而是由于围绕建立 TCP 连接的网络操作困难。

那一切都好吗?

本文解答了关于基于拉取监控方法最常见的可扩展性担忧。随着 Prometheus 和其他基于拉取的系统在大型环境中成功使用,并且拉取本身并未在实践中构成瓶颈,结果应该很清楚:“拉取无法扩展”的说法并非一个真正的问题。我们希望未来的讨论能够聚焦于比这个误导性论点更重要的问题。

Prometheus 达到 1.0 版本

一月份,我们发表了一篇关于Prometheus 公开一年的博文,总结了这对我们来说是一段多么精彩的旅程,希望也为您带来了一个创新且实用的监控解决方案。自那时起,Prometheus 也加入了云原生计算基金会(Cloud Native Computing Foundation),继 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 系列中保持稳定

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

不稳定,在 1.x 版本内可能发生变化

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

那么 Prometheus 现在就完整了吗?

绝对不是。我们还有漫长的路线图,充满了许多优秀的功能待实现。Prometheus 不会在 1.x 版本停留多年。基础设施领域正在快速发展,我们完全希望 Prometheus 能够随之演进。这意味着我们将继续愿意质疑过去所做的事情,并对放弃那些不再相关的部分持开放态度。Prometheus 将会有新的主要版本,以促进未来的计划,例如持久的长期存储、Alertmanager 的新迭代、内部存储改进,以及许多我们目前尚不了解的事情。

总结陈词

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

谢谢你们,请继续努力!

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

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

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

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

我们认为 CNCF 和 Prometheus 在主题上是理想的搭配,因为两者都致力于实现现代云愿景。

在接下来的几个月里,我们将与 CNCF 合作最终确定项目治理结构。有更多细节需要宣布时,我们会再进行报告。

何时(不)使用可变位长块 (varbit chunks)

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

ShowMax 访谈

这是我们与 Prometheus 用户访谈系列中的第二篇,允许他们分享评估和使用 Prometheus 的经验。

您能介绍一下您自己以及 ShowMax 是做什么的吗?

我是 Antonin Kral,负责 ShowMax 的研究和架构工作。在此之前,我在过去的 12 年里担任过架构师和 CTO 职务。

ShowMax 是一项订阅点播视频服务,于 2015 年在南非推出。我们拥有庞大的内容库,包含 20,000 多集电视剧和电影。我们的服务目前在全球 65 个国家/地区提供。当更知名的竞争对手在美国和欧洲竞争时,ShowMax 正在攻克一个更棘手的问题:如何在撒哈拉以南非洲网络连接极差的村庄里观看剧集?全球视频流媒体播放量已达到 35%,但仍有许多地方这场革命尚未触及。

ShowMax logo

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

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

Life360 访谈

这是我们与 Prometheus 用户系列访谈的第一篇,旨在让他们分享评估和使用 Prometheus 的经验。我们的首次访谈对象是来自 Life360 的 Daniel。

您能介绍一下您自己以及 Life360 是做什么的吗?

我叫 Daniel Ben Yosef,也就是 dby,我是 Life360 的基础设施工程师,在此之前,我在过去的 9 年里一直从事系统工程方面的工作。

Life360 创建帮助家庭保持联系的技术,我们是面向家庭的家庭网络应用程序。在高峰期,我们每分钟为 7000 万注册家庭提供 70 万次请求服务。

我们在生产环境中管理着大约 20 个服务,主要处理来自移动客户端(Android、iOS 和 Windows Phone)的位置请求,高峰期实例数量超过 150 个。冗余和高可用性是我们的目标,我们努力在可能的情况下保持 100% 的正常运行时间,因为家庭信任我们会保持可用。

我们将用户数据存储在 MySQL 多主集群和包含大约 4TB 数据的 12 节点 Cassandra 环中。我们有使用 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 的工作,以及我们在 DreamHack Summer 2015 期间如何使用 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。