OpenTelemetry Collector 的韧性:队列、持久化与故障恢复

如何配置具有韧性的 OTel Collector 流水线。

OpenTelemetry Collector 提供多种组件和配置,用于尽量减少遥测数据处理、导出过程中的数据丢失。但要构建可靠的可观测性流水线,必须理解哪些情形仍可能丢失数据,以及如何缓解这些问题。

理解 Collector 的韧性

具有韧性的 Collector 即使遇到不利条件,也能维持遥测数据流转与处理能力,使整个可观测性流水线保持运转。

Collector 的韧性主要体现在两类情况的数据处理:配置的端点——也就是 trace、metric 或 log 的目的地——不可用,以及 Collector 实例自身出现崩溃等问题。

发送队列:内存缓冲

Collector 导出器内置的最基本韧性机制是发送队列。

  • 工作方式:导出器通常包含一个发送队列,在将数据发送到下游端点之前先放入内存缓冲。如果端点可用,数据会很快通过队列。
  • 端点不可用时:如果端点因网络问题或后端重启等原因不可用,导出器就无法立即发送数据。它会将数据加入内存发送队列,而不是立即丢弃。
  • 重试机制:Collector 使用带随机抖动的指数退避,在等待一定间隔后反复尝试发送缓冲数据。默认最多重试 5 分钟。
  • 可能丢失数据的情形:
    • 队列已满:内存队列大小可配置,默认值通常为 1000 个批次或请求。如果端点持续不可用,而新数据不断到来,队列就可能填满。此后新到的数据会被丢弃,以避免 Collector 耗尽内存。
    • 重试超时:如果端点不可用的时间超过配置的最长重试时间,默认 5 分钟,Collector 会停止重试队列中最旧的数据,并将其丢弃。
  • 配置:可以在导出器设置中配置队列大小与重试行为:
exporters:
  otlp:
    endpoint: otlp.example.com:4317
    sending_queue:
      storage: file_storage
      queue_size: 5_000 # Increase queue size (default 1000)
    retry_on_failure:
      initial_interval: 5s
      max_interval: 30s
      max_elapsed_time: 10m # Increase max retry time (default 300s)

持久化存储:预写日志(WAL)

为了防止 Collector 实例自身崩溃或重启时丢失数据,可以使用 file_storage 扩展为发送队列启用持久化存储。

  • 工作方式:发送队列不再仅将数据缓冲在内存中,而是在尝试导出之前将其写入磁盘上的预写日志(Write-Ahead Log,WAL)。
  • Collector 崩溃时:如果 Collector 在队列仍有数据时崩溃,数据已经持久化到磁盘。重启后,Collector 会从 WAL 读取数据,并继续尝试将其发送到端点。
  • 可能丢失数据的情形:磁盘故障、磁盘空间耗尽,或 Collector 重启后端点不可用的时间仍超过重试限制,都可能导致数据丢失。此机制提供的保证也可能不及专用消息队列。

配置步骤:

  1. 定义 file_storage 扩展。
  2. 在导出器的 sending_queue 配置中引用该存储实例的 ID。
extensions:
  file_storage: # Define the extension instance
    directory: /var/lib/otelcol/storage # Choose a persistent directory

exporters:
  otlp:
    endpoint: otlp.example.com:4317
    sending_queue:
      storage: file_storage # Reference the storage extension instance

service:
  extensions: [file_storage] # Enable the extension in the service pipeline
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [otlp]

消息队列

若需要最高级别的韧性,尤其是在不同 Collector 层级之间——如 Agent 到 Gateway——或基础设施与供应商后端之间,可以引入 Kafka 等专用消息队列。

  • 工作方式:一个 Collector 实例(Agent)通过 Kafka exporter 将数据导出到 Kafka topic;另一个 Collector 实例(Gateway)通过 Kafka receiver 消费该 topic 中的数据。
  • 端点或 Collector 不可用时:
    • 如果消费数据的 Collector(Gateway)停机,消息会积压在 Kafka topic 中,直到达到 Kafka 保留策略的限制。只要 Kafka 可用,生产数据的 Collector(Agent)就不受影响。
    • 如果生产数据的 Collector(Agent)停机,不会有新数据进入队列,但消费者仍可处理已有消息。
    • 如果 Kafka 自身停机,生产数据的 Collector 就需要自己的韧性机制,例如发送队列,必要时配合 WAL,以缓冲发往 Kafka 的数据。
  • 可能丢失数据的情形:主要与 Kafka 自身有关,例如集群故障、topic 配置错误、数据过期;另一种情形是生产者无法将数据发送到 Kafka,且没有足够的本地缓冲。

Agent Collector 配置:生产者

exporters:
  kafka:
    brokers: ['kafka-broker1:9092', 'kafka-broker2:9092']
    topic: otlp_traces

receivers:
  otlp:
    protocols:
      grpc:

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [kafka]

Gateway Collector 配置:消费者

receivers:
  kafka:
    brokers: ['kafka-broker1:9092', 'kafka-broker2:9092']
    topic: otlp_traces
    initial_offset: earliest # Process backlog

exporters:
  otlp:
    endpoint: otlp.example.com:4317
    # Consider queue/retry for exporting *from* Gateway to Backend

service:
  pipelines:
    traces:
      receivers: [kafka]
      exporters: [otlp]

会导致数据丢失的情形

以下情况下可能丢失数据:

  1. 网络不可用且重试超时:下游端点不可用的时间超过 retry_on_failure 中配置的 max_elapsed_time。
  2. 网络不可用且队列溢出:下游端点不可用,发送队列——内存或持久化队列——在端点恢复之前达到容量上限,新数据因此被丢弃。
  3. Collector 崩溃且未持久化:Collector 崩溃或被终止,而它只使用内存发送队列,内存数据会丢失。
  4. 持久化存储故障:file_storage 扩展使用的磁盘故障或空间耗尽。
  5. 消息队列故障:Kafka 等外部消息队列发生停机或数据丢失,而生产数据的 Collector 没有足够的本地缓冲。
  6. 配置错误:导出器或接收器配置错误,导致数据无法流转。
  7. 禁用韧性机制:在配置中明确禁用了发送队列或重试机制。

防止数据丢失的建议

遵循以下建议,尽量减少数据丢失并确保遥测数据采集可靠:

  1. 始终使用发送队列:为通过网络发送数据的导出器启用 sending_queue。
  2. 监控 Collector 指标:主动监控 otelcol_exporter_queue_size、otelcol_exporter_queue_capacity、otelcol_exporter_send_failed_spans,以及对应的 metric/log 指标,尽早发现潜在问题。
  3. 调整队列大小与重试:根据预期负载、内存和磁盘资源,以及端点可接受的停机时长调整 queue_size 与 retry_on_failure。
  4. 使用持久化存储(WAL):对于不能接受 Collector 重启期间数据丢失的 Agent 或 Gateway,为发送队列配置 file_storage 扩展。
  5. 考虑消息队列:若运维开销可以接受,可使用 Kafka 等托管消息队列,获得跨网络链路的最大持久性,或解耦 Collector 各层级。
  6. 使用适当的部署模式:
    • 采用 Agent + Gateway 架构。Agent 负责本地采集;Gateway 负责处理、批处理和具有韧性的导出。
    • 将队列、WAL、Kafka 等韧性措施集中在网络跳点:Agent → Gateway,以及 Gateway → Backend。
    • 应用程序 SDK 与本地 Agent(Sidecar/DaemonSet)之间通常有可靠的本地网络,因此这段链路的韧性往往没那么关键。如果 Agent 不可用,在此处增加队列有时会对应用程序产生负面影响。

理解这些机制并采用适当配置,可以显著提高 OpenTelemetry Collector 部署的韧性,尽量减少数据丢失。

来源:OpenTelemetry 官方文档:Resiliency。原文最近更新:2026 年 1 月 14 日。© OpenTelemetry Authors,文档采用 CC BY 4.0;本页为中文翻译,代码保留原样。原文与译文均按原样提供,不作保证。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容