使用OpenTelemetry Collector规划可观测性流水线时,应考虑随着遥测采集量增加,如何扩展整条流水线。
下面各节将帮助你完成规划:讨论哪些组件需要扩展、如何判断扩展时机,以及如何执行扩展计划。
扩展什么
虽然OpenTelemetry Collector在一个二进制程序中处理所有遥测信号类型,但各种信号的扩展需求可能不同,需要不同的扩展策略。首先分析工作负载,确定哪类信号预计占据最大负载,以及Collector将接收哪些格式。例如,扩展抓取集群与扩展日志接收器有很大不同。
还要考虑工作负载的弹性:一天中的特定时段是否有高峰,还是24小时负载相似?收集这些信息后,就能知道需要扩展什么。
例如,假设你需要抓取数百个Prometheus端点,每分钟接收来自fluentd实例的1 TB日志,并从最新微服务接收OTLP格式的应用指标与链路。在这种情况下,需要一种能分别扩展各类信号的架构:扩展Prometheus接收器时,抓取器之间必须协调,确定每个抓取器负责哪个端点。
相比之下,无状态日志接收器可以按需水平扩展。将接收指标与链路的OTLP接收器放在第三个Collector集群中,可以隔离故障,并更快迭代,不必担心重启繁忙的流水线。由于OTLP接收器支持所有遥测类型,可以将应用指标和链路保留在同一实例中,在需要时水平扩展。
何时扩展
同样,应先理解工作负载,再决定何时扩容或缩容。不过,Collector发出的某些指标能为采取行动的时机提供线索。
当流水线使用memory_limiter处理器时,otelcol_processor_refused_spans是一个有用指标。这个处理器限制Collector可使用的内存。实际内存占用可能略高于配置的上限,但最终memory_limiter会阻止新数据继续通过流水线,并通过该指标记录拒收情况。
其他遥测类型也有对应指标。如果数据过于频繁地被拒绝进入流水线,通常应考虑扩容Collector集群。当各节点内存占用显著低于处理器配置的上限时,可以缩容。
另一组需关注的指标是导出器队列相关的otelcol_exporter_queue_capacity与otelcol_exporter_queue_size。等待可用工作线程发送数据期间,Collector会在内存中排队。如果工作线程不足,或后端太慢,数据就会在队列中堆积。
队列达到容量后(原文写为otelcol_exporter_queue_size > otelcol_exporter_queue_capacity),会拒绝数据,并记录otelcol_exporter_enqueue_failed_spans。增加工作线程通常能让Collector导出更多数据,但这未必是你希望的结果,参见下文“何时不应扩展”。
一般建议监控队列大小,达到容量的60%–70%时考虑扩容;若持续很低则考虑缩容,同时保持最低副本数,例如3个,以确保韧性。
还应熟悉准备使用的组件,因为不同组件可能发出其他指标。例如,负载均衡导出器会记录导出操作的耗时,并通过直方图otelcol_loadbalancer_backend_latency暴露。
可以据此判断各后端处理请求的耗时是否接近:单个后端变慢,可能意味着Collector之外的问题。
对于Prometheus接收器这类执行抓取的接收器,如果抓取所有目标所需时间经常逼近抓取间隔,就应扩展或分片抓取任务。此时需要增加抓取器,通常就是新增Collector实例。
何时不应扩展
理解哪些迹象意味着扩展不会带来好处,可能与知道何时扩展同样重要。例如,遥测数据库无法承受负载时,如果不扩展数据库,向集群加入更多Collector也无济于事。同样,Collector与后端之间的网络连接饱和时,增加Collector可能带来有害的副作用。
一种识别方式仍是观察otelcol_exporter_queue_size与otelcol_exporter_queue_capacity。队列大小持续接近容量,说明导出数据比接收数据慢。可以尝试增大队列容量,这会增加Collector内存消耗,但也能为后端争取缓冲空间,避免永久丢弃遥测数据。
不过,如果不断增大容量,队列大小也以相同比例持续上升,就应排查Collector以外的环节。此时增加工作线程也不会有帮助,只会让已经承受高负载的系统压力更大。
另一个后端可能有问题的迹象是otelcol_exporter_send_failed_spans增大,表示向后端发送数据永久失败。如果这种情况持续发生,扩容Collector很可能只会恶化局面。
如何扩展
至此,我们已知道流水线中哪些部分需要扩展。从扩展角度看,组件可分为三类:无状态组件、抓取器和有状态组件。
大多数Collector组件都是无状态的。即使它们在内存中保存某些状态,这些状态也不影响扩展。
Prometheus接收器等抓取器通过配置从外部位置获取遥测数据,然后逐个抓取目标,将数据放入流水线。
尾部采样处理器等组件会保存与业务处理有关的重要内存状态,因此不能简单扩展。扩容这些组件之前必须仔细考虑。
扩展无状态Collector并使用负载均衡器
好消息是,大多数情况下扩展Collector很简单:增加副本,再通过负载均衡器将流量分配到各副本即可。
需要实现以下目标时,负载均衡器必不可少:
- 将传入遥测流量分发到多个无状态Collector实例,避免单个实例过载。
- 提高采集流水线的可用性和容错能力;实例故障时,将流量转向健康实例。
- 按需求水平扩展Collector层。
在Kubernetes环境中,可以使用Istio、Linkerd等服务网格,或云厂商负载均衡器提供的成熟负载均衡与限流方案。它们往往提供超越基本负载分发的流量管理、韧性和可观测性功能。
使用gRPC接收数据时——OTLP常见的场景——应使用理解gRPC的L7负载均衡器。普通L4负载均衡器可能与某一个后端Collector维持持久连接,使客户端总是访问同一个实例,抵消扩容的收益。划分采集流水线时仍应考虑可靠性。
例如,工作负载运行在Kubernetes中时,可通过DaemonSet在同一物理节点上部署Collector,并让远程中央Collector在数据送入存储前负责预处理。节点较少而Pod较多时,Sidecar可能更合适:无需专用gRPC负载均衡器,也能改善Collector各层之间gRPC连接的负载分配。
使用Sidecar还有助于避免某个DaemonSet Pod故障时,影响节点上所有Pod依赖的关键组件。
Sidecar模式是在工作负载Pod中加入一个容器。OpenTelemetry Operator可以自动执行这一操作。需要创建OpenTelemetry Collector自定义资源(CR),并在PodSpec或Pod中加入注解,让Operator注入Sidecar:
---
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: sidecar-for-my-workload
spec:
mode: sidecar
config: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
exporters:
# Note: Prior to v0.86.0 use the `logging` instead of `debug`.
debug:
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [debug]
---
apiVersion: v1
kind: Pod
metadata:
name: my-microservice
annotations:
sidecar.opentelemetry.io/inject: 'true'
spec:
containers:
- name: my-microservice
image: my-org/my-microservice:v0.0.0
ports:
- containerPort: 8080
protocol: TCP
如果希望绕过Operator,手动添加Sidecar,可参考以下示例:
apiVersion: v1
kind: Pod
metadata:
name: my-microservice
spec:
containers:
- name: my-microservice
image: my-org/my-microservice:v0.0.0
ports:
- containerPort: 8080
protocol: TCP
- name: sidecar
image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector:0.69.0
ports:
- containerPort: 8888
name: metrics
protocol: TCP
- containerPort: 4317
name: otlp-grpc
protocol: TCP
args:
- --config=/conf/collector.yaml
volumeMounts:
- mountPath: /conf
name: sidecar-conf
volumes:
- name: sidecar-conf
configMap:
name: sidecar-for-my-workload
items:
- key: collector.yaml
path: collector.yaml
扩展抓取器
部分接收器主动获取遥测数据并送入流水线,例如host_metrics与prometheus接收器。主机指标采集通常无需扩容,但Prometheus接收器抓取数千个端点时,可能需要拆分任务。不能简单地以相同配置增加实例,否则集群中每个Collector都会尝试抓取相同端点,带来乱序样本等更多问题。
解决方法是按Collector实例对端点分片,使新增副本后,各实例负责不同端点集合。
一种方法是每个Collector使用各自的配置文件,只发现属于自己的端点。例如,每个Collector负责一个Kubernetes命名空间,或具有特定标签的工作负载。
另一种方法是使用Target Allocator。它是一个额外的二进制程序,可随OpenTelemetry Operator部署,将给定配置中的Prometheus抓取目标分配到Collector集群。可以使用如下自定义资源启用它:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: collector-with-ta
spec:
mode: statefulset
targetAllocator:
enabled: true
config: |
receivers:
prometheus:
config:
scrape_configs:
- job_name: 'otel-collector'
scrape_interval: 10s
static_configs:
- targets: [ '0.0.0.0:8888' ]
exporters:
# Note: Prior to v0.86.0 use the `logging` instead of `debug`.
debug:
service:
pipelines:
metrics:
receivers: [prometheus]
processors: []
exporters: [debug]
完成协调后,OpenTelemetry Operator会将Collector配置转换为:
exporters:
# Note: Prior to v0.86.0 use the `logging` instead of `debug`.
debug: null
receivers:
prometheus:
config:
global:
scrape_interval: 1m
scrape_timeout: 10s
evaluation_interval: 1m
scrape_configs:
- job_name: otel-collector
honor_timestamps: true
scrape_interval: 10s
scrape_timeout: 10s
metrics_path: /metrics
scheme: http
follow_redirects: true
http_sd_configs:
- follow_redirects: false
url: http://collector-with-ta-targetallocator:80/jobs/otel-collector/targets?collector_id=$POD_NAME
service:
pipelines:
metrics:
exporters:
- debug
processors: []
receivers:
- prometheus
注意,Operator为otel-collector抓取配置加入了global部分和新的http_sd_configs,指向它创建的Target Allocator实例。现在,只需修改CR的replicas属性来扩展Collector,Target Allocator就会为每个Collector实例(Pod)提供定制的http_sd_config,相应分配负载。
扩展有状态Collector
某些组件在内存中保存数据,扩容后会产生不同结果。例如,尾部采样处理器会在一段时间内保存span,直到认为链路完整时才做采样决策。向Collector集群增加副本,意味着同一链路的span可能被不同Collector接收。各实例分别判断是否采样,可能得到不同答案。
这种行为会导致链路缺失span,无法准确反映该次事务发生的情况。
使用span-to-metrics处理器生成服务指标时也可能出现类似情况。不同Collector接收同一服务的数据后,按服务名进行的聚合会不准确。
为解决这一问题,可以在执行尾部采样或span-to-metrics处理的Collector前,部署包含负载均衡导出器的Collector层。该导出器对链路ID或服务名进行一致性哈希,确定哪个后端Collector接收同一链路的span。可以配置它使用某个DNS A记录背后的主机列表,例如Kubernetes无头服务。
该服务后面的部署扩容或缩容时,负载均衡导出器最终会看到更新后的主机列表。也可以指定静态主机列表。增加副本数即可扩展配置了负载均衡导出器的Collector层。请注意,各Collector可能在不同时间执行DNS查询,导致短暂的集群视图差异。
在弹性变化频繁的环境中,建议减小interval值,缩短集群视图不一致的时间。
以下配置以DNS A记录作为后端信息来源,即observability命名空间中的Kubernetes服务otelcol:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
exporters:
load_balancing:
protocol:
otlp:
resolver:
dns:
hostname: otelcol.observability.svc.cluster.local
service:
pipelines:
traces:
receivers:
- otlp
processors: []
exporters:
- load_balancing
原文:Scaling the Collector,OpenTelemetry官方文档,最后修改于2026年9月10日。源文档采用CC BY 4.0;本稿为中文翻译。原配置中的版本与历史API(包括v1alpha1、0.69.0和v0.86.0前的logging说明)保留,未部署验证。











暂无评论内容