LabHub
学习 学习路径 课程

OTCA — OpenTelemetry 认证助理

memory_limiter 为什么排最前,batch 为什么排最后

在 LabHub 中继续学习

一句话总结

Collector 配置中,处理器在 pipeline 里的排列顺序,就是信号实际经过的处理顺序。这句话虽短,生产影响却很大:memory_limiter 放最前,batch 放最后,tail_sampling 位于 batch 前,敏感信息删除则应放在添加元数据的处理器之后

概念图: 就是信号实际经过的处理顺序 · 之后 · 无需重新部署即可改变策略。 · 把应用与后端故障隔离。

为什么需要它

SDK 直发后端也能工作,但部署 Collector 有五个理由。

  1. 无需重新部署即可改变策略。 采样率、属性过滤和保留对象都需在运行中调整;若放在应用环境变量中,就要滚动更新 20 个服务。
  2. 把应用与后端故障隔离。 后端变慢时,SDK 发送队列堆积,应用内存上升;Collector 可代为承受压力。
  3. 可以更换后端。 按信号使用不同目的地或并行运行两个后端,都只需改一处配置。
  4. 在应用外删除敏感信息。 令牌或邮箱混入属性的事故一定会发生。有 Collector 防线后,响应方式是改配置而非重新部署。
  5. 可以尾部采样。 根据追踪结果作决定,需要把 span 汇集到一处,而这个位置不能是应用。

工作原理

配置有六个顶层区段:receiversprocessorsexportersconnectorsextensionsservice。关键是,在前五处只定义组件并不会启用它;必须在 service.pipelines 中引用(扩展在 service.extensions),它才真正工作。配置全写完却毫无效果的事故,有一半源自这里。

connectors 把一个 pipeline 的输出接到另一个 pipeline 的输入。从 trace 生成 RED 指标的 spanmetrics 是典型例子。它既是 exporter 又是 receiver,因此拥有独立区段。

逐项看顺序造成的差异

Collector pipeline 的顺序及原因——memory_limiter 必须最先,在解析前拒绝并向上游施加 backpressure;删除与哈希必须位于添加元数据的 k8sattributes 之后;tail_sampling 必须位于 batch 前以免同一 trace 的 span 分散;batch 位于最后

memory_limiter 的取值有常用惯例。

容器内存 limit_mib spike_limit_mib GOMEMLIMIT
1Gi 820 164 656MiB
2Gi 1638 328 1310MiB
4Gi 3276 655 2621MiB

limit_mib 约为容器上限的 80%,spike_limit_mib 为其 20%。若 limit_mib 高于容器上限,处理器介入前内核就会杀死进程。

batch 的常见错误是把 send_batch_size 当成上限。它只是“积累到该数量就立即发送”的触发值,真正上限是 send_batch_max_size。不指定后者,批次可能远大于预期。

现场会遇到的情况

症状分三类。

完全没有数据进入。 临时添加 debug exporter,先确认是否到达 receiver。接收指标为 0,表示应用尚未发送或地址错误;最常见原因是写反 gRPC 与 HTTP 端口。

数据进入了,后端却没有。 先看发送失败指标;没有失败仍消失,则看队列和拒绝指标。tail_sampling 经常是原因。策略过于激进时,数据正常发送,但后端只缺某些 trace,且指标完全不报异常。暂时从 pipeline 移除它再复现,是最快区分法。

周期性退出。 多半是内存压力。已有 memory_limiter 仍退出,应怀疑其上限与容器限制不匹配。

自身指标分三阶段读取:接收看 otelcol_receiver_accepted_spansotelcol_receiver_refused_spans;处理比较 otelcol_processor_incoming_itemsoutgoing_items;发送看 otelcol_exporter_sent_spanssend_failed_spansenqueue_failed_spans,以及 queue_sizequeue_capacity 比率。若只能设一个告警,就选择队列指标。 队列持续贴近容量后,接下来几乎总是拒绝与丢失。

下一实验要做什么

从头编写 /root/otca-collector/config.yaml:OTLP receiver 的两个端口、按容器上限 80% 设置的 memory_limiter、Kubernetes 元数据附加、敏感属性删除与哈希、同时指定触发值和上限的 batch、启用队列和重试的 exporter、health_check 与 zpages 扩展,以及遵守处理器顺序的三个 pipeline。