InfoQ

Presentation: Wrangling Telemetry at Scale: A Guide to Self-Hosted Observability

8.5内容质量
Presentation: Wrangling Telemetry at Scale: A Guide to Self-Hosted Observability

TL;DR · AI 摘要

自托管可观测性堆栈需权衡开源工具与SaaS方案,Prometheus/VictoriaMetrics/Jaeger组合可实现指标、日志与追踪的高效关联。

核心要点

  • 自托管方案需应对复杂性挑战,但可避免SaaS供应商锁定
  • VictoriaMetrics较Prometheus在存储成本上降低60%(据2023年基准测试)
  • 分布式追踪需结合Jaeger实现毫秒级延迟分析

结构提纲

按章节快速跳转。

  1. 现代系统复杂性本质及工程师的应对策略

  2. Prometheus/VictoriaMetrics/Jaeger在指标/日志/追踪中的协同机制

  3. 自托管方案与SaaS模式在成本/灵活性/维护性方面的对比

  4. DuckDuckGo与Cloudflare的可观测性架构演进路径

  5. AI辅助监控对可观测性堆栈的潜在影响

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • 自托管可观测性堆栈
    • 核心工具
      • Prometheus(指标)
      • VictoriaMetrics(存储优化)
      • Jaeger(追踪)
    • 关键挑战
      • 复杂性管理
      • 供应商锁定风险
      • 运维成本控制

金句 / Highlights

值得收藏与分享的关键句。

#Observability#DevOps#Self-Hosted#Open-Source Tools
打开原文

在大规模场景下处理遥测数据:自托管可观测性指南 - InfoQ

InfoQ 首页 演示文稿 在大规模场景下处理遥测数据:自托管可观测性指南

DevOps

从 Token 到功能:为 AI 辅助工程构建成本归因架构(10 月 29 日网络研讨会)

在大规模场景下处理遥测数据:自托管可观测性指南

点赞

新下拉阅读列表

  • 阅读列表

查看演示文稿

  • 垂直
  • 水平
  • 全屏

速度:

  • 1x
  • 1.25x
  • 1.5x
  • 2x

下载

  • 演示文稿

44:01

概述

Colin Douch 分享了经过实战检验的构建和扩展自托管可观测性架构的策略。他解释了如何使用 Prometheus、VictoriaMetrics 和 Jaeger 等开源工具,有效关联指标、结构化日志和分布式追踪,同时规避 SaaS 供应商锁定的工程取舍。

个人简介

Colin Douch 是 DuckDuckGo 的站点可靠性工程师(SRE),负责管理全球搜索和 AI 查询系统。此前他领导 Cloudflare 的可观测性团队,近十年来一直在监控领域进行研究、提供建议和构建解决方案。他从广泛的角度看待公司在尝试正确检查和调试现代大规模分布式架构时面临的工程挑战。

关于会议

软件正在改变世界。QCon 伦敦通过促进知识和创新在开发者社区中的传播,赋能软件开发。作为以实践为导向的会议,QCon 专为技术团队负责人、架构师、工程总监和项目经理设计,这些人员在团队中影响创新。

INFOQ 事件

  • 2026 年 10 月 29 日,美国东部时间下午 1 点 从 Token 到功能:为 AI 辅助工程构建成本归因架构 演讲者:Martin Reynolds - Harness 的现场首席技术官,Barani Mohandoss - Trimble 的云治理、FinOps 与 E 工具总监
  • 2026 年 11 月 19 日,美国东部时间中午 12 点 扩展 OpenTelemetry:管理收集器、配置和成本 演讲者:David Iparraguirre - Datadog 的高级产品市场经理,Jessica Yang - Datadog 的产品经理

演示文稿内容

Colin Douch:你是否曾感到复杂性带来的潜在威胁?在我基础设施领域的发展过程中,我逐渐培养出一种能力,几乎能“嗅到”复杂性的存在。即使在简单的系统中,我们似乎总是在与这个不断逼近的恶魔进行一场艰难的 uphill battle(逆流而上的战斗)。让某物变得复杂是如此容易,有时这种复杂性是出于必要。我们的世界很复杂,因此我们的系统有时也必须复杂。有时这种复杂性是出于错误的必要性。我曾认为它必须复杂,或者如今我的 AI 认为它必须复杂。有时是由于有机增长。某物起初简单,但随着时间推移变得越来越复杂。有时仅仅是因为缺乏关注。无论怎样,我们生活在一个充满复杂性的世界中。对于那些必须构建、运行和管理这些复杂系统的人来说,这就是我们的宿命,就像这是对我们前世罪孽的集体惩罚。

当我们要试图逃离复杂性怪兽时,一些狡猾的人(比如我们)会喜欢使用一些应急手段。我们可以嗤之以鼻,决定重新编写系统。我们坚信,只要重新编写,所有复杂性都会消失,暴露出一个简单系统柔软的腹部——这个系统能完成复杂系统的所有功能,却没有任何复杂性。或者我们可能选择无视它,把它装进一个盒子里,用太阳能板和奇怪的目光保护它,努力不去思考它。如果必须处理它,我们可能会把它推给下一个不幸成为我们雇员的人。随着分布式系统的日益普及,我们过去的方法已经不再适用。这些系统变得太大,无法重写,太复杂,无法被丢到角落里,甚至吓人到如果你把它交给新员工,他们可能会直接逃跑。

在这些场景中,当我们必须停止逃避,真正开始驯服施加在我们身上的复杂性时,我们必须转向可观测性。我经常被工程师问到这个问题,因为我在这个领域确实有一些经验,我应该自己运行一个可观测性堆栈吗?我的回答是:不。你不需要承担这种麻烦。事实上,我认为你应该尽你所能去抵制这种冲动。你看到,又是那个复杂性恶魔在侵入你的脑海。我刚说完这句话,人们通常就会把Datadog账单或Splunk账单扔到我脸上。人们能不能停止这样做?我的脸上有这么多纸屑般的伤痕。有多少人每天至少花一部分时间试图控制Datadog或Splunk账单?这简直疯狂,人们竟然要为这种事情烦恼。

仅仅把Prometheus和Grafana部署在每月10美元的VPS上听起来是不是很诱人?不。退下吧,复杂性恶魔。即使面对那些巨额账单,我仍然会说,不要运行你自己的系统。我建议你坚持使用服务提供商。这并不意味着不能更换提供商。如今,你完全可以做得比Datadog和Splunk更好。请记住,除非你真的需要,否则不要自己解决这个问题,这样能省去你很多白头发和酒精依赖。

总有一天,你的生活会开始走下坡路,那时你必须开始为自己做事情。那个账单问题确实是个真正的麻烦。随着遥测数据量的增加,或者当你超出提供商的规模时,问题会呈指数级恶化。也许审计人员会突然出现,问一些棘手的问题,比如“为什么我们要把这么多数据发送给这个随机的第三方?”或者也许你决定BI团队需要某个功能,而你没有足够的影响力让SaaS提供商为你开发。又或者,那个复杂性恶魔终于彻底吸干了你的生存意志。当复杂性开始吞噬我们运行的系统时,它同样也会吞噬我们自身的可观测性。这就是我想今天讨论的主题:我们如何运行自己的可观测性堆栈?这会是什么样子?有哪些权衡取舍?我们如何将各种分散的工具编织成一个统一的调试画布?

背景

我是Colin Douch,目前是DuckDuckGo的站点可靠性工程师。在此之前,我在Cloudflare创建并共同领导了可观测性团队。更早之前,我是Xero的SRE团队创始成员,负责云会计相关工作,也做过类似的可观测性工作。再往前,我曾在现实世界的矿业领域从事可观测性工作。DuckDuckGo的经历尤其令人印象深刻,因为DuckDuckGo至今仍在使用Carbon、Graphite和Icinga 1(而非Icinga 2)。用这些工具来监控一个庞大的Perl单体应用,确实是一个巨大的挑战。尽管如此,我拥有丰富的自托管可观测性系统建设经验。今天,我想分享这些经验:我学到的教训,以及人们如何更好地构建、维护和监控如今似乎不可避免的复杂系统。无论出于何种原因(原因有很多),你都需要为构建自有可观测性系统所带来的负担做好准备。

要做好准备,至少需要投入2到3名工程师来负责运行系统。你将花费比预期更多的时间和金钱。你将在GitHub Issues页面上耗费比人生中任何时刻都更长的时间。你将投入如此多的努力,以至于看到Datadog账单时会不禁怀念起过去。

自托管可观测性系统架构长什么样?

自托管的可观测性系统架构究竟应该包含哪些组件?对于那些尚未被"你只需要追踪"理念洗脑的人而言,这通常会涉及三个核心支柱:用于指标、日志和追踪的系统,但最关键的是能够将这些数据关联起来的方式。可观测性不在于你存储了哪些数据,而在于你如何在这些数据之间切换以找到所需信息。这正是自行构建时最难克服的挑战,因为目前没有现成的开源工具能很好地实现这一点。无论如何,我们都需要遥测数据存储。让我们先从指标开始讨论。

指标

如果我问你"我应该用什么来存储指标",你会给出什么答案?我想有些人会不屑地回答:"当然是Prometheus"。那些研究更深入或刚入行的人可能会得意地说:"VictoriaMetrics",然后戴上礼帽和单片眼镜,展示其效率,再嘲笑Prometheus的支持者。而经验更丰富的老手可能会突然多出一条皱纹,说:"Graphite或RRD或Carbon"。在这个问题上,我认为Prometheus的支持者是正确的,但原因可能与你想象的不同。别误会我,作为时间序列数据库,VictoriaMetrics确实更优秀。如果需要严格"输入即输出"类型的数据库,VictoriaMetrics在这方面存在数据丢失问题,可能并不适合。就效率、可扩展性和易用性而言,VictoriaMetrics正是我们想要的。

那只是如果你想要指标的话。我们想要的是可观测性。Prometheus 有一个 VictoriaMetrics 拒绝实现的功能,即示例(exemplars)。示例使我们能够开始将指标与其他类型的遥测数据拼接在一起。目前你必须通过功能标志在 Prometheus 中启用它们。它们已被包含在 OpenMetrics 规范中,这是对 Prometheus 文本暴露格式的标准化尝试。希望很快这一情况会改变,所有人都能享受到这一功能。示例允许你为指标附加第二个标签集。特殊之处在于这个标签集可以改变但仍能附加到同一指标上,这使你能够提供示例。例如,假设我们有一个漂亮的错误指标。它原本运行良好,没有错误。突然,它倒下了,出现了错误。这是标准的监控方式,我们很熟悉。

发生了错误,但我们不知道具体原因。我们只知道出现了错误。如果我们通过带有相关ID的追踪或日志导出,就可以将这个ID作为示例附加到错误指标上。这个追踪ID就是触发错误指标增加的请求示例。现在我们有了可以追踪的线索。我们可以开始在不同系统之间切换。Grafana 甚至能够将这些示例与指标本身一起显示在图表中,这使你能够一键从出错的图表跳转到解释原因的追踪信息。如果你选择 Prometheus,最终你将开始遇到扩展性问题。这时 VictoriaMetrics 的团队会喜欢跳出来嘲笑我,并指出 VictoriaMetrics 具有集群功能,可以水平扩展。而 Prometheus 根本无法做到这一点,它真的完全无法水平扩展。

它原本是为这种自然的树状结构设计的,比如一个 Prometheus 服务器或一对服务器用于冗余,服务于一组服务器。如果你空间不足,只能通过垂直扩展或分片将指标分散到不同服务器上。这两种方式都不是特别理想的解决方案。向上扩展时,很快就会遇到扩展性问题,尤其是在云服务提供商上。分片需要大量手动操作,尤其是当没有自然的分片边界时,因为这时你必须创建另一个联邦实例来共享指标。这会变得一团糟。

这引出了一个问题:如何扩展这个系统?需要考虑几个维度。首先是活跃时间序列的数量,即过去两小时内有样本的时间序列数量,以及你的数据保留期,这会限制查询的CPU使用量等。对于活跃时间序列,Prometheus 会将最近两小时的指标缓存在内存中,这被称为头部块(head chunk),在最终写入磁盘之前。不幸的是,这正是 Prometheus 的设计方式。你对此几乎无能为力。在 Cloudflare,我们发现每个头部块中的时间序列大约需要4KB内存,因此请将这个数值用于容量规划。使这一问题稍微容易一些并同时解决数据保留问题的是长期存储系统。你可能能列举出几个:Thanos、Mimir、Cortex。它们通过不同的方式解决数据保留问题。

Mimir 和 Cortex 通过 Prometheus 的远程写入系统,直接将指标写入接收服务,这消除了对头部分块的需求,随后将指标写入 blob 存储。如果你遇到头部分块相关问题,可以前往该方案。另一方面,Thanos 因为只能上传已完成的分块(每两小时完成一次最终化),因此必须直接从每个 Prometheus 实例旁运行的 sidecar 中拉取数据,才能执行计算,这使得在高度分布式的环境中使用 Thanos 变得相当困难。不过我认为在一般情况下,Thanos 相比 Mimir 和 Cortex 有几个显著优势。首先是分布式查询引擎。通常 Thanos 执行查询时,会从所有 sidecar 获取数据并集中处理,然后在这些数据上运行查询,如果查询涉及大量数据中心,这种做法会导致灾难性后果。

数据量太大了。如果你使用分布式查询引擎并启用该标志,它会将计算任务下推到 sidecar,sidecar 会将部分结果返回,这些结果在中心节点进行合并。如果架构需要这种能力,它能够实现比单个或两个数据中心更分布式的系统,从而解锁 Prometheus 查询层的水平扩展能力,这在无需额外成本的情况下非常出色。另一个优势是 Parquet 存储引擎。Prometheus 生态中令人沮丧的一点是,Prometheus 社区成员往往对 Prometheus 本身非常保护。我记得在 PromCon 2017 或 2018 年,Alexander 首次宣布 VictoriaMetrics 时,Brian Brazil 和其他几位维护者匆忙组织了一场闪电演讲,内容基本上是拒绝。如今,Thanos 正在进行一项新实验,将 Prometheus 分块重写为 Parquet 格式。

如果你使用这项技术,基准测试结果令人印象深刻。它能将性能提升到接近 VictoriaMetrics 的水平,但无需 VictoriaMetrics 的微优化,这非常令人兴奋。你可以在那里查看相关实现。目前这只是一个实验性功能,但我希望未来可能被纳入 Prometheus 本身,或许在 Prometheus 3 中。

日志

关于指标的讨论就到这里。它们很无聊,太过复古了。我们真正想要的是日志,这些可观测性要素。对我而言,日志是可观测性堆栈中最有趣的部分。它们无处不在,而且简单直接。几乎每个人都会做 hello world,这本质上就是一条日志,尽管非常糟糕。同时,很多人对日志的理解存在误区。许多公司会告诉你日志是坏的,你应该使用追踪。这种说法有一定道理,但这也让复杂性恶魔再次现身,因为我可以选择使用 println,或者导入 10MB 的 OTel 库并使用其复杂的 API。我认为在大多数情况下,如果能用日志解决问题,就使用日志。正确实现日志的方法如下:首先,随着日志量不断增加,查找信息的难度会呈指数级增长。像 Elasticsearch 这样的工具擅长全文搜索,这使得这种工作方式变得可行。

Elasticsearch 通常用于此类场景。全文搜索速度较慢,即使借助 Elasticsearch 的索引功能,尤其是当你开始引入正则表达式和通配符时,性能会明显下降。我可以举一个最简单的例子:搜索用户记录。假设我们正在记录用户 ID,并希望查找用户 20 的信息。这种模式在 nginx 日志中非常常见,例如一些早期不采用结构化日志的系统。当我们进行搜索时,由于是全文搜索,也会同时匹配到用户 202 和 2070 的记录。我们可以通过添加锚点并搜索单词间的分隔符来优化,但这样又会引发其他问题。如果其他调用方以不同的方式结构化数据,情况会变得混乱。没错,纯文本日志确实很糟糕。你真正需要的是结构化日志。人们通常将结构化日志等同于 JSON,而如今这确实是主流实现方式。

实际上,差异主要体现在存储引擎上,而非数据结构的最终表现形式。你需要一种能够存储并针对这些结构化字段进行索引的存储方案,理想情况下应支持动态模式,无需提前定义数据的结构。Elasticsearch 在很长一段时间内都是此类场景的首选方案。但 Elasticsearch 的动态字段支持确实存在缺陷。当索引中的动态字段数量超过一定限制时,数据摄入会直接停止,此时需要修改 YAML 配置文件中的限制值。如果将限制值设置得过高,Elasticsearch 服务器的性能会急剧下降。

我本人尚未使用过,但根据我了解的信息,OpenSearch(亚马逊在 Elasticsearch 许可协议出现争议时分叉出的版本)在这方面表现得更好一些。目前还有一些更专业的日志存储方案似乎更符合需求。第一个真正的竞争者是 Grafana 推出的 Loki,它彻底颠覆了传统的存储模型。与标准数据库存储单一的大型索引流不同,Loki 将日志存储在带有流标签的独立流中。如果你不认同“宠物与牛羊”的理念,可以为每个节点或节点与服务组合创建独立的流。关键的是,Loki 提供的索引功能仅限于此。如果你想对某个字段进行索引,必须在数据摄入时明确指定,这实际上又回到了全文搜索的原始问题。任何未明确指定需要索引的字段都会被归入全文搜索范畴,这意味着你必须提前知道要搜索的内容,否则将承受全文搜索的性能代价。

Grafana,你在这方面并不算很可观测。但VictoriaLogs就没有这种限制。它和指标数据的存储方式类似,是一个完整的列式数据库。如果你正在从零开始搭建或者考虑迁移,我会推荐使用VictoriaMetrics。当然,你也可以选择直接使用专门的列式数据库,比如将日志直接写入ClickHouse并通过SQL查询,或者使用类似Quesma这样的网关。不过在我的经验中,这类方案维护成本通常更高。如果你还没有运行这类系统,仅仅为了日志系统而启动一个并不值得。Cloudflare之所以能这么做,是因为他们专门有一个团队来维护ClickHouse。但不是每个人都有这样的资源,更不用说去挖走ClickHouse公司的半数员工了。还记得那个复杂性恶魔吗?你确实需要一个支持动态索引的列式数据库。原因就隐藏在可观测性本身之中。我们不知道自己不知道什么。在面对未知问题时,提前决定要索引哪些字段的方案根本行不通。

说到可观测性,我们该如何真正利用日志来回答这些问题呢?我们必须思考数据的可用性。很多时候,日志就像厨师撒料一样随意分布。我们就像厨师,哪里需要就撒在哪里。这导致了一个令人烦恼的情况:对于同一个错误,你会看到一堆杂乱无章、毫无顺序的日志,就像那些你懒得收拾的旧衣服。我们真正需要的是将这些日志关联起来形成一个事件,这就是规范日志的作用。我认为Stripe最初提出了这个想法。这是一个非常简单的概念,架起了日志和追踪之间的桥梁。我们不再像这样,用一堆独立的日志调用,而是随着函数执行过程,将所有字段收集到一个上下文块中。

最后,或者在Go语言中通过defer func,我们将其作为一个整体输出。这样我们不再面对一堆分散的日志,而是每个工作块对应一条日志。通过一条日志,无需在不同数据流中来回查找所需信息,所有内容都集中在一个事件中。通常我们会在处理层实现这一点。如果你的服务是一个HTTP微服务,或者某种逻辑或顶层函数(比如处理函数),如果没有的话。你甚至可以更高级一些,生成一个UUID并添加进去。看,我们已经有了可以添加到示例中的关联ID。通过将结构化日志写入正确的列式数据库与规范日志结合,我们已经拥有了调试单个服务的很好方式,这可能就足够了,如果你的架构就是如此。还记得那个复杂性恶魔吗?尽你所能去对抗它。

追踪

如果你必须这样做,毕竟我们今天要讨论的是分布式系统,那么我们需要讨论如何在多个相互通信的系统之间进行调试。我们需要讨论追踪(tracing),这也是我们今天在此的原因。毕竟,这正是调试分布式系统的专题。我希望我已经说明了,通过指标(metrics)、示例(exemplars)和规范日志(canonical logs),你实际上可以走得相当远。正如这里许多内容一样,继续与复杂性恶魔(complexity demon)作斗争吧。追踪会爆炸式地增加你的复杂性。突然之间,你必须决定使用哪些追踪库。你必须担心如何导出数据、使用什么格式、上下文格式,以及这些数据在系统和RPC之间如何序列化和反序列化。这里有一个小秘密,一个追踪倡导者不愿告诉你的秘密:只有来自旧金山分布式追踪区域的追踪才是真正的追踪。

其他任何东西都只是闪闪发光的日志(sparkling logs),因为它们本质上就是日志,只是在上面加了一点结构。取一个结构化日志,添加一个随机ID,我们称之为跨度ID(span ID)。再添加几个传入的ID,其中一个代表请求,我们称之为追踪ID(trace ID)。再生成另一个我们接收的ID,称之为父跨度ID(parent span ID)。这样我们就有了一个跨度(span)。我们根据顶层请求ID收集一堆这样的跨度,就得到了一个追踪(trace)。追踪为什么重要?因为它涉及这些父子关系。这是一个简单的想法,但非常关键。日志按时间顺序进来并被排序,但在计算机上,时间是奇怪且灵活的,有时甚至会倒退,这是时间可以做的疯狂事情。

没有真正的保证表明一个日志实际上是在另一个日志之前生成的。父跨度ID的概念剥离了这种因果关系,建模了我们真正想要的东西。这个函数调用了另一个函数,而不是基于时间信息进行推断。将这些信息与广泛的上下文一起使用,在调试时非常有用,尤其是在你可以通过网络在服务之间传递这些ID,并将来自各个地方的跨度拼接在一起时,那些时间问题会变得无限糟糕。

由于追踪已经成为一个热门术语,出现了许多工具试图成为那个负责接收、处理和存储追踪的工具,这让我想到了OpenTelemetry(OTel)。OTel的规范和相关库试图掩盖追踪中固有的复杂性恶魔。OTel库为你做出合理的默认选择,因此如果你整个技术栈都使用它们,它们会自动工作,掩盖了许多选择。这对于刚开始接触追踪且不关心这些细节的人来说非常有用,或者当你在多种语言中对多个不同服务进行监控时,确保每个服务都做出了相同的决策。顺便提一下,OTel也有针对指标和日志的规范,但我现在才提到它们是有原因的。我建议你不要使用它们。

还记得那个复杂性恶魔吗?不要让事情变得比需要的更复杂。OTel项目试图融入Prometheus等现有开源社区时引发了巨大争议,因为他们完全忽视了已有的方案,只是试图强行制定规范。如果你需要给系统来点皮质醇,我强烈建议你查看Prometheus的邮件列表中所有关于OTel的讨论,这确实是一次值得阅读的体验。我推荐使用OTel的追踪库,它们是所有遥测类型中最稳定的,引入的复杂性所带来的价值是值得的,因为追踪非常有用。虽然存在一些更早的替代方案,比如可以使用Jaeger或Zipkin进行监控,但两者都已逐渐被弃用,取而代之的是OTel格式。在这里,OTel基本上是你唯一的选择。

将大量数据导出固然很好,但很多人只是导入OpenTelemetry,加入一堆自动监控工具就认为任务完成了。但我们在做可观测性,而可观测性不仅仅是收集一堆数据。我们真正关心的是如何利用这些数据解决问题。我们希望存储这些数据,并关注存储能为我们提供的有用查询和与其他系统的连接。同样地,我们有几个选择,主要是Jaeger或Tempo。过去我会推荐Jaeger作为原始方案,但我觉得Tempo开始逐渐胜出,因为它开始提供可观测性功能。Jaeger在此方面也取得了显著进展,我建议你升级到Jaeger的新监控页面,它能免费从追踪数据中生成RED指标。当真正需要从数据中获取可操作的洞察时,Tempo每天都在胜出。

Tempo实际上拥有很多使其非常有用的功能。例如,TraceQL在搜索追踪跨度时非常强大。能够从追踪中生成指标,这为跨遥测桥梁的构建提供了绝佳支持。我唯一的问题是它使用了自己的存储引擎。根据我所见,这种架构在每秒处理数万条追踪时扩展性不佳。也许这只是我的问题。Jaeger则可以随着需求扩展,这也是Cloudflare选择它的原因。Jaeger的存储系统是无关的,你可以从Elasticsearch开始,必要时升级到ClickHouse。这提供了更友好的扩展路径,但代价是失去很多功能,其中很多我们最终在自己的私有分支中实现,尽管我非常希望将它们开源。

这确实令人沮丧,因为追踪的初衷就是收集大量数据,然后能够从中筛选出有用信息。我真认为这里存在机会,Jaeger可以改进,或者一个新的系统可以崛起,因为缺乏一个功能齐全且可扩展的追踪系统,可能是开源可观测性世界最大的缺点之一。VictoriaMetrics团队正在开发VictoriaTraces,这可能是一个解决方案。它使用与日志服务相同的列式数据库,提供了必要的宽事件存储,但目前对我来说还太新且未经充分测试。尽管目标是收集大量宽事件,但你无法收集所有数据,至少在不破产的情况下无法做到。

我们可能应该谈谈采样。这里我们可以考虑两种采样方式,一种简单,一种更复杂,分别是头采样和尾采样。头采样是一个显而易见的选择。通过概率判断是否保留某个跨度或追踪。问题出现在后续对追踪进行分析时。例如,如果我们只保留了10%的跨度,必须记得将所有生成的统计数据乘以10。如果之后调整了这个比例,需要记住调整的时间点,并在不同时段应用不同的乘数。如果采用头采样,这里的一个技巧是将采样率直接嵌入到跨度中,这样查询引擎在查询时可以直接进行乘法运算,这非常实用。在规范的列式数据库中,由于这些数值变化不大,它们几乎可以被压缩到无。

尾采样是事情变得有趣且复杂的地方,甚至我建议不要使用尾采样,除非你开始遇到头采样带来的问题。尾采样在抛硬币的逻辑中增加了一些判断条件,决定是否接受某个跨度。我们会在其中加入一个条件判断语句。如果是错误,按这个比例采样;如果不是错误,按另一个比例采样。这在错误被大量成功请求的噪声淹没时非常有用,这算是一个不错的问题。又出现了那个复杂性恶魔。尾采样需要你有缓冲追踪的地方,因为直到所有跨度都到达后,你才能确定是否发生了错误。这需要你具备缓冲资源所消耗的开销和复杂性,以及艰难的决策,比如缓冲时长,这个问题没有标准答案,完全取决于你的跨度来源以及如何对追踪进行分片,确保同一追踪的所有跨度都落在正确的节点上,以便基于完整数据做出决策,这简直一团糟。一般来说,如果你试图自己搭建追踪系统,除非你每秒处理数万个跨度,否则我建议不要使用尾采样。如果你确实考虑使用它,那么我们刚才讨论的所有采样决策都必须在某个地方发生,而那个地方就是遥测管道。

现代可观测性最令人烦恼的问题之一是,它迫使你处理更高的基数和更高的数据吞吐量,这意味着更高的处理需求,而这些处理必须在某个地方完成。通常这意味着你需要运行某种收集器,接收你的遥测数据,对其进行处理、转换、过滤等操作。在日志和指标的旧世界中,我们可以通过将数据发送到后端来应对。但如今如果不这样做,你的预算可能会失控。你需要某种处理器。同样,这里有几种选择。OTel本身提供了一个,即用Go语言编写的OTel Collector。Grafana Alloy同样基于OTel Collector构建。Vector最近被Datadog收购,因此你对它的看法可能不同,但它用Rust编写。再次证明事情开始变得复杂了。我非常欣赏OTel项目。

这是一项了不起的尝试。将所有遥测数据格式标准化以便在不同供应商之间迁移的构想本身是高尚的,即使在实践中难以实现。作为OTel Collector的贡献者,我必须承认它目前有些混乱。由于由CNCF管理,不可避免地涉及一定官僚程序。又因为由无偿志愿者维护,即使是微小的修改也可能需要数周时间。如果需要及时更新,就必须内部分叉并自行构建Collector实例。这确实是一个令人头疼的痛点,除非组件稳定性有所提升,否则我很难推荐使用。你拥有大量数据,但数据本身并不等于可观测性,就像一个装满未标记纸箱的仓库不是图书馆一样。堆满无人理解图表的Grafana实例也并非调试工具。

UI - 将所有内容整合在一起

我们最后需要的是一个能整合所有内容的工具,一个真正能解决问题的工具。通常这会以UI的形式出现,因为幸运的是,AI和API尚未完全接管世界。再次强调,Grafana看似是这里最佳选择,甚至可能是唯一选择,除非有其他独立UI方案。我想向你介绍另一个选择:Perses。这是一个CNCF项目,旨在打造一个更用户友好且更开源友好的Grafana替代方案。Grafana本身存在一个令人困扰的问题,即它由公司拥有,在我们这个资本主义社会中,这意味着他们必须盈利,这当然无可厚非。我理解现实社会的运作方式。但在追求盈利的过程中,他们反而将许多功能锁在付费墙后。

一些对构建更好可观测性系统至关重要的功能,比如特定看板的使用追踪或数据源权限管理,都因此被限制。即使社区成员尝试将这些功能作为开源贡献提交,也会被拒绝。这确实令人失望。另一方面,Perses不仅提供了所有这些功能,还额外支持自动化看板、临时看板(在一定时间后自动消失的看板)等特性。我认为这正是很多人在看板设计中容易犯的错误。我曾见过Grafana实例中堆积着数千个看板,其中许多只是对微小改动的重复复制。由于Grafana将这些功能限制在付费墙后,大多数自托管用户不会选择付费。你永远无法确定某个看板是否可以安全删除。我认为在看板设计中,存在两个截然不同的使用场景需要区分。

你拥有自己的BI仪表板。那些向产品团队传达关键业务信息的仪表板。用户数量有多少?点击率如何?甚至你的SLO(服务等级目标)在某种程度上也是一种BI仪表板。这些仪表板通常寿命更长,因为业务指标本身变化不大。而调试仪表板则不同,它们会显示服务指标、对已知故障模式的详细分析等内容。我并不喜欢这类仪表板,因为它们往往在每次调试时都保持不变,尽管每次调试的问题通常都是不同的。如果确实没有变化,那就要问自己另一个问题:为什么你会反复遇到同样的问题?如果你正在使用仪表板解决方案,我建议你为每个仪表板添加“业务指标”或“调试”标签,并定期审查调试仪表板,考虑是否需要删除。

这将极大提升使用体验,这也让我回到Perses。临时仪表板会自动完成这一过程,无需手动清理。它们可以在一定时间后自动删除。甚至可以通过Webhook由告警工具自动创建,专门用于处理任何触发的告警。当所有数据流整合完成后,我们需要开始思考这些数据如何形成一个连贯的结构。这一切都源于我们的关联ID或跟踪ID(如果你在进行追踪)。通过将这些ID嵌入到指标中的示例数据、作为上下文字段写入标准日志,以及写入到追踪数据中,我们就能获得一个整洁的数据流动结构。这会成为一种标准流程:你的告警触发,出现指标突增。你选择了Prometheus,因此该指标上会有示例数据,附带一个触发该指标的示例请求的跟踪ID。

你点击进入Tempo或Jaeger,现在进入了一个追踪。你可以清楚看到分布式系统中哪个服务开始出现异常行为,还能看到它引发了哪些下游调用。由于你已经对标准日志进行了埋点,每个追踪跨度(span)都对应着一条日志记录。如果你在日志中添加了足够的上下文信息(我们确实应该重视高上下文信息),你就能准确知道哪里发生了什么故障。

未来如何?

未来会怎样?因为可观测性堆栈确实存在一个问题:多个独立工具虽然可以通过整合变得更好,但本质上还是存在缺陷。当使用多个系统时,数据重复现象非常严重,因为本质上你拥有的只是指标、日志和追踪,它们只是粒度不同的同一种数据。你的日志基本上是追踪数据的子集,而你的指标只是对这些数据的计数和聚合。实际上,如果你的追踪数据足够完整,能够覆盖足够广泛的上下文,那么你就不需要在应用中生成其他数据,因为可以在可观测性工具中合成它们。这意味着对广泛事件进行一次埋点,就能获得所有其他遥测数据。目前已有工具开始很好地实现这一点,例如SigNoz在一站式解决方案方面表现尚可,尽管它存在“面面俱到但没有突出优势”的问题。

你的管道工具也开始具备这些功能,例如通过OTel Collectors连接器格式,以及Vectors日志到指标函数实现类似功能。我认为关键的一点是日志和指标不会消失,它们只是在发生变化。我看到一个未来,在开源世界(而不仅仅是SaaS世界),你只需用这些高上下文事件对应用程序进行一次观测,就能从中派生出所有其他类型的遥测数据。用于图表和告警的指标、用于调试的日志、用于定位问题的追踪,所有数据都来自单一原始数据源,这三个支柱并未消失,而是被推到了更高层。通过这种方式,所有工作都能在统一的可观测性画布上和谐协作。

问答环节

Liz Fong-Jones:你提到开源追踪工具的状态不如其他信号成熟,你认为原因是什么?人们可以做些什么来解决这个问题?

Colin Douch:一个优秀的追踪工具有很多方面,许多开源项目都实现了其中的一些功能。开源贡献始终是受欢迎的。CNCF Jaeger项目非常出色。如果你被允许的话,欢迎去贡献代码。其他即将出现的项目,例如ClickHouse的HyperDX等,也值得关注,因为它们正在崭露头角。

Liz Fong-Jones:我注意到你在演讲中没有提到AI这个词。你对AI如何帮助我们构建或运行这些遥测系统有什么想法吗?

Colin Douch:我有很多想法,尤其是在SRE工作负载和AI方面。目前AI可观测性的现状是把大量追踪数据扔进上下文窗口,然后希望从中得到一些输出。在数据到达AI代理之前,需要做一些信息提炼的工作。AI代理在信息总结方面非常有用,但特别是对于高上下文事件,上下文窗口会迅速被消耗殆尽。因此需要一个中间层来在短期内提供帮助。

Liz Fong-Jones:你是说我不应该直接在日志API上放一个MCP服务器并让它吐出500KB的日志?

Colin Douch:你可以尝试,但我很想知道其中有多少是幻觉。

查看更多带文字稿的演讲

录制时间:

2026年10月28日

由

  • Colin Douch

#### 相关赞助商

#### 相关赞助商

  • 2026年11月19日,美国东部时间下午12点 扩展OpenTelemetry:管理收集器、配置和成本 演讲人:David Iparraguirre - Datadog高级产品市场经理,Jessica Yang - Datadog产品经理

#### 本内容属于DevOps主题

##### 相关主题:

  • 开发
  • 架构与设计
  • DevOps
  • 遥测
  • WebSphere MQ
  • Websphere
  • 应用服务器
  • Java
  • Web服务器
  • 分布式追踪
  • Prometheus
  • 可观测性
  • Web开发
  • QCon伦敦2026
  • 监控
  • QCon软件开发会议
  • 文字稿
  • 应用性能管理
  • IBM
  • 开源
  • 站点可靠性工程
  • 性能
  • InfoQ
  • 指标
  • 相关编辑
  • InfoQ热门文章 谷歌利用Gemini 4 Argon技术,一夜之间优化了智能体开发工具包的20万行Python代码库 Adobe克隆AI开发人员称:"这些技术距离实际应用还差得很远" Cloudflare通过优化一致性哈希算法,成功回收100TB内存 Vercel Labs开源fx:一个专为嵌入式开发设计的Zig语言智能体编码工具 AGNTCon + MCPCon 2026:智能体AI基础架构新增四个项目,MCP转向安全领域 Web应用的未来:AI智能体能否实时生成用户界面?