Mengoptimalkan performa pipeline telemetry: tuning memory dan CPU collector, menyetel memory_limiter, konfigurasi concurrency, mengendalikan cardinality metrics, melakukan load test pipeline, dan profiling collector memakai pprof

Semua episode sebelumnya membangun pipeline yang benar. Episode 19 membangun pipeline yang efisien — karena di skala produksi, observability adalah beban yang harus dibayar: memory collector, CPU untuk parsing, dan biaya backend per series metrics. Pipeline yang tidak dituning akan diam-diam menggerus resource cluster.
Mengapa penting? Collector yang boros memory akan di-restart oleh K8s; metrics ber-cardinality liar akan meledakkan biaya dan memperlambat query; dan pipeline yang tidak di-load test akan mengejutkan kalian tepat saat traffic tinggi — momen ketika observability paling dibutuhkan.
Tuning memory_limiter membutuhkan angka yang diukur, bukan ditebak. Aturannya:
limit_mib sekitar 80% dari limit memory container (sisanya untuk runtime dan spike).spike_limit_mib sekitar 20-25% dari limit — ruang untuk lonjakan sesaat.otelcol_processor_..._limit_mib dan otelcol_processor_..._spike_limit_mib untuk memverifikasi.processors:
memory_limiter:
check_interval: 1s
limit_mib: 800
spike_limit_mib: 200Jika collector sering thrash (GC terus-menerus, refusal naik), cek dulu komponen mana yang paling boros — jangan asal menaikkan limit.
batch yang terlalu besar menambah memory (batch dipegang sampai terkirim) — sesuaikan send_batch_size dengan throughput.sending_queue (episode 14) adalah pemakai memory utama — queue_size besar berarti memory besar; hitung 1 item kira-kira beberapa ratus byte sampai beberapa KB tergantung data.Collector berbasis Go — CPU tuning sebagian besar lewat paralelisme pipeline:
exporters:
otlp/backend:
endpoint: jaeger:4317
tls:
insecure: true
sending_queue:
enabled: true
queue_size: 5120
num_consumers: 4
processors:
batch:
timeout: 2s
send_batch_size: 1024
send_batch_max_size: 2048num_consumers — berapa goroutine pengirim paralel; mulai dari 4, ukur, naikkan bila antrean menumpuk.send_batch_max_size — mencegah batch membesar tak terkendali saat lonjakan.GOMAXPROCS via flag --gomemlimit atau env).Tip
Sebelum men-tune concurrency, ukur dulu. Satu collector contributor yang dikonfigurasi benar bisa meneruskan ratusan ribu span/detik. Jika collector kalian "selalu penuh", kemungkinan besar masalahnya bukan CPU — melainkan cardinality (metrik seri membengkak) atau queue tanpa batas.
Cardinality adalah jumlah kombinasi unique key=value dalam satu metric. Attribute ber-kardinalitas tinggi (user_id, request_id, ip_address) membuat satu metric meledak menjadi jutaan series — biaya backend dan query melambat.
Strategi pengendalian:
# Buruk: satu series per user_id → meledak
latency.record(d, {"user_id": user.id})
# Baik: cardinality rendah, tetap berguna
latency.record(d, {"http.route": route, "http.response.status_code": status})transform processor untuk menghapus key liar sebelum diekspor:processors:
transform/cardinality:
error_mode: ignore
metric_statements:
- context: datapoint
statements:
- delete_key(attributes, "request_id")
- delete_key(attributes, "user_id")View dengan aggregation untuk mengabaikan attribute tertentu (episode 5).Ukur cardinality dengan query backend (misal PromQL count(metric)), lalu bandingkan sebelum/sesudah perbaikan.
Sebelum men-tune lebih jauh, kalian butuh baseline. Jalankan load test ringan yang mengirim telemetry buatan ke collector dan ukur throughput:
docker run --rm \
-v "$PWD/config.yaml:/etc/config.yaml" \
ghcr.io/open-telemetry/opentelemetry-collector-contrib/telemetrygen \
traces --otlp-endpoint localhost:4317 \
--traces 100000 --workers 8 \
--otlp-attributes service.name=load-testMetrik yang diperhatikan selama test:
otelcol_receiver_accepted_spans vs otelcol_receiver_refused_spans.otelcol_exporter_sent_spans vs otelcol_exporter_send_failed_spans.otelcol_exporter_queue_size — naik terus = hilir tidak mampu mengimbangi.process_runtime_heap_alloc_bytes / GC pause — memory sehat?Warning
Load test yang benar menguji seluruh pipeline, bukan collector sendirian. Backend yang ikut diuji (Jaeger, Prometheus) bisa jadi bottleneck sesungguhnya. Mulailah dari volume kecil dan naikkan bertahap sambil memantau semua metrik internal — jangan langsung membanjiri dengan volume maksimal.
Saat CPU collector tinggi tanpa penyebab yang jelas, aktifkan pprof:
service:
telemetry:
profilers:
block:
enabled: true
memory:
enabled: true
cpu:
enabled: trueLalu ambil profile dari port 1777:
curl -o cpu.prof "http://localhost:1777/debug/pprof/profile?seconds=30"
go tool pprof -top cpu.profHasil -top menunjukkan fungsi mana yang menyedot CPU — sering kali ini mengarah pada regex redaksi yang mahal, komponen parsing yang tak terduga, atau GC yang terlalu agresif.
Pada episode 19 ini, kalian telah mengoptimalkan performa pipeline telemetry.
Inti yang harus dibawa pulang:
num_consumers dan send_batch_max_size — ukur dulu sebelum mengubah.telemetrygen, dan profiling dengan pprof saat CPU tidak jelas penyebabnya.Di episode 20 selanjutnya, kita akan membahas multi-backend & cloud observability — routing ke beberapa backend sekaligus (fan-out) atau per-sinyal, serta distro cloud seperti AWS Distro ADOT, GCP OTel, dan Azure Monitor dengan strategi multi-vendor. Sampai jumpa di episode 20!