OpenTelemetry OpenTelemetry

让 Collector 达到生产就绪:内存限制、批处理与重试

配置 processor、队列和持久化存储,使遥测数据在过载和故障中存活。

12 min 中级

在笔记本电脑上能工作的 Collector 在生产环境中可能会垮掉:流量激增耗尽内存,后端故障丢失数据,或者一次重启丢失所有在途的东西。修复全都是配置。本指南涵盖每个生产 Collector 都应具备的 processor 和 exporter 设置,以及摆放它们的顺序。

基线管线

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20
  batch:
    timeout: 5s
    send_batch_size: 8192

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/backend]

顺序很重要:processor 按列出的顺序运行。memory_limiter 放在最前,这样背压能在其他任何东西消耗内存之前到达 receiver。batch 放在最后,在任何过滤或丰富之后,这样批次是由最终的数据构建的。

memory_limiter

它监视 Collector 的内存,并在使用量过高时拒绝新数据,所以进程是放慢速度,而不是被操作系统杀死。

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 4000
    spike_limit_mib: 800
  • check_interval 是多久测量一次内存。推荐值为 1s,默认值 0s 会禁用周期性检查。
  • limit_mib 是堆内存的硬限制。整个进程通常会使用稍多一些。
  • spike_limit_mib 是预期的两次检查之间的最大跳升量,默认是限制的 20%。软限制是 limit_mib 减去 spike_limit_mib(这里是 3200 MiB)。
  • limit_percentage 和 spike_limit_percentage 把同样的限制表示为可用内存的份额(使用 cgroup 的 Linux)。它们适合由 Kubernetes 设置内存限制的容器。如果同时设置了 limit_mib,则以它为准。

超过软限制时,该 processor 通过向上一个组件返回错误来拒绝数据,行为良好的发送方会重试或放慢速度。超过硬限制时,它还会强制进行垃圾回收。请把它设置得略低于容器的内存限制,使它在内核之前起作用。

batch

批处理将条目分组,使导出更少、更大,这节省网络和后端的工作。

processors:
  batch:
    timeout: 5s            # send after this long even if the batch isn't full
    send_batch_size: 8192  # target batch size
    send_batch_max_size: 0 # 0 means no upper bound

为延迟调整 timeout,为吞吐量调整 send_batch_size。较新的 Collector 版本还可以在 exporter 的队列内部进行批处理;请查看你所用版本的 exporter helper 文档。

Exporter 队列与重试

通过网络发送的 exporter 有一个发送队列和一个重试策略。它们位于 exporter 中,而不是 processor 中,正是它们保护你免受后端短暂故障的影响:

exporters:
  otlp/backend:
    endpoint: backend.example.com:4317
    sending_queue:
      enabled: true
      queue_size: 5000        # default is 1000
    retry_on_failure:
      enabled: true
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 10m   # default is 300s

如何思考这些数字:

  • 当后端缓慢或宕机时,队列缓冲批次。更大的队列能熬过更长的事故,但会使用更多内存。
  • retry_on_failure 以递增的延迟重试,直到 max_elapsed_time。之后数据会被丢弃。
  • 请根据你的流量以及你希望无损熬过的最长故障时间来确定两者的大小。

持久队列:熬过重启

默认情况下队列位于内存中,所以崩溃会丢失已排队的内容。用 file_storage 扩展让它由磁盘支持:

extensions:
  file_storage:
    directory: /var/lib/otelcol/storage

exporters:
  otlp/backend:
    endpoint: backend.example.com:4317
    sending_queue:
      storage: file_storage

service:
  extensions: [file_storage]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/backend]

需要三个部分:定义该扩展、在 exporter 中引用它,并在 service.extensions 下启用它。在该目录挂载一个持久卷,例如为 StatefulSet 挂载 PersistentVolumeClaim。如果磁盘已满或损坏,或者后端宕机时间超过重试限制,数据仍然可能丢失,所以请监控磁盘使用情况。

基础之外有用的 processor

添加或更改属性:

processors:
  resource/env:
    attributes:
      - key: deployment.environment.name
        value: production
        action: upsert
  attributes/scrub:
    actions:
      - key: http.request.header.authorization
        action: delete
      - key: user.email
        action: hash

resource 编辑描述生产者的属性(应用于整个批次),而 attributes 编辑每个 span、每个指标数据点或每条日志记录的属性。用它们添加环境标签,并在数据离开你的网络之前移除或哈希敏感值。

丢弃噪声,使用 filter processor,用 OpenTelemetry 转换语言(OTTL)书写:

processors:
  filter/health:
    error_mode: ignore
    traces:
      span:
        - 'attributes["url.path"] == "/healthz"'
        - 'attributes["url.path"] == "/ready"'

转换数据,使用 transform processor:

processors:
  transform/normalize:
    error_mode: ignore
    trace_statements:
      - context: span
        statements:
          - set(attributes["team"], "payments") where resource.attributes["service.name"] == "checkout"

OTTL 很强大,所以在把语句启用到生产环境之前,先用 debug exporter 在你数据的副本上测试它们。语句的语法和可用的上下文因版本而异,所以请查看该 processor 的 README。这些 processor 在 contrib 发行版中。

保护 Collector 本身

  • 设置 Kubernetes 资源 request 和 limit,并让 memory_limiter 低于该 limit。
  • 添加 health_check,并将其用于存活和就绪探针。
  • 监控 Collector 自己在 8888 端口上的指标,了解队列大小、丢弃的条目和被拒绝的数据。当 otelcol_exporter_queue_size 接近其容量,或 exporter 报告发送失败时发出告警。
  • 为网关在 Service 后面运行多个副本,并按你预期的突发量为单个副本定容。

检查清单

  • memory_limiter 是每条管线中的第一个 processor。
  • batch 是最后一个 processor。
  • 网络 exporter 具有按你的故障容忍度定容的发送队列和重试策略。
  • 在不能容忍数据丢失的地方配置持久队列。
  • 敏感属性在边缘被删除或哈希。
  • 健康检查、资源限制和 Collector 指标都已就位。

热门指南