LabHub
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

尾部采样的策略与路由层

在 LabHub 中继续学习

目标

设计五项尾部采样策略,在其前方放置 trace ID 路由层,亲自计算缓冲区内存,并将该值应用到 Operator CR。

为什么重要

尾部采样并不是“启用后就能降低成本”的功能。由于必须等所有 span 到达后才能作出决定,从 Agent 到 Collector 的网络流量完全不会减少,减少的只有后端存储和索引。作为代价,会新增三项开销:在 decision_wait 期间保留所有 span 的内存、将同一 trace 汇集到一个实例的路由层,以及运行该层的复杂度。因此,是否采用不能凭感觉,而要通过乘法决定。将每秒 trace 数乘以等待时间得到 num_traces,再乘以 span 数和大小得到内存。如果跳过这项计算,就可能在上限不足的状态下运行;旧 trace 被强制决策后,数据会消失,而指标却不会报告任何异常。

步骤

  1. 创建 /root/otca-sampling/tailsampling.yaml,在 processors.tail_sampling 中写入 decision_wait: 30snum_traces: 300000expected_new_traces_per_sec: 10000
  2. policies 中加入两项策略:name: keep-errorstype: status_codestatus_code.status_codes 中加入 ERROR)和 name: keep-slowtype: latencylatency.threshold_ms: 800)。
  3. 添加 name: drop-healthchecks 策略。type: string_attributestring_attribute.key: http.routevalues/healthz/readyz,并设置 invert_match: true
  4. 添加 name: vip-slow 策略。其 type: and,并在 and.and_sub_policy 中放置两个子策略——一个 type: string_attribute,要求 tenant.tierenterprise;另一个 type: latency,设置 threshold_ms: 300。最后添加 name: baselinetype: probabilisticprobabilistic.sampling_percentage: 2),使策略总数达到 5 项
  5. /root/otca-sampling/loadbalancing.yaml 中编写前置路由层。在 exporters.loadbalancing 中设置 routing_key: traceIDresolver.dns.hostname 使用包含 otel-tailsampler 的服务地址;设置 resolver.dns.port: 4317service.pipelines.traces 的 Exporter 只能是 [loadbalancing],Processor 中不能加入 tail_sampling
  6. /root/otca-sampling/buffer-memory.txt 中用三行写入计算结果:num_traces_required=(10,000 trace/s × 30s)、buffer_mb=(将 10,000 × 30 × 12 span × 1.2KB 换算为 MB 后四舍五入)、buffer_mb_with_headroom=(前者的 2 倍)。每行采用无空格的 키=값 格式。
  7. 创建命名空间 otca-sampling,并在 /root/otca-sampling/collector-cr.yaml 中编写 CR。apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata.name: otel-tailsamplermetadata.namespace: otca-samplingspec.mode: deploymentspec.replicas: 3。在 spec.config 中包含第 1~4 步的 tail_sampling(原样保留五项策略),并将 spec.config.service.pipelines.traces.processors 配置为 tail_sampling 位于 batch 之前,且 batch 位于最后。

参考

tail_sampling 基本值

创建 /root/otca-sampling/tailsampling.yaml,在 processors.tail_sampling 中写入 decision_wait: 30snum_traces: 300000expected_new_traces_per_sec: 10000

decision_wait 是等待一个 trace 的所有 span 到达所留出的时间。太短会根据不完整的 trace 作出决策,太长则会导致内存激增。num_traces 来自每秒 trace 数与等待时间的乘积。

两项基于结果的策略

policies 中加入两项策略:name: keep-errorstype: status_codestatus_code.status_codes 中加入 ERROR)和 name: keep-slowtype: latencylatency.threshold_ms: 800)。

这两项策略正是尾部采样存在的理由。头部采样只能按概率获得这些 trace,而这些规则可以 100% 保留它们。每项策略都包含 name、type,以及与 type 同名的配置块。

排除健康检查

添加 name: drop-healthchecks 策略。type: string_attributestring_attribute.key: http.routevalues/healthz/readyz,并设置 invert_match: true

所有策略都表示“保留条件”。因此,要排除特定路由,需要一个反转匹配的选项。请使用按属性值列表匹配的策略类型。

and 组合策略与基础概率

添加 name: vip-slow 策略。其 type: and,并在 and.and_sub_policy 中放置两个子策略——一个 type: string_attribute,要求 tenant.tierenterprise;另一个 type: latency,设置 threshold_ms: 300。最后添加 name: baselinetype: probabilisticprobabilistic.sampling_percentage: 2),使策略总数达到 5 项

只有同时满足两个条件时才保留,需要使用组合策略。各子策略也是包含 name 和 type 的完整策略。最后,为其余 trace 添加概率策略。

前置路由层

/root/otca-sampling/loadbalancing.yaml 中编写前置路由层。在 exporters.loadbalancing 中设置 routing_key: traceIDresolver.dns.hostname 使用包含 otel-tailsampler 的服务地址;设置 resolver.dns.port: 4317service.pipelines.traces 的 Exporter 只能是 [loadbalancing],Processor 中不能加入 tail_sampling

决策层前方需要一层将同一 trace 的 span 汇集到一个实例。普通负载均衡器无法做到,必须使用以 trace ID 为键的 Exporter。此前置层不作采样决策。

计算缓冲区内存

/root/otca-sampling/buffer-memory.txt 中用三行写入计算结果:num_traces_required=(10,000 trace/s × 30s)、buffer_mb=(将 10,000 × 30 × 12 span × 1.2KB 换算为 MB 后四舍五入)、buffer_mb_with_headroom=(前者的 2 倍)。每行采用无空格的 키=값 格式。

计算方式为:每秒 trace 数 × 等待时间 × 每个 trace 的 span 数 × span 大小。将 KB 转换为 MB 时除以 1024,并对小数四舍五入。num_traces 的所需值只需相乘前两项。

OpenTelemetryCollector CR

创建命名空间 otca-sampling,并在 /root/otca-sampling/collector-cr.yaml 中编写 CR。apiVersion: opentelemetry.io/v1beta1kind: OpenTelemetryCollectormetadata.name: otel-tailsamplermetadata.namespace: otca-samplingspec.mode: deploymentspec.replicas: 3。在 spec.config 中包含第 1~4 步的 tail_sampling(原样保留五项策略),并将 spec.config.service.pipelines.traces.processors 配置为 tail_sampling 位于 batch 之前,且 batch 位于最后。

如果采用每个节点都启动实例的部署模式,同一 trace 的 span 会分散到多个节点,无法作出决策。CR 内的配置与 Collector 配置文件结构相同,Processor 顺序规则也完全适用。此环境没有 CRD,因此只需编写文件,并实际创建命名空间。