← blog · 29 Ekim 2026

Dağıtık İzlemede Örnekleme: Baş ve Kuyruk Örneklemesi, Aynı İzi Aynı Toplayıcıya Göndermek ve Bozulan Metrikler

Her span'ı saklamak pahalı, yanlış yerde örneklemek ise aranan izi çöpe atar. Baş ve kuyruk örneklemesi arasında seçim, OpenTelemetry Collector ile kuyruk örneklemesi, izin kimliğine göre yük dağıtımı, metrikleri örneklemeden önce üretmek ve yarım izlerin nedenleri.

Dağıtık izlemeyi açan ekip birkaç hafta içinde aynı yere varır: her isteğin her span'ını saklamak, uygulamanın kendisinden pahalı bir depolama faturası çıkarır. Trafiğin büyük kısmı da zaten birbirinin aynısı olan, hızlı ve hatasız isteklerdir. Örnekleme (sampling) bu yüzden kaçınılmazdır, asıl soru kararın nerede ve neye bakarak verileceğidir. Yanlış yerde verilen karar ya aranan izi çöpe atar ya da izleri ortasından koparır.

İki karar noktası

Baş örnekleme (head sampling) kararı izin en başında, kök span oluşturulurken verir. Karar W3C traceparent başlığındaki sampled bayrağıyla aşağı akıştaki servislere taşınır ve her servis üst servisin kararına uyar. Maliyeti neredeyse sıfırdır: örneklenmeyen span hiç dışa aktarılmaz, ağa ve toplayıcıya yük bindirmez. Zayıf yanı, karar anında isteğin nasıl biteceğini kimsenin bilmemesidir. Yüzde on örneklemeyle günde elli kez görülen nadir bir hatanın izlerinin yaklaşık yüzde doksanı hiç kaydedilmez.

Kuyruk örneklemesi (tail sampling) kararı izin tamamı toplandıktan sonra verir. Toplayıcı bir izin span'larını bir süre bellekte bekletir, sonra kurallara bakar: hata içeren izler, gecikme eşiğini aşanlar, belirli bir uçtan geçenler saklanır, geri kalandan küçük bir oran alınır. Aranan anormal örnekler kaçmaz. Bedeli, bütün span'ların uygulamadan çıkıp toplayıcıya kadar gelmesi, orada bellekte tutulması ve aynı izin bütün parçalarının aynı toplayıcı örneğine ulaşması gerekliliğidir.

Taraf tutmak gerekirse: trafiği orta ve üstü olan, birden fazla servisli bir sistemde varsayılan seçim kuyruk örneklemesi olmalıdır. İz verisinin değeri neredeyse tamamen istisnalardadır, baş örnekleme ise istisnaları ortalamayla aynı oranda atar. Baş örnekleme, trafiğin toplayıcıya taşınmasının bile pahalı olduğu çok yüksek hacimde ve kuyruk örneklemesinin önünde bir ilk eleme olarak anlamlıdır.

Baş örnekleme: tutarlılığı bozmayın

OpenTelemetry SDK'ları örnekleyiciyi ortam değişkeniyle seçer:

OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1

parentbased_ öneki önemlidir. Bu örnekleyici yalnızca kök span'da oran uygular, üst bağlamı olan span'larda gelen kararı aynen izler. Önek olmadan traceidratio kullanan bir servis, üst servis izi örneklemiş olsa bile kendi kararını verir. Oran izin kimliğinden belirlenimci biçimde hesaplandığı için bütün servisler aynı oranı kullandığı sürece sonuç aynı çıkar, ama servislerden biri farklı oranla yapılandırıldığında izlerin bir kısmı ortasından kopar ve arayüzde üst span'ı eksik parçalar görürsünüz.

Varsayılan değer parentbased_always_on'dur, yani hiçbir şey ayarlamazsanız her şey örneklenir. Kuyruk örneklemesi kullanacaksanız bu doğru başlangıçtır: uygulamada tutar, toplayıcıda karar verirsiniz.

Kuyruk örneklemesi: OpenTelemetry Collector ile

Collector'ın contrib dağıtımındaki tail_sampling işlemcisi bu işi yapar. Politikalar sırayla değerlendirilir ve herhangi biri izi örneklerse iz saklanır:

receivers:
  otlp:
    protocols:
      grpc:

processors:
  memory_limiter:
    check_interval: 1s
    limit_percentage: 80
    spike_limit_percentage: 20
  tail_sampling:
    decision_wait: 10s
    num_traces: 100000
    expected_new_traces_per_sec: 1000
    policies:
      - name: hatalar
        type: status_code
        status_code:
          status_codes: [ERROR]
      - name: yavaslar
        type: latency
        latency:
          threshold_ms: 1500
      - name: geri-kalan
        type: probabilistic
        probabilistic:
          sampling_percentage: 5
  batch: {}

exporters:
  otlp:
    endpoint: trace-backend:4317

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

decision_wait, ilk span geldikten sonra kararın ne kadar bekleyeceğidir. Bu sürenin en yavaş normal isteğinizden uzun olması gerekir; aksi hâlde karar verildiğinde izin yarısı henüz gelmemiştir. num_traces bellekte aynı anda tutulacak iz sayısıdır ve bellek tüketimini doğrudan belirler. Kabaca saniyedeki yeni iz sayısı ile bekleme süresinin çarpımı kadar iz bellekte durur; bunun iki üç katı pay bırakın. memory_limiter hattın ilk işlemcisi olmalıdır ki ani bir artış toplayıcıyı bellek yetersizliğinden düşürmek yerine veriyi geri çevirsin.

Aynı iz, aynı toplayıcı

Kuyruk örneklemesinin en sık atlanan şartı budur. Toplayıcıyı yatay ölçeklediğinizde ve önüne sıradan bir yük dengeleyici koyduğunuzda, bir izin span'ları farklı örneklere dağılır. Her örnek izin yalnız bir parçasını görür: hatalı span'ı gören örnek kendi parçasını saklar, diğerleri izi sıradan sanıp atar. Sonuç, yarım izlerdir.

Çözüm iki katmanlı bir düzendir. İlk katman uygulamalardan veriyi alır ve loadbalancing dışa aktarıcısıyla izin kimliğine göre ikinci katmana dağıtır; ikinci katman kuyruk örneklemesini yapar:

receivers:
  otlp:
    protocols:
      grpc:

connectors:
  spanmetrics: {}

exporters:
  loadbalancing:
    routing_key: traceID
    protocol:
      otlp:
        tls:
          insecure: true
    resolver:
      dns:
        hostname: sampling-collector-headless.observability.svc.cluster.local
  otlphttp/metrics:
    endpoint: http://metrics-backend:4318

service:
  pipelines:
    traces:
      receivers: [otlp]
      exporters: [spanmetrics, loadbalancing]
    metrics:
      receivers: [spanmetrics]
      exporters: [otlphttp/metrics]

DNS çözücüsü, ikinci katmanın bütün örneklerinin adreslerini döndüren bir ad ister; Kubernetes'te bu, başsız (headless) bir servistir. Normal bir servis adı tek bir sanal IP döndürür ve dağıtım yine rastgele olur. Kubernetes'te k8s çözücüsü de vardır ve uç noktaları API'den izler.

Metrikleri örneklemeden önce üretin

Yukarıdaki yapılandırmada spanmetrics bağlayıcısı ilk katmanda, yani örneklemeden önce durur. Bu bilinçli bir seçimdir. Span'lardan istek sayısı, hata oranı ve gecikme dağılımı üretiyorsanız ve bunu örneklenmiş veriden yaparsanız, saklanan izlerin hepsi hatalı ve yavaş olanlar ağırlıklı olduğu için panonuzda hata oranı gerçeğin onlarca katı görünür. İstek sayısı da yüzde beşe iner.

Baş örnekleme kullanıyorsanız aynı sorun daha derindir: örneklenmeyen span toplayıcıya hiç gelmez, span'dan türetilen metrik baştan yanlıştır. Bu durumda istek metriklerini SDK'nın metrik enstrümantasyonundan alın, izden türetmeyin.

Tuzaklar

Hata tanımı enstrümantasyona bağlıdır. status_code politikası span durumuna bakar, HTTP koduna değil. Anlamsal kurallara göre sunucu span'larında 4xx yanıtlar hata sayılmaz, durum boş kalır. Yakalanıp kullanıcıya düzgün bir mesajla dönen istisnalar da çoğu zaman span'ı hatalı işaretlemez. Önemli bir hata yolunuz varsa span durumunu kodda açıkça ayarlayın ya da o özniteliğe bakan ayrı bir politika yazın.

Geç gelen span'lar. Karar verildikten sonra gelen bir span, toplayıcı o izin kararını hatırlamıyorsa yeni bir iz gibi değerlendirilir ve çoğu zaman atılır. Uzun süren arka plan işleri ya da kuyruktan geç tüketilen mesajlar bu yüzden saklanan izlerde eksik görünür. Kullandığınız sürümde karar önbelleği ayarlarının olup olmadığını ve varsayılanını kontrol edin; yoksa çok uzun işleri ayrı bir iz olarak başlatıp bağlantı (span link) ile ilişkilendirmek daha temiz sonuç verir.

Ölçekleme sırasında yeniden dağıtım. İkinci katmana örnek eklendiğinde ya da biri yeniden başladığında izin kimliği ile örnek arasındaki eşleme değişir. O anda yolda olan izler iki örneğe bölünür. Bu kalıcı bir hata değildir ama otomatik ölçeklemeyi çok hassas ayarlarsanız sürekli bir yarım iz akışı üretir. İkinci katmanı sabit ya da yavaş değişen bir boyutta tutun.

Politikaların toplamı. Politikalar birbirinden bağımsız değerlendirilir; saklanan hacmi tahmin ederken her politikanın tuttuğunu ayrı ayrı toplayın. Trafikte ani bir hata dalgası, hata politikası yüzünden saklanan hacmi bir anda katlar. Arka ucunuz bunu kaldırmıyorsa hata politikasının yanında rate_limiting türünde bir üst sınır düşünün.

Örnekleme oranını analizde unutmak. Saklanan izlerden "bu uç saatte kaç kez çağrıldı" sorusunu cevaplamaya çalışmak, örnekleme oranı her izde farklı olduğu için yanıltıcıdır. Sayım sorularını metrikten, tekil isteğin hikâyesini izden sorun.

Ne zaman örneklemeyin

Günde birkaç bin istek alan bir sistemde her şeyi saklamak çoğu arka uçta önemsiz bir maliyettir ve örnekleme altyapısının işletim yükü kazancı aşar. Tek servisli bir uygulamada da kuyruk örneklemesi için iki katmanlı toplayıcı kurmak, çözdüğünden fazla parça ekler. Böyle durumlarda parentbased_always_on ile her şeyi gönderin, saklama süresini kısa tutun. Örneklemeye, iz depolamasının maliyeti ya da toplayıcının yükü gerçekten bir kalem hâline geldiğinde geçin ve geçtiğiniz gün metriklerinizin hâlâ örneklenmemiş veriden üretildiğini doğrulayın.