Introduction
OpenTelemetry Collector에서 사실 상 필수로 사용하길 권장되는 component인 memory limit, Batch processor에 대한 논의로, 사실 상 아래 공식 README에 대한 요약이다.
-
Memory Limit Processor
opentelemetry-collector/processor/memorylimiterprocessor at main · open-telemetry/opentelemetry-collectorOpenTelemetry Collector. Contribute to open-telemetry/opentelemetry-collector development by creating an account on GitHub.
https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/memorylimiterprocessor -
Batch Processor
opentelemetry-collector/processor/batchprocessor at main · open-telemetry/opentelemetry-collectorOpenTelemetry Collector. Contribute to open-telemetry/opentelemetry-collector development by creating an account on GitHub.
https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor/batchprocessor
Memory Limit Processor
Memory Limit Processor는 Out Of Memory(OOM) 오류 방지를 위함으로, 발생 전에 OpenTelemetry Collector로의 telemetry 인입을 거부하거나, garbage collection을 발생시킴으로 OOM 발생을 미연에 방지한다. 대상 telemetry는 metric, log, trace 전체이다.
구조

-
hard limit: garbage collection 강제 발동 threshold.
limit_mib로 정의됨.limit_mib(default: 0): process heap에 할당된 최대 메모리량. MiB 단위. process의 전체 메모리 사용량은 일반적으로 본 값보다 50MiB 더 사용함.limit_percentage(default: 75):limit_mib에 대한 상대 값 버전.limit_mib와 동시 정의될 경우 우선순위가 낮음.
-
soft limit: telemetry 인입 거부 threshold.
limit_mib-spike_limit_mib로 정의됨.-
spike_limit_mib: 메모리 사용량 측정 간에 기대되는 최대 스파이크 -
spike_limit_percentage(default: 0):spike_limit_mib의 상대값 버전. hard limit이 아닌 전체 메모리량 기준 비유을 의미.limit_percentage가 사용될 때만 유효 -
거부 시 본 processor에 앞선 component(e.g. receiver)에 오류를 전달. receiver는 본 오류 확인 시 데이터 전달을 재시도하는 것으로 기대됨.
- (Claude AI에 따르면) Prometheus receiver는 재시도하지 않고 해당 데이터를 drop. 비록 해당 주기의 데이터는 사라지더라도 다음 주기에 데이터를 가져올 것으로 기대. 반면 OTLP receiver는 OTLP client가 재시도를 하도록 429 또는 503 응답을 주거나, gRPC 상에서 flow control 신호를 client에 보냄으로 client로 하여금 전송 속도를 조절하도록 함.
(Claude AI 답변) backpressure에 대한 Prometheus, OTLP receiver 동작 방식
-
Prometheus receiver
- 자동 재시도(retry) 메커니즘 없음. 따라서 데이터 유실 발생
그 이유는:
- Prometheus의 pull 모델에서는 다음 스크래핑 간격(scrape interval)에 다시 데이터를 수집
- 실패한 스크래핑에 대한 즉각적인 재시도는 메모리 부하를 더 가중시킬 수 있음.
- 메트릭 데이터의 특성상 다음 수집 주기에 새로운 데이터를 가져오는 것이 더 합리적.
따라서, memory_limiter로 인한 거부 발생 시,
- 해당 스크래핑 주기의 데이터 유실 발생
- 다음 스크래핑 간격에 새로운 데이터 수집을 시도
- up 메트릭을 통해 스크래핑 실패를 모니터링 가능
-
OTLP receiver
-
OTLP receiver는 "push" 기반 모델이므로 Prometheus receiver와는 다르게 backpressure를 지원
-
기본 동작
- OTLP는 gRPC 또는 HTTP를 통해 데이터를 수신
- gRPC의 경우 내장된 flow control 메커니즘을 활용
- memory_limiter에서 제한이 걸리면 backpressure가 발생합니다
-
Backpressure 처리
-
gRPC 스트림의 경우
- 서버가 처리 속도를 제어할 수 있습니다
- 클라이언트에게 flow control 신호를 보낼 수 있습니다
- 클라이언트는 이 신호에 따라 전송 속도를 조절합니다
-
HTTP의 경우
- 429 (Too Many Requests) 또는 503 (Service Unavailable) 응답 반환
- 클라이언트는 재시도 메커니즘을 구현해야
-
-
재시도 동작
- OTLP 클라이언트는 보통 지수 백오프(exponential backoff)를 사용한 재시도를 구현
- 재시도 간격이 점진적으로 증가하여 시스템에 과부하가 걸리는 것을 방지
- 설정된 최대 재시도 횟수나 시간 초과까지 시도
-
구성 고려사항
- batch processor와 함께 사용하면 더 효율적인 처리가 가능
- retry_on_failure 설정을 통해 재시도 동작을 제어할 수 있음
- 적절한 batch 크기와 timeout 설정이 중요
-
-
Best Practices
-
collector의 적절한 resource 조절에 대한 대안이 아님: soft limit은 결국 데이터 유실로 이어질 수 있음(재시도 로직이 있다 하더라도 무한정 재시도는 할 수 없기 때문에). 따라서 soft limit, hard limit 값 등을 메모리 사용량을 확인함으로 적절히 조절해야(#4의 본 processor가 생성하는 metric을 상시 참고. 특히 refuse 건에 대해).
-
Processor pipeline에 모든 타 processor 보다 앞에 놓아야: 이렇게 함으로 receiver로 memory 부하가 발생했을 때 receiver로 하여금 적게 데이터를 보내게 함으로 데이터 drop을 줄일 수 있음
-
GOMEMLIMIT를 hard limit의 80% 설정 강력히 권장 -
Memory Limit Processor가 생성하는 metric은 다음 참고
processor/memorylimiterprocessor/documentation.mdopen-telemetry · 2026-10-22 업데이트
Batch Processor
Batch Processor는 전송 대상 데이터를 압축하고, outgoing connection 갯수를 줄이는 목적으로 사용한다. 대상 telemetry는 metric, log, trace 전체이다.
구조
기본적으로 batch의 크기 및 누적 시간을 기준으로 각 batch가 생성된다. 그리고 최대 크기를 넘길 경우 batch를 분리한다.
flowchart TB
subgraph "Batch Buffer"
B[데이터 누적]
C1[size 검사]
C2[timeout 검사]
C3[max size 검사]
end
subgraph "Batch Creation"
P1[batch 생성]
P2[batch 분할]
end
I[Injested metric, log, trace] --> B
B --> C1
C1 --> |"buffer size < send_batch_size"| C2
C2 --> |"time elapsed < timeout"| B
C1 --> |"buffer size >= send_batch_size"| C3
C2 --> |"time elapsed >= timeout"| C3
C3 --> |"buffer size <= send_batch_max_size"| P1
C3 --> |"bufer size > send_batch_max_size"| P2
P2 --> P1
P1 --> O[다음 프로세서]
classDef input fill:#f9f,stroke:#333,stroke-width:2px
classDef buffer fill:#bbf,stroke:#333,stroke-width:2px
classDef process fill:#bfb,stroke:#333,stroke-width:2px
classDef output fill:#fbb,stroke:#333,stroke-width:2px
class I input
class B,C1,C2,C3 buffer
class P1,P2 process
class O output
send_batch_size: 전송 trigger를 일으키는 telemetry의 갯수로서 단일 batch의 기준 크기. default는 8192.timeout: 전송 trigger를 일으키는 batch 간 시간 간격으로 default는 200ms. 0일 경우send_batch_size보다 telemetry 갯수가 적더라도 즉시 전송이 시작됨.send_batch_max_size: 단일 batch의 최대 크기(telemetry 갯수). 본 값을 넘어서면 batch는 분할된다. default는 0으로, 이 경우 단일 batch 크기 제한이 없음을 의미.- 참고:
send_batch_size가 있음에도send_batch_max_size가 있는 이유는 buffer에send_batch_max_size를 넘어서는 telemetry 갯수가 위치할 수 있기 떄문.
Pipeline 상 Processor 순서에 관하여
하기 Processor 공식 문서에 따르면 processor 간의 순서는 매우 중요하며, pipeline 구조인 것을 감안하면 그게 당연하다. memory_limit 은 모든 processor 중 가장 앞에 위치하는 것을, 그리고 batch 는 sampling, filtering 및 metric에 변경을 가하는 processor 뒤에 위치하는 것을 논한다. Example 에 pipeline 상 processor 순서를 나타내고 있다.
Example
env:
- name: GOMEMLIMIT
value: 640MiB # 1Gi * 0.85(limit_percentage) * 0.8 80% of hard memory limit is highly recommended by Official README.
config:
processors:
memory_limiter:
check_interval: 1s # recommended by official README
limit_percentage: 85
spike_limit_percentage: 17 # default is 20% of hard limit. 17 = 0.85 * 0.2
batch: # https://github.com/open-telemetry/opentelemetry-collector/blob/main/processor/batchprocessor/README.md
send_batch_size: 8192 # default 8192
send_batch_max_size: 0 # default 0, which means no limit on size.
timeout: 200ms # default 200ms
service:
pipelines:
metrics:
processors:
- memory_limiter # recommended to be the first in processors pipeline
- "Any sampling or initial filtering processors"
- "Any processor relying on sending source from Context (e.g. k8sattributes)"
- batch # place before any attribute, transform, sampling, filter processors as well as memory limit processor
- "Any other processors"
YAML
Comments