分布式调用链存储架构对比:Jaeger、Tempo、SkyWalking 与商业方案

调用链(Distributed Tracing)存储是可观测性体系中技术分歧最大的领域之一。不同于时序和日志有相对收敛的存储模式(TSDB 与 ClickHouse-like),调用链系统的存储方案因索引策略的根本分歧而分化为三条路径。

本章逐一分析 Jaeger、Grafana Tempo、Apache SkyWalking、Zipkin 以及 Datadog/Splunk 商业方案的存储架构,最后进行横向对比。

新手类比:调用链就像快递物流追踪——每个包裹(请求)经过每个分拣中心(服务)都会产生一条签收记录(span),快递单号(trace_id)把所有记录串在一起。查一下单号,就能看到包裹从发货到签收的完整路径。

区别在于:调用链的 “快递单号” 是 128 位的 trace_id,每个服务还会加上自己的 “内部工单号”(span_id)。下方动画展示 trace 上下文如何在服务间传播:

W3C TraceContext:trace_id 在服务间传播服务节点traceparent 请求头Gateway(入口网关)traceparent: 00-abc123def456-0001-01生成 trace_id: abc123def456Service A(订单服务)traceparent: 00-abc123def456-0002-01trace_id 不变,生成 span_id: 0002Service B(支付服务)traceparent: 00-abc123def456-0003-01trace_id 不变,生成 span_id: 0003Database(数据存储)traceparent: 00-abc123def456-0004-01trace_id 不变,生成 span_id: 0004一个请求 = 一个 trace_id → 多个服务 = 多个 spanspan 通过 parent_span_id 串联成调用链树——这就是分布式追踪的核心

动画说明:上方动画循环展示一个请求从 Gateway 穿透到 Database 的全过程。每个节点收到请求后,保持相同的 trace_id(快递单号不变),但生成新的 span_id(自己的签收记录)。traceparent 请求头携带这些信息在服务间传递。所有 span 收集后,通过 parent_span_id 串联成完整的调用链树——实现端到端请求可视化。

Jaeger

Jaeger 是 CNCF 毕业项目,Uber 开源,作为 OpenTelemetry 的参考实现之一,在调用链领域有着广泛影响力。

Span/Trace 数据模型

Jaeger 的 TraceID 在数据模型层是 16 字节序列,有多种表示形式[J2]:UI 层 hex 字符串(128 位时 32 字符)、Go domain model 一对无符号 64 位整数(big-endian)、Protobuf model byte 序列。

Span 模型包含:traceId、spanId、parentSpanId、operationName、startTime、duration、tags、logs、process(service/tags)、references(follows-from / child-of)[J4]

底层存储结构与索引设计

Jaeger 后端的核心权衡体现在两条路径[J2]

Cassandra 路径(KV 存储 + 客户端索引):单条 span 写入本身快,但 Jaeger 必须在 KV 之上自行实现搜索能力 → 写放大严重:除写 span 本身一条记录外,还要为 service name、operation name 各写一条索引,并且 每个 tag 都要额外写一条索引

Elasticsearch/OpenSearch 路径(倒排索引):写一条 span 即一次写,所有索引在 ES 节点内部完成。搜索能力强、结果一致、可被 Kibana 直接查询做聚合分析。

官方明确推荐 ES/OpenSearch 优于 Cassandra,理由即上述搜索能力与写放大[J2]

支持的存储后端[J1][J3]:Cassandra 4.x/5.x、Elasticsearch 7.x/8.x、OpenSearch 1.0+、ClickHouse(经 Remote Storage API 认证)、Badger(嵌入式)、memory(测试)、Kafka(仅作缓冲)。

采样机制(核心特色)

Jaeger 客户端实现一致性的头采样(upfront/head-based):根服务做决策并随请求传播,保证整条 trace 的 spans 要么全采要么全不采[J6]

客户端采样器类型[J6]:const(全采/全不采)、probabilistic(概率,默认 0.001 = 0.1%)、ratelimiting(漏桶)、remote(默认,向 agent/collector 拉取策略)。

自适应采样(v1.27+)[J6]:Collector 观察收到的 spans,按 service/endpoint 组合重算采样概率,使采集量匹配 --sampling.target-samples-per-second

注意:Jaeger 没有原生的尾采样(tail-based)能力,这是其相对 OTel Collector / Splunk 的明显局限。

拓扑分析

Dependencies 页面在内存存储时按需计算;分布式存储下太贵,需跑离线作业——旧的 spark-dependencies(周期性 Spark)或新的实验性 jaeger-analytics(Flink 流式持续构建)[J2]


Grafana Tempo

Tempo 是 Grafana Labs 推出的调用链存储系统,设计哲学与 Loki 一脉相承。

设计哲学:只索引 TraceID(类 Loki 理念)

Tempo 的核心理念与 Loki 一脉相承:不对 trace 内容建倒排索引,只索引 TraceID,trace 内容以压缩 block 存对象存储[T7][T24]。这把"索引成本"从海量属性压缩到单一 TraceID 上,据 designround 二级估算可降低约 100× 成本(官方未公布精确数字),实现"无限保留"[T24]

微服务架构与组件

Tempo 所有组件编译进同一二进制,用 -target 控制启动哪个,支持单体/微服务两种模式[T7]

写路径架构

mermaid
flowchart TD
    A[Distributor] --> B[Kafka]
    B --> C[Block-builder]
    C --> D[ObjectStorage]
    B --> E[Metrics-generator]
    E --> F[Mimir/Prometheus]
    style A fill:#2196F3,color:#fff
    style B fill:#FF9800,color:#fff
    style C fill:#9C27B0,color:#fff
    style D fill:#4CAF50,color:#fff
    style E fill:#9C27B0,color:#fff
    style F fill:#4CAF50,color:#fff

Tempo 写入路径包含 6 个关键组件:Distributor 接收多格式 spans 并做 TraceID 哈希分片,写入 Kafka 作为持久 WAL;Block-builder 消费 Kafka 按时间窗组织 blocks 送对象存储;Metrics-generator(可选)从 trace 派生 RED 指标写回 Prometheus/Mimir。

读路径架构

mermaid
flowchart TD
    A[Querier] --> B[ObjectStorage]
    A --> C[Live-store]
    D[Kafka] --> C
    style A fill:#2196F3,color:#fff
    style B fill:#4CAF50,color:#fff
    style C fill:#FF9800,color:#fff
    style D fill:#FF9800,color:#fff

读路径中,Live-store 消费 Kafka 提供约近 30 分钟~1 小时的实时数据查询;Querier 同时在对象存储 block 与 live-store 中查找 trace,利用 bloom filters 和 index 高效定位。

关键组件详解[T7]

  • Distributor:接收 spans(支持 Jaeger/OTLP/Zipkin 格式),按 traceID 哈希分片,写 Kafka。仅当 Kafka 确认后才向客户端 ACK[T7]
  • Kafka 兼容系统:作为 distributor 与下游间的持久 WAL,解耦读写路径[T7]
  • Block-builder:消费 Kafka partition,按可配置时间窗组织 spans 成 block,送对象存储[T7]
  • Live-store(读路径):消费 Kafka 提供近期数据查询(约最近 30min~1h)[T7]
  • Querier:在对象存储 block 与 live-store 中查找,用 bloom filters 和 index 高效定位 block 内 trace[T7][T29]
  • Metrics-generator(可选):从 trace 派生 RED 指标和服务图,写 Mimir/Prometheus[T7][T12]

Block 结构与 Parquet 存储格式

Tempo 2.0 起 Apache Parquet 列式格式成为默认[T8]。一个 block 是对象存储里的一个目录[T9]

文件用途
meta.jsonblock 元数据(时间范围、tenant、block ID)
data.parquet列式 trace 数据
Bloom filters概率数据结构,高效 TraceID 查找(默认 false_positive 0.01)
IndexTraceID → data.parquet 中 row group 的映射

Schema 设计:面向 span 的高度嵌套 Parquet schema[T9]

  • Intrinsic 字段(顶层列):trace ID、span ID、parent span ID、span name、span kind、duration 等,查询始终高效
  • 通用属性:其余 resource/span 属性存于通用 Attrs 列(key-value),查询需扫描属性 map,较慢
  • 专用列(Dedicated columns):可把高频查询属性提升为独立 Parquet 列以加速[T9][T30]

TraceQL 查询语言(2.0+)

TraceQL 是类 PromQL/LogQL 的 trace 查询语言[T13][T8]{} 始终从当前 trace 选择一组 spans,如 { span.http.status_code = 500 }[T15]。Parquet 列式存储使 TraceQL 只需读取相关列,大幅减少 IO[T9]


Apache SkyWalking

SkyWalking 是 ASF 顶级项目,以其丰富的分析能力和实时拓扑计算在 Java 生态中广泛应用。

OAP(Observability Analysis Platform)架构

mermaid
flowchart TD
    A[Probes] --> B[OAP<br/>Receiver + Aggregator]
    B --> C[流式处理]
    B --> D[批处理]
    C --> E[Storage]
    D --> E
    E --> F[UI]
    style A fill:#2196F3,color:#fff
    style B fill:#9C27B0,color:#fff
    style C fill:#2196F3,color:#fff
    style D fill:#2196F3,color:#fff
    style E fill:#4CAF50,color:#fff
    style F fill:#FF9800,color:#fff

SkyWalking 逻辑分四部分:Probes(探针)、Platform backend(OAP)、Storage、UI[SW16]。OAP 是核心大脑,兼具 Receiver 与 Aggregator 角色,完成接收、清洗、分析、聚合、存储、查询[SW17]。探针(蓝色)上报数据给 OAP(紫色),OAP 内部通过流式处理和批处理两道流程加工数据后写入存储(绿色),最终由 UI(橙色)查询展示。

OAP 两大核心流程[SW17]

  • 流式处理:实时接收 Agent 上报原始数据,解析链路模型,生成服务拓扑、实时指标、调用关系
  • 批处理:按时间维度对历史数据聚合,生成小时级/天级指标

分析规则用三种 DSL 定义:OAL(trace/metrics 聚合规则)、MAL(metrics)、LAL(log)[SW18]。OAP 默认架构 不引入 MQ[SW16]

Segment 数据模型(关键概念)

Segment 是 SkyWalking 独有概念[SW19]:一个 segment 包含 单个 OS 进程内一次请求的所有 spans。跨进程时,每个进程产生一个独立 segment,通过 reference 串联成完整 trace。

三种 Span 类型[SW19]

  • EntrySpan:服务提供方/服务端端点
  • LocalSpan:不涉及远程服务的普通方法
  • ExitSpan:服务客户端/MQ producer(如 JDBC 访问 DB、读 Redis)

拓扑图计算与端点级度量

  • 拓扑:OAP 用 STAM 流式拓扑分析法,从 ExitSpan 的 peer 地址与 reference 实时构建 service/instance/endpoint 间的依赖关系[SW18][SW19]。这是相对 Jaeger/Zipkin 离线作业的显著优势(实时拓扑)
  • 端点级度量:OAL 分析 trace span,按 endpoint 聚合 QPS、P99、成功率等 RED 指标[SW17][SW18]

存储后端与 BanyanDB

可插拔存储接口,支持 Elasticsearch、BanyanDB、MySQL、H2、TiDB[SW16]BanyanDB 是 SkyWalking 团队自研的专用存储[SW20]

BanyanDB 数据模型层级[SW14]:数据组织为 group 内的 streams、measures、traces、properties。

  • Measure:时序数据点序列,支持 GORILLA 编码 + ZSTD 压缩。entity 定义唯一时间序列
  • Trace专为分布式追踪设计——按 trace ID 分组 spans,每个 span 一个数据点,需指定 trace_id_tag_namespan_id_tag_nametimestamp_tag_name
  • TopNAggregation:在写入阶段预计算 Top/Bottom N 实体[SW14]

索引机制[SW14]:三种索引结构:

  • INVERTED(倒排):适合 measure tag,查询性能好
  • SKIPPING(跳表/跳过索引):多数 stream tag,优先空间利用
  • TREE(树索引)专为 trace 设计,用用户可控的 int64 排序键(如 duration、timestamp)存树索引

Zipkin

Zipkin 是 Twitter 开源的最早的调用链系统之一,其数据模型影响深远(B3 传播协议广泛被 Jaeger/SkyWalking 参考)。

架构与 Span 数据模型

Zipkin 四大组件[Z23]:collector、storage、search(query service)、web UI。Tracer 在应用内记录 timing/metadata,只 in-band 传播 ID,out-of-band 异步上报 span。

Span 模型比 Jaeger/SkyWalking 更精简[Z23][Z24]:核心字段 traceId、id(spanId)、parentId、name、timestamp、duration、annotations(带 endpoint 的时序事件)、tags。用 B3 头(X-B3-TraceId / X-B3-SpanId)传播。

存储后端

最初为 Cassandra 构建(Twitter 内部),后插件化[Z23]:Cassandra(可扩展、schema 灵活、高写吞吐、原生 TTL)、Elasticsearch(查询强、支持复杂分析)、MySQL/Postgres(结构化、易维护,仅中小型/测试用)。

依赖图存储与计算

与 Jaeger 类似,Zipkin 不在存储中实时维护依赖图,而是用 zipkin-dependencies Spark 作业离线聚合:从 spans 提取 parent→child 服务调用关系,聚合成 DependencyLink[Z23]。这是与 SkyWalking 实时拓扑的关键差异。


商业方案(Datadog/Splunk)

Datadog:头采样 + 15 分钟全量 + 15 天智能保留

数据量级洞察[D21]:Datadog 对客户群的调研显示,未采样 trace 量约为日志量的 5 倍,采样后仍为日志量的 2 倍

采样哲学[D21]:坚持头采样,决策在 trace 开始做出,通过 trace context 传播。据 Datadog 公开架构博客,默认目标 10 trace/s(DD_APM_MAX_TPS,公开技术 docs 未明确此默认值)。

存储/保留分层[D21][D22]

  • Live Search(15 分钟滚动窗口):可查询最近 15 分钟内所有已 ingest 的 spans(100% 全量,无需索引)
  • 15 天索引保留:超出 15 分钟需通过 retention filters 索引 spans
  • Intelligent Retention Filter:diversity sampling(多样性采样)+ 1% flat sampling(1% 扁平采样)

Trace Metrics(RED)[D21]:基于 100% 应用流量计算 rate/error/duration 指标(非采样)——即"指标全量、trace 采样"的混合策略。

Splunk APM:100% 全量无采样

Splunk 宣称 100% 全量存储 traces(产品页措辞,未在技术 docs 给出独立验证)[D25][D26]:不采样,存储全量 trace,使工程师可回溯查询任意 trace(对间歇性故障,万分之一出现的请求也能查)。

  • Trace Analyzer:基于 100% trace,按任意 tag 值/错误/延迟组合搜索任意 trace[D26]
  • Tag Spotlight:识别问题 trace 的共性
  • AlwaysOn Profiling:持续监控 Java/.NET/Node.js 的 CPU/内存,把代码级热点与具体 trace 关联[D25]

VictoriaTraces

定位:基于 VictoriaLogs 的调用链存储

VictoriaTraces 是 VictoriaMetrics 团队开发的调用链数据库,基于 VictoriaLogs 构建[VT1][VT2]。核心设计思路:将 OTLP 协议收到的 span 数据转化为结构化日志,复用 VictoriaLogs 的高效列式 LSM-Tree 引擎。对外兼容 Jaeger Query Service JSON API,可直接接入 Grafana 的 Jaeger 数据源[VT3]

架构模式

单机模式:单一二进制 victoria-traces-prod,同时负责 ingestion、存储和查询,Kubernetes 中以 StatefulSet 部署。

集群模式由三个独立组件构成[VT4]

组件职责
vtinsert接收 OTLP trace span,按 trace ID 哈希均匀分发到各 vtstorage 节点
vtstorage存储 trace span 于本地磁盘,处理来自 vtselect 的查询请求
vtselect接收用户查询,分发到各 vtstorage 并聚合结果后返回

组件间通过 HTTP 通信:vtinsert → vtstorage 使用 POST /internal/insertvtselect → vtstorage 使用 GET /internal/select/*

数据模型:Span 即日志

VictoriaTraces 不定义专有 trace 存储格式,而是将 OTLP span 拍平为结构化日志[VT3]

字段类别示例说明
时间戳_time默认使用 EndTimeUnixNano
流标签_stream{resource_attr:service.name="payment", name="tcp.connect"}
Trace 标识trace_id, span_id, parent_span_id调用链关联
Resource 属性resource_attr:service.nameOTLP Resource 拍平展开
Span 属性span_attr:http.status_codeOTLP Span Attributes 拍平展开
计算字段durationingestion 时自动计算

这种设计的核心优势:所有字段自动建立全文索引,无需预定义索引 schema——相比 Tempo 需要手动配置专用列才能加速属性查询,VictoriaTraces 使用体验更接近日志搜索引擎。

写入路径

mermaid
flowchart TD
  A["OTLP Spans<br/>gRPC / HTTP"] --> B["vtinsert<br/>按 Trace ID 分片"]
  B --> C["vtstorage<br/>转结构化日志"]
  C --> D["VictoriaLogs<br/>列式 LSM-Tree"]
  D --> E["本地磁盘<br/>per-day 分区"]

写入流程详解

  1. 数据接收:通过 OTLP/gRPC 或 OTLP/HTTP 端点接收 span 流
  2. Trace ID 分片:vtinsert 按 trace_id 哈希将 span 分发到对应 vtstorage 节点,保证同一 trace 的所有 span 落在同一节点
  3. 数据转换:vtstorage 将 OTLP span 拍平为结构化日志——resource attributes 展开为 resource_attr:*,span attributes 展开为 span_attr:*,并自动计算 duration
  4. 列式写入:经由 VictoriaLogs 的 LSM-Tree 引擎写入本地磁盘,按天分区存储。与 VictoriaMetrics 不同,VictoriaTraces 目前暂不支持对象存储[VT6]

查询路径

mermaid
flowchart TD
  A["Grafana<br/>Jaeger 数据源"] --> B["vtselect<br/>分发查询"]
  B --> C["vtstorage<br/>LogsQL 检索"]
  C --> D["VictoriaLogs<br/>全文索引扫描"]
  D --> E["跨节点<br/>结果合并"]
  E --> F["返回 Trace<br/>Waterfall 视图"]

两层查询接口[VT5]

  1. Jaeger 兼容 API/select/jaeger/api/traces/{trace_id} — 按 trace ID 精确查询,同时提供服务列表、操作列表、服务依赖图等 Jaeger 原生 API
  2. LogsQL 查询接口/select/logsql/query — 使用 LogsQL 对所有 span 字段进行全文搜索,支持包括 span 属性在内的任意字段过滤

LogsQL 示例:

logsql
1
resource_attr:service.name="payment" AND span_attr:http.status_code>=500

性能对比

官方在 10,000 spans/s(4 CPU, 8 GiB RAM)下的对比测试[VT6]

指标VictoriaTracesGrafana TempoClickHouse
CPU 使用0.50 vCPU1.35 vCPU0.69 vCPU
内存使用1.15 GiB4.26 GiB1.12 GiB
磁盘使用3.27 GiB~4.4 GiB5.86 GiB

在 30,000 spans/s 高负载下,VictoriaTraces 相比 Tempo 节省 3.7x 内存和 2.6x CPU[VT6]。Docker 镜像仅 15.1 MB,无任何外部依赖。

与主流方案对比

维度VictoriaTracesGrafana TempoJaeger(Elasticsearch)
存储引擎VictoriaLogs(列式 LSM-Tree)对象存储 + ParquetElasticsearch 倒排
查询语言LogsQL + Jaeger APITraceQL无(API-only)
外部依赖无(裸二进制)对象存储(S3/GCS)Elasticsearch / Cassandra
资源效率极高(3.7x < Tempo)低(写放大)
部署复杂度低(单二进制 / 三组件)中(多组件 + 对象存储)中(多组件 + ES 运维)
成熟度预览版(v0.9.3)稳定版稳定版

调用链横向对比

索引策略对比(核心分歧)

mermaid
flowchart TD
    A[调用链索引策略] --> B[全倒排索引派<br/>搜索灵活成本高]
    A --> C[只索引 TraceID 派<br/>成本极低]
    A --> D[混合派<br/>平衡搜索与成本]
    A --> E[全文索引派<br/>VictoriaTraces]
    style A fill:#FF9800,color:#fff
    style B fill:#f44336,color:#fff
    style C fill:#4CAF50,color:#fff
    style D fill:#9C27B0,color:#fff
    style E fill:#795548,color:#fff

调用链存储的索引策略可分为四大流派:全倒排索引派(红色)以 Jaeger/ES、Zipkin/ES、Datadog、Splunk 为代表,搜索灵活但索引成本高;只索引 TraceID 派(绿色)以 Tempo 为代表,成本极低但 TraceID 以外的搜索需依赖列式扫描;混合派(紫色)以 SkyWalking BanyanDB 的多索引结构和 Datadog 的分层保留为代表;全文索引派(棕色)以 VictoriaTraces 为代表,基于 VictoriaLogs 全文索引,所有字段自动索引无需预定义 schema。

  • 全倒排索引派:Jaeger(ES)、Zipkin(ES)、Datadog/Splunk — 搜索灵活但成本高、写放大
  • 只索引 TraceID 派:Tempo — 成本极低、TraceID 查询快、内容搜索靠列式扫描 + TraceQL
  • 混合派:SkyWalking(BanyanDB INVERTED+SKIPPING+TREE 多索引,trace 专用 TREE)、Datadog(近期全量 + 远期选择性索引)
  • 全文索引派:VictoriaTraces — 基于 VictoriaLogs 全文索引,所有字段自动建立索引,无需预定义 schema,按需全文搜索任意属性

采样策略对比

项目头采样尾采样自适应
Jaeger✅(默认 remote)✅(v1.27+,按 endpoint)
Tempo❌(后端全收)
SkyWalking✅(agent 端)
Zipkin✅(客户端)
Datadog✅(默认 10 trace/s)部分支持
Splunk❌(全量不采样)
VictoriaTraces❌(依赖 OTel Collector 采样)

Jaeger 采样流程示意

mermaid
sequenceDiagram
    participant RS as RootService
    participant C as Collector
    participant A as Agent
    participant DS as DownstreamService
    RS->>RS: 决策采样
    RS->>DS: 传播 trace context
    DS->>DS: 继承采样决策
    DS->>C: 上报 spans
    C->>C: 自适应调整
    C->>A: 回推策略
    A->>RS: 更新采样策略
    Note over RS,DS: 头采样保证整条 trace 一致性

Jaeger 的采样流程展示了头采样的完整生命周期:根服务(RootService)在请求入口做出采样决策,通过 trace context 传播给下游服务(DownstreamService),下游继承同一决策保证整条 trace 的一致性。Collector 接收上报后按 service/endpoint 组合进行自适应调整,并通过 Agent 回推更新采样策略。

容量估算参考[T24]

5M spans/s 采样前 → 500K spans/s 采样后(10%)→ 250 MB/s 摄入 → 21.6 TB/天(原始 JSON)→ ClickHouse 列式压缩 5-10x 后约 3 TB/天 → 14 天约 300 TB(原始)/ ~40 TB(压缩)。


来源

[J1] Jaeger Features. https://www.jaegertracing.io/docs/1.57/features/

[J2] Jaeger Architecture. https://www.jaegertracing.io/docs/1.57/architecture/

[J3] Jaeger CLI / Storage Backends. https://www.jaegertracing.io/docs/1.57/cli/#storage-backends

[J4] Jaeger Data Model. https://www.jaegertracing.io/docs/1.57/data-model/

[J6] Jaeger Sampling. https://www.jaegertracing.io/docs/1.57/sampling/

[T7] Tempo Architecture. https://grafana.com/docs/tempo/latest/operations/architecture/

[T8] Tempo 2.0 Release. https://grafana.com/blog/2023/03/07/grafana-tempo-2.0-is-here/

[T9] Tempo Parquet Design. https://grafana.com/docs/tempo/latest/operations/parquet/

[T12] Tempo Metrics-generator. https://grafana.com/docs/tempo/latest/metrics-generator/

[T13] TraceQL Documentation. https://grafana.com/docs/tempo/latest/traceql/

[T15] TraceQL Examples. https://grafana.com/docs/tempo/latest/traceql/examples/

[T24] Grafana Labs Keynote / Tempo Capacity Estimate. https://grafana.com/blog/2021/09/22/grafana-tempo-1.0/

[T29] Tempo Bloom Filters. https://grafana.com/docs/tempo/latest/operations/bloom-filters/

[T30] Tempo Dedicated Columns. https://grafana.com/docs/tempo/latest/operations/dedicated-columns/

[SW14] BanyanDB Data Model. https://skywalking.apache.org/docs/main/latest/en/setup/backend/banyandb/

[SW16] SkyWalking Architecture. https://skywalking.apache.org/docs/main/latest/en/concepts-and-designs/overview/

[SW17] SkyWalking OAP. https://skywalking.apache.org/docs/main/latest/en/setup/backend/oap/

[SW18] SkyWalking OAL. https://skywalking.apache.org/docs/main/latest/en/concepts-and-designs/oal/

[SW19] SkyWalking Segment Model. https://skywalking.apache.org/docs/main/latest/en/concepts-and-designs/segment/

[SW20] BanyanDB Overview. https://skywalking.apache.org/docs/main/latest/en/setup/backend/banyandb/

[Z23] Zipkin Architecture. https://zipkin.io/pages/architecture.html

[Z24] Zipkin Span Model. https://zipkin.io/zipkin-api/#/default/get_trace__traceId_

[D21] Datadog APM Trace Sampling. https://docs.datadoghq.com/tracing/guide/trace_sampling_and_storage/

[D22] Datadog Intelligent Retention. https://docs.datadoghq.com/tracing/trace_retention/

[D25] Splunk APM AlwaysOn Profiling. https://www.splunk.com/en_us/observability/apm.html

[D26] Splunk APM Trace Analyzer. https://docs.splunk.com/observability/en/apm/traces/trace-analyzer.html

[VT1] [官方] VictoriaTraces overview: https://docs.victoriametrics.com/victoriatraces/

[VT2] [官方] VictoriaTraces GitHub: https://github.com/VictoriaMetrics/VictoriaTraces

[VT3] [官方] VictoriaTraces key concepts: https://docs.victoriametrics.com/victoriatraces/keyconcepts/

[VT4] [官方] VictoriaTraces cluster: https://docs.victoriametrics.com/victoriatraces/cluster/

[VT5] [官方] VictoriaTraces querying: https://docs.victoriametrics.com/victoriatraces/querying/

[VT6] [官方] VictoriaTraces benchmark (distributed tracing with VictoriaLogs): https://victoriametrics.com/blog/dev-note-distributed-tracing-with-victorialogs/

[VT7] [官方] VictoriaTraces data ingestion: https://docs.victoriametrics.com/victoriatraces/data-ingestion/