如果你维护过微服务,大概率被链路追踪折磨过:数据量太大存不起,存少了又查不到问题。Grafana Tempo 3.1 这次更新,核心思路就是解决这两个老难题——用查询语言精准脱敏,以及让基于采样数据的指标查询结果更准确。

先说说背景。Tempo 是 Grafana 家的分布式追踪后端,今年 6 月发布的 3.0 做了一次大手术,把默认架构从原来的 ingester + compactor 模式,换成了 Kafka 兼容架构(代号 Project Rhythm)。新架构里,数据先写到 Kafka topic,然后由 block-builder 消费并写成 Parquet 块存到对象存储,同时 live-store 也消费 Kafka 来服务最近数据的查询。原来的 ingester 和 compactor 被彻底移除,取而代之的是一个后端调度器和一堆 worker。这么改最大的好处是存储成本:以前为了保证不丢数据要存 3 份副本,存储开销是追踪数据量的 3 到 3.5 倍,现在只需要一份。单机模式仍然可以不依赖 Kafka。

但 Kafka 上了关键路径,3.0 自带的客户端就成了短板。它只支持 SASL PLAIN 且不加密,遇到要求 TLS 的 broker 直接连不上。3.1 补上了这块:支持 TLS(包括可选的 mTLS),还加了 SCRAM-SHA-256、SCRAM-SHA-512、OAUTHBEARER 和 AWS_MSK_IAM 这些认证机制。另外新增了 client_rack 选项,可以实现机架感知的拉取(KIP-392),让 block-builder、live-store 和 metrics-generator 优先从自己可用区内的副本读数据,省掉跨可用区的流量费。还有个 producer_compression 选项,可以选 none、gzip、snappy、lz4 或 zstd,默认 snappy。Grafana 特别提到,有了 TLS 和 gzip 压缩,Azure Event Hubs 也能当后端用了,因为它只接受 gzip。这三个改动都来自社区贡献者。

接下来是这次更新的重头戏:基于查询的追踪脱敏。3.0 里就有脱敏功能,通过 tempo-cli redact 命令实现,但那时候你得先列出一堆 trace ID。问题是,token、账号这类敏感值往往散布在成千上万个 trace 里,你根本列不过来。3.1 改成了直接传 TraceQL 查询,还支持 --dry-run 参数,可以先数一下有多少匹配而不真正改数据。不过 Grafana 限制了语法:只能用一个 spanset 过滤器,用 resource.* 和 span.* 属性的等值比较,配合 && 和 ||。为什么限制这么严?因为重写操作不可逆,改错了没法撤销。另外还有 --start 和 --end 参数可以限定时间范围,这个很重要,因为脱敏期间 Tempo 会暂停该租户的压缩。Grafana 警告说,老版本的 worker 会忽略这个时间窗口,把每个 block 里所有匹配的都删掉,而且不报错。所以这两个参数只能在所有 scheduler 和 worker 都升级到 3.1 之后才能用。

TraceQL metrics 在 3.0 已经 GA,这次加了三个改动。最值得关注的是实验性的 extrapolate=true 提示,它会让指标查询结果按采样率放大。原理是遵循 OpenTelemetry 的概率采样规则:如果采样率是 50%,那么每一条存储的 span 就代表实际的两条。没有记录采样率的 span 按 1 算,这样部分接入采样的服务不会影响其他服务的统计。这个提示适用于 rate、count_over_time、sum_over_time、avg_over_time、histogram_over_time、quantile_over_time 和 compare,但不适用于 min_over_time 和 max_over_time。它要求 vParquet4 或更高版本,读取采样率的方式和 3.0 里 metrics-generator 的 enable_tracestate_span_multiplier 设置一致,所以临时查询和预聚合的序列结果能对得上。第二个改动是指标查询现在支持 +、-、*、/ 和标量运算,比如错误率可以写成一条查询了。第三个改动是 3.0 里实验性的 span-only 读取路径,现在对 vParquet5 block 默认开启。在一个预热测试里,{ } | rate() 的耗时比之前快了一倍多。

其他小改动也值得提一下。trace-by-ID v2 端点加了实验性的 span 剪枝选项,能把相似的叶子 span 合并成一个带计数和时长统计的摘要 span,这个端点也支持 TraceQL 过滤了。新增的实验性 POST /api/v2/traces/diff 端点可以对比两个 trace,返回紧凑摘要而不是逐 span 的差异补丁,通过 gcx、tempo-cli 和 Tempo MCP server 暴露。Grafana 说更小的 payload 对 LLM 驱动的排查很有帮助。metrics-generator 那边,过期的 service-graph 边会带上 unmatched_span_kind 标签,支持了 OpenTelemetry 改名的 db.system.name 属性,还有池化的 label buffer,Grafana 说在 service-graph 基准测试里把每个 span 的内存分配降到了零。

这套设计思路其实可以迁移到很多场景。如果你在维护自己的追踪或日志系统,Kafka 上关键路径后的客户端能力补齐是个典型教训:架构升级时别忽略基础设施组件的边界能力。TraceQL 脱敏的思路也值得借鉴——用查询语言而不是枚举 ID 来圈定敏感数据范围,配合 dry-run 预览,是处理大规模数据变更的安全姿势。采样感知的指标计算更是通用:任何基于采样数据做统计的系统,都应该考虑在查询时按采样率还原真实值,否则你的 P99 延迟和错误率全是错的。

要注意的坑:脱敏的不可逆性决定了它必须限制语法,别想着支持任意表达式;时间窗口参数要等所有节点升级完才能用,否则老 worker 会误删数据;extrapolate 目前还是实验特性,生产环境用之前先在小范围验证。如果你正在用 Tempo 3.0,这次升级值得做,尤其是存储成本敏感或者用了 Azure 的场景。

Accelerating Performance by Incrementally Integrating Rust into Existing Codebas
Accelerating Performance by Incrementally Integrating Rust into Existing Codebas
阅读原文 → 返回 AI 技术文档

内容与图片版权归原作者所有 · 原文: https://www.infoq.com/news/2026/10/grafana-tempo-31/?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global