VictoriaMetrics 开发者笔记:团队内关于 Distributed Tracing 的调研,对比 Tempo 和 ClickHouse - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
RedisMasterNode
V2EX    程序员

VictoriaMetrics 开发者笔记:团队内关于 Distributed Tracing 的调研,对比 Tempo 和 ClickHouse

  •  1
     
  •   RedisMasterNode 150 天前 1496 次点击
    这是一个创建于 150 天前的主题,其中的信息可能已经有所发展或是发生改变。

    谈到可观测性,人们总是会提起它的三大支柱:Metrics, Tracing, 和 Logging 。在 VictoriaMetrics,我们已经有了 Metrics 和 Logging 的解决方案 VictoriaMetrics 和 VictoriaLogs 。同时我们也一直听到很多声音,其中之一就是:VictoriaTraces 什么时候发布。

    如果你也关心这个问题,那么相信这篇博客可以让你了解我们内部对 Distributed Tracing 解决方案的调研情况:会不会有 VictoriaTraces它和竞品比起来怎么样

    1. 什么数据库适合 Trace Span

    一个 Trace 是由许多 Span 组成的,所以要打造一个 VictoriaTraces ,我们首先思考的是,Span 长什么样子,什么数据库适合存储这种数据

    以下是一个 Span 的例子:

    { "name": "/v1/sys/health", "context": { "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", "span_id": "086e83747d0e381e" }, "parent_id": "", "start_time": "2021-10-22 16:04:01.209458162 +0000 UTC", "end_time": "2021-10-22 16:04:01.209514132 +0000 UTC", "status_code": "STATUS_CODE_OK", "status_message": "", "attributes": { "http.method": "GET", "http.target": "/v1/sys/health", "http.server_name": "mortar-gateway", }, "events": [ { "name": "", "message": "OK", "timestamp": "2021-10-22 16:04:01.209512872 +0000 UTC" } ] } 

    很容易留意到,它就是一系列 Key-Value 的组合,大部分 Key-Value 仅作展示,小部分(如 trace_idattributes)可以被用作查询条件。

    如果你恰好也有了解过 Logging 的一些解决方案,你会发现 Trace Span 和 Structured Log 很像:

    1. Structured Log 和 Trace Span 都是由一系列的 Key-Values (或者 Fields ,Attributes ,Tags ,不管怎么称呼它们都行)组成,而这些 Key-Values 中有很多重复的内容
    2. 它们对写入量需求很大,一个企业每天可以轻松采集数 TB 甚至 PB 的 Logs ,Traces 也是一样。
    3. 这些被保存下来的数据只有很少一部分会被查阅,所以围绕这个特点产生了很多采样方案。

    当前,几乎没有数据结构能同时针对读性能写性能磁盘空间进行优化,在这个三个考察标准中通常只能满足其中一或两项。对于 Structured Logs 和 Trace Spans ,它们很显然更强调写入吞吐量以及磁盘空间。所以:

    1. 基于 LSM-Tree 的数据结构比基于 B+Tree 的数据结构更合适。前者通常能提供更好的写入性能,而后者更强调查询性能。
    2. Column-oriented 数据库比 Row-oriented 数据库提供更好的空间利用率,因为 Column (或 Field )中数据的相似性更高,更易于压缩。反之,数据按 Row 存储时更容易获取一行内的数据,这对高性能的查询有帮助。

    那么到这里,我们的目标稍微明确了一些:VictoriaTraces 可能是一个基于 LSM-Tree 的列式存储数据库

    2. 造新轮子?

    在造轮子之前,我们需要先了解满足这些要求的数据库都有哪些。如果你是 Jaeger 的用户,你一定熟悉它的其中一种存储方案:ClickHouse。ClickHouse 在 Jaeger v1 中以 plugin 形式存在。到了 Jaeger v2 ,社区希望对其提供原生支持这再一次说明基于 LSM-Tree 的列式存储非常契合 Trace Span 数据

    题外话:谁在用 ClickHouse 作为 Traces 存储?

    • 当我还在 Shopee 工作的时候,内部 Tracing 平台是基于 Jaeger 改造的,它的存储最初是 Elasticsearch ,当规模逐步扩大后,被替换为 ClickHouse 。
    • 后来,我入职了富途牛牛,尽管时间很短只有 3 个月,我与可观测团队还是有过一些简单的交流。它们的 Tracing 平台使用的是 Zipkin ,并且刚从 Cassandra 迁移到 ClickHouse 。
    • 在加入 VictoriaMetrics 前,我在 TT 语音工作,当时使用的是腾讯云的 Tracing 平台。从一次数据导出中,我观察到很多地方有 ClickHouse 的身影,例如表名、数据结构等,所以腾讯云应该也是 ClickHouse 用户之一。

    在 VictoriaLogs v1.0.0 版本发布后不久,我们发现它似乎也满足存储 Trace Span 的要求。它是为 Structured Logs 设计的,而我们前面说过,Structured Logs 和 Trace Spans 在方方面面都很相似。

    所以,我们打算在从 0 开始构建 VictoriaTraces 之前,用 VictoriaLogs 先做一次 PoC ( Proof Of Concept ,概念验证),万一它能用,万一它很好用呢?

    3. VictoriaLogs 数据模型 与 Trace Span

    在 VictoriaLogs 中,每条 Log 是由多个 Fields 组成的,包含几个特殊 Fields 以及其余的普通 Fields:

    1. Stream Fields:数据首先是按照 Stream Fields 来组织的,这可以用来缩小查询范围,它就像索引一样存在,例如 {application_name="...", env="..."}。一些高基数的 Value (例如 ipuser_idtrace_id)不适合作为 Stream Fields 存在。
    2. Time Field:每条 Log 都应该带有时间,这个 Field 同样是为减少需要扫描的数据范围而设计的。
    3. 普通 Fields:任何内容都可以以 Key-Value 的形式作为普通 Field 存在,它可以帮助优化查询。

    要将 Trace Span 存储到 VictoriaLogs 中,思路也很简单:把所有的内容都平铺为 Fields ,并在其中挑选出特定的 Fields 作为 Stream Fields 即可

    考虑到 Service NameSpan Name(在 Jaeger 中也称为 Operation Name)通常都会被用作搜索 Traces 的首要条件,并且它们也不包含高基数的 Value ,所以它们就被设计为了 Stream Fields ,其余 Span Attributes 都被平铺成普通 Fields 。

    4. Data Ingestion 性能

    我们最关注的是 VictoriaLogs 的 Data Ingestion 性能与其他竞品比起来怎么样。

    目前,热门的 Distributed Tracing 方案包括 Jaeger、Grafana Tempo。所以在测试中,我们选择了 Jaeger + ClickHouse / Jaeger + Elasticsearch / Grafana Tempo + S3 作为比较对象。

    在这个 PoC 中,对比对象均分配了 4 CPUs 及 8 GiB 内存,其余组件则按需提供足量资源保证不成为瓶颈。

    整体的测试架构非常简单:

    为了直观对比不同方案的硬件资源需求量,我们控制变量,先尝试将 Ingestion Rate 保持在 10000 spans/s。此时得到的结果如监控所示:

    题外话:为什么缺少 Jaeger + Elasticsearch 的测试结果?为什么用 10000 spans/s ?

    遗憾的是,Elasticsearch 方案在 Ingestion Rate 仅为 5000 spans/s 时就开始出现队列拥堵和 Crash ,在更高的负载下无法保持稳定,因此未能出现在最终的对比中。

    事实上,我们也在不同负载下做过多次测试,尝试让所有比较对象都能顺利完成。例如使 Tempo 数据写入本地磁盘而非对象存储,它可以通过 18000 spans/s 的测试,尽管这并不是 Tempo 的推荐使用方式。如果你对这些更为极限的测试感兴趣,请在文章下留言,或者前往 Slack 频道与我们讨论。

    在 CPU 使用率上,VictoriaLogs (50.4%) < ClickHouse (69.4%) < Tempo (135%)。同时,ClickHouse 与 Tempo 的 CPU 使用率波动更明显

    如果仅对比 VictoriaLogs 和 ClickHouse ,在负载提升至 17000 spans/s 时,ClickHouse 的 CPU 波动问题会更加突出。

    在内存用量上,**ClickHouse (14%) = VictoriaLogs (14.4%) < Tempo (53.3%)**,此时 VictoriaLogs 与 ClickHouse 的内存较为稳定,而 Tempo 使用了 4x 内存容量并且抖动明显,最终也出现了 OOM 的情况。

    在数据增长体积上,相同时间范围内 VictoriaLogs (3.27 GiB) < ClickHouse (5.86 GiB)Tempo 使用的是对象存储,根据平台提供的数据,其数据量约为 4.4 GiB,但是并不便于直观对比。因此我们在后续测试中对比了 Tempo 使用本地磁盘作为存储时的情况:

    可以看出,虽然 Tempo 使用的对象存储成本更低,但是压缩率不如 VictoriaLogs 和 ClickHouse 。如果 VictoriaLogs 能在未来支持对象存储,那将变得更有竞争力。

    题外话:问题

    你有留意到不同方案的 In/Out-Traffic 差异吗,是什么原因导致的呢?提示:

    1. Jaeger 与 ClickHouse 连接时使用了什么配置
    2. Jaeger/Tempo 的数据写入请求发送至 ClickHouse 或 S3 后会收到什么响应呢?

    以下是以 VictoriaLogs 作为基准,相同负载下各方案所需的资源对比汇总:

    5. 数据可视化

    行业中炙手可热的 OpenTelemetry 标准只定义了数据传输的协议 OTLP ,但是对于数据如何被查询和可视化并没有明确的标准,这也导致 Jaeger 、Tempo 等项目各自实现了不同的查询 APIs 。

    VictoriaLogs 目前没有提供 Trace 的可视化方案,但是为了验证 VictoriaLogs 的查询语言 LogsQL 能否覆盖 Trace 展示的所有场景,我们尝试基于 VictoriaLogs 实现 Jaeger 的 APIs 。

    题外话:为什么选择 Jaeger ?

    我们选择在 PoC 中实现 Jaeger HTTP APIs 是因为:

    1. Jaeger 项目使用广泛。
    2. Grafana 原生提供了 Jaeger Datasource 支持,意味着只要实现 Jaeger APIs ,用户可以在 Grafana 上直接将 VictoriaLogs 中的 Trace 数据可视化。

    数据可视化本质上是第 3 节内容的逆向过程,其实并不复杂。

    在实现过程中,我们发现 Time Range Filter 是对查询性能影响最大的。例如查询 trace_idc3b94b884c236e1e7ae39e7ca3589d18 的数据,因为 VictoriaLogs 并不存在 trace_id 索引,即不明确这个 trace_id 的对应的数据在什么时间范围、有多少 Spans ,所以需要扫描所有时间内符合条件的数据 Block ,而其中大量扫描是没有必要的。如果可以将时间范围限制在特定的 10 分钟、30 分钟内,整体查询都能大大提速。

    因此,使用 VictoriaLogs 作为 Trace 存储,最好可以配置特定的 Lookback Windows 。例如,配置 metadata_lookbehind=3d 使得每次加载所有 Service Name 列表时,只检索最近 3 天内出现过的 Service Name 。

    又如,trace_id_lookbehind_step=7d 在每次直接通过 trace_id 查找 Trace Span 时,按照 7 天作为步长逐步检索,如果检索到了数据,则不再去查找下一个步长内的数据了。

    实现 Jaeger APIs 后的 VictoriaLogs 既可以搭配 Jaeger UI 使用,也可以在 Grafana 上查询,响应时效较 ClickHouse 和 Elasticsearch 明显更短,说明 VictoriaLogs 也能很好胜任需要展示 Trace 的场景。

    不知道这样的 UI 对用户来说体验怎么样呢?

    6. 总结

    通过这篇文章,我们希望解答的问题是:

    1. 什么样的数据库适合用于存储 Trace Span ,为什么 VictoriaLogs 可以成为众多选择之一?
    2. Trace 数据在 VictoriaLogs 中是以怎样的形式存在的?
    3. VictoriaLogs 在 Distributed Tracing 的场景下性能有多好,与其他竞品相比如何?
    4. Trace 数据如何展示?
    5. 我们还需要 VictoriaTraces 吗?

    我想除了最后一个问题,其它 4 个问题应该在前面的章节中已经有了答案。

    如果没有更加突破性的方案(例如相同配置下实现 10 倍的数据写入量),我们应该不会单独打造 VictoriaTraces ,毕竟 VictoriaTraces over VictoriaLogs 也很酷不是么?另外,和 VictoriaMetrics 不同,VictoriaLogs 的对象存储支持已经在我们的日程中。相信 VictoriaTraces over VictoriaLogs 也会从中受益。

    考虑到 Distributed Tracing 生态中仍有许多工具缺乏好的实现,或许打造一些与采样相关的工具( vtagent?)也会是个不错的主意。

    目前,我们想要积极地听取用户对这项功能的意见。我们的初衷是提供高性能低成本架构简洁易于扩展的解决方案,这优先于其他所有目标。

    题外话:关于性能

    目前实验中的 VictoriaLogs 可以在平均 1.2 (最高 2.6 ) CPU 的资源开销下支持 30000 spans/s 的 Ingestion Rate 。由于尚未进行 Profiling 和优化,我们预计正式的 Pull Request 还有很长一段时间才能和大家见面。

    但是如果你已经迫不及待想要动手试试这个“玩具”,可以查看以下 Demo

    如果你认为这个功能可以代替你现有的 Trace 存储,想要赶紧体验一下,或者它因为什么原因不是你的菜,请务必通过评论,GitHub Issue 或者 Slack 频道告诉我们,VictoriaMetrics 团队期待在多个方面为我们的用户提供技术支持。

    7. 番外篇

    其实在更早之前,我尝试过让 VictoriaLogs 作为 Jaeger 的 gRPC Remote Storage ,出于一系列的原因,资源开销并不理想( 10x 之于 ClickHouse )。当时我的结论是 VictoriaLogs 可以存储、查询 Trace Span ,不过毫无竞争力,并且打算就此结束。

    但是 @hagen1778 和我说,现在下结论还太早,并且给了我很多的建议。相似的事情也发生在我和 @valyala 之间,我还从 @AndrewChubatiuk 及其他同事的代码中找到了许多有帮助的技巧。Thanks to these experienced engineers for saving my day 。

    7 条回复    2025-05-20 10:45:17 +08:00
    tinkerer
        1
    tinkerer  
       150 天前   1
    打算尝试一下, 感谢你们的智慧和劳动
    F281M6Dh8DXpD1g2
        2
    F281M6Dh8DXpD1g2  
       150 天前
    你要知道 clickhouse 在 ingestion 上有多少花活又放弃了多少一致性就不会这么比了
    OliverDD
        3
    OliverDD  
       149 天前   1
    @liprais #2 可以详细说说嘛?挺感兴趣的
    lrh3321
        4
    lrh3321  
       149 天前
    为什么我感觉这文章有点像是翻译腔。
    crackidz
        5
    crackidz  
       149 天前
    @lrh3321 这篇就是翻译的官方博客吧
    RedisMasterNode
        6
    RedisMasterNode  
    OP
       149 天前 via Android
    @lrh3321 @crackidz 不是翻译的...而且即将要从中文翻译回去英文...像翻译腔只是因为作者写作水平不够好..
    wsszh
        7
    wsszh  
       149 天前   1
    感谢分享,挺有意思的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5697 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 49ms UTC 06:24 PVG 14:24 LAX 23:24 JFK 02:24
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86