---
title: 'Ölçüt Toplama Modelleri'
source: 'https://academia.sh/tr/kurslar/devops-gozlemlenebilirlik/olcut-toplama-modelleri'
course: 'Gözlemlenebilirlik ve İşletim'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Ölçüt Toplama Modelleri

Çekme ve itme temelli toplama aynı pencerede koşturulur ve işletimde gerçekten sorulan on iki sorudan oluşan bir kümeye uygulanır: hangi model kaç soruyu yanıtlıyor, kısa ömürlü iş çekmede neden kaçıyor, itmede kaynak kimliği neden karışıyor, keşif gecikmesi ve soru başına bayt ne kadar.

Bir önceki kursun kapanışı altyapının kayda bağlandığı, her değişikliğin bir gözden geçirmeden ve
bir kapıdan geçtiği noktada bitti. Ama kapıdan geçtikten sonra sistemin koşarken ne yaptığını
kimse görmüyordu. Bu kursun ilk sorusu oradan devralınır ve bir adım daha ileri gider: **neyin
ölçüleceğine kim karar veriyor?**

Bu kursun ölçü birimi veri değil, **sorudur**. Bir toplama kurulumunun iyi olup olmadığı kaç
gigabayt biriktirdiğiyle değil, işletimde gerçekten sorulan sorulardan kaçını yanıtladığıyla
ölçülür. Bu ders o soru kümesini kurar ve iki toplama modelini — **çekme temelli** ve **itme
temelli** — aynı pencerede koşturup kümeye uygular.

Ölçüm yine **bölgesel ölçüm ağı** üzerindedir: su sayaçlarından okuma toplayan, okumaları
doğrulayan, faturaya çeviren ve saha ekiplerine iş emri açan bir yazılım. Ağ da, ölçülen sayılar
da **kurgudur**; gerçek bir toplayıcı koşturulmaz, sayılan şey `node` ile kurulmuş bir
**modeldir**.

**OG1.** On iki soru kurgudur ve önceden yazılıdır; her sorunun gerektirdiği kaynak sınıfı, ölçüt
ve etiketler de öyle.
**OG2.** Envanter kurgudur: üç ortamda 29 uzun ömürlü örnek, bir saatlik pencerede 11 yeniden
başlatma ve 42 gecelik doğrulama koşumu.
**OG3.** Çekme temelli toplayıcı 15 saniyede bir kazır, hedef envanterini 30 saniyede bir
yeniler; itme temelli gönderici uzun ömürlü süreçte 10 saniyede bir boşaltır, toplu iş her adım
bitiminde gönderir.
**OG4.** Bir kayıt 16 bayt, bir seri künyesi 120 bayttır.
**OG5.** Bir kaynak sınıfı ancak ömürlerinin en az yüzde 90'ından ikişer ölçüm alınabiliyorsa
kapsam içinde sayılır; tek ölçüm bir değişimi göstermez.
**OG6.** Yeniden başlatma zamanları ve koşum süreleri kendi üretecimizle üretilir, tohum
`20260901`.

## İşletimde Sorulan On İki Soru

Soru kümesi ölçüm aracının değil, işletimin ürünüdür: nöbet sırasında, sabah raporunda ve olay
incelemesinde gerçekten sorulmuş cümlelerdir. Her soru üç şeye bağlanır — hangi **kaynak
sınıfından** veri gerekiyor, hangi **ölçüt**, hangi **etiketler**.

```js
// ag.mjs — bolgesel olcum agi modeli ve isletim soru kumesi. Ikisi de kurgudur.
export const ORNEK = {                               // ortam -> servis -> uzun omurlu ornek
  uretim: { "okuma-toplayici": 8, dogrulayici: 6, faturalama: 4, "is-emri": 3 },
  sinama: { "okuma-toplayici": 2, dogrulayici: 2, faturalama: 1, "is-emri": 1 },
  gelistirme: { "okuma-toplayici": 1, dogrulayici: 1, faturalama: 0, "is-emri": 0 } };
export const UZUN_SAYISI = Object.values(ORNEK)
  .reduce((t, o) => t + Object.values(o).reduce((a, b) => a + b, 0), 0);

export const OLCUT_UZUN = { "istek-sayisi": { sonuc: 5 }, "istek-suresi": { dilim: 12 },
  "kuyruk-boyu": { kuyruk: 3 }, "islenen-okuma": { bolge: 11, sonuc: 5 },
  "surec-baslangic-zamani": {}, "cop-toplama-duraklamasi": { kova: 8 }, "dosya-tanitici-sayisi": {} };
export const OLCUT_KISA = { "is-adimi-suresi": { adim: 6 }, "is-islenen-kayit": {} };
export const seri = (o) => Object.values(o)
  .reduce((t, e) => t + Object.values(e).reduce((c, k) => c * k, 1), 0);

// isletimde gercekten sorulan on iki soru: [kimlik, metin, kaynak sinifi, olcut, gereken alanlar]
export const SORU = [
  ["S1", "hangi servis yavasladi", "uzun", "istek-suresi", ["servis"]],
  ["S2", "gecikmenin ust dilimi ne", "uzun", "istek-suresi", ["servis", "dilim"]],
  ["S3", "hangi ortamda hata artti", "uzun", "istek-sayisi", ["ortam", "sonuc"]],
  ["S4", "hangi surumden sonra bozuldu", "uzun", "istek-sayisi", ["surum"]],
  ["S5", "gecelik is kac okuma isledi", "kisa", "is-islenen-kayit", ["is"]],
  ["S6", "gecelik is dun neden gec bitti", "kisa", "is-adimi-suresi", ["is", "adim"]],
  ["S7", "hangi bolgenin okumasi dogrulanmadi", "uzun", "islenen-okuma", ["bolge", "sonuc"]],
  ["S8", "hangi ornek yeniden basladi", "uzun", "istek-sayisi", ["ornek"]],
  ["S9", "hangi dogrulama kosumu yavasti", "kisa", "is-adimi-suresi", ["is", "ornek"]],
  ["S10", "hangi hata kodu artti", "uzun", "istek-sayisi", ["sonuc"]],
  ["S11", "is emri kuyrugu neden birikti", "uzun", "kuyruk-boyu", ["servis", "kuyruk"]],
  ["S12", "bir fatura hangi okumadan uretildi", "istek", "-", ["islem-kimligi"]],
];
export const yanit = (kapsam, alan) =>
  SORU.filter(([, , k, , a]) => kapsam.includes(k) && a.every((e) => alan.includes(e)));

export const uretec = (t) => () => (t = (t * 1103515245 + 12345) % 2147483648) / 2147483648;
export const KAYIT_BAYT = 16, SERI_BAYT = 120;
export const mb = (b) => (b / 1024 ** 2).toFixed(1);
```

Üç kaynak sınıfı vardır. **Uzun ömürlü** olan, saatlerce koşan servis örneğidir. **Kısa ömürlü**
olan, gecelik toplu işin her koşumudur; ortalama yarım dakika yaşar. **İstek** sınıfı tek bir
işlemin kendisidir ve hiçbir ölçüt onu taşıyamaz, çünkü işlem kimliğinin kardinalitesi sınırsızdır.
S12 bu yüzden baştan işaretlidir: bir ölçüt hattı onu ne kadar veri toplarsa toplasın yanıtlayamaz.

## Çekme ve İtme Aynı Pencerede

İki model aynı bir saatlik pencerede koşturulur. Fark üç yerde toplanır: **neyin görüldüğü**
(kapsam), **ne zaman görüldüğü** (keşif gecikmesi) ve **kimin gördüğü olarak kaydedildiği**
(kaynak kimliği).

```js
// topla.mjs — cekme ve itme temelli toplama ayni pencerede kosturulur ve soru kumesine uygulanir.
import { ORNEK, UZUN_SAYISI, OLCUT_UZUN, OLCUT_KISA, seri, SORU, yanit, uretec, KAYIT_BAYT, SERI_BAYT, mb }
  from "./ag.mjs";

const PENCERE = 3600, KAZIMA = 15, ENVANTER = 30, ITME = 10;   // saniye
const rast = uretec(20260901);                                 // tohum gorunur
const omur = [];                                               // 29 ornek pencere basindan, 11 yeniden baslatma
for (let i = 0; i < UZUN_SAYISI; i++) omur.push({ sinif: "uzun", bas: 0, bit: PENCERE });
for (let i = 0; i < 11; i++) {
  const h = omur[Math.floor(rast() * UZUN_SAYISI)], t = 300 + Math.floor(rast() * 3000);
  h.bit = t; omur.push({ sinif: "uzun", bas: t + 20, bit: PENCERE });
}
const kosum = Array.from({ length: 42 }, (_, i) => {           // gecelik dogrulama kosumlari
  const bas = 60 + i * 80 + Math.floor(rast() * 30);
  return { sinif: "kisa", bas, bit: bas + 6 + Math.floor(rast() * 33) };
});
const hepsi = [...omur, ...kosum];

const cekme = (o) => {                                         // envanter yenilendikten sonraki kazimalar
  const t = [], gorunur = Math.ceil(o.bas / ENVANTER) * ENVANTER;
  for (let s = Math.ceil(gorunur / KAZIMA) * KAZIMA; s < o.bit; s += KAZIMA) t.push(s);
  return t;
};
const itme = (o) => {                                          // surec kendi gonderir; kesif turu yok
  const t = [];
  if (o.sinif === "kisa") {                                    // toplu is her adim bitiminde gonderir
    for (let a = 1; a <= 6; a++) t.push(o.bas + Math.round(((o.bit - o.bas) * a) / 6));
    return t;
  }
  for (let s = o.bas + ITME; s < o.bit; s += ITME) t.push(s);
  return t;
};
const kapsanan = (f, s) => hepsi.filter((o) => o.sinif === s && f(o).length >= 2).length;
const toplam = (s) => hepsi.filter((o) => o.sinif === s).length;
const kesif = (f) => {                                         // yalniz pencere icinde baslayan omurler
  const g = omur.filter((o) => o.bas > 0).map((o) => f(o)[0] - o.bas);   // yeniden baslayan ornekler
  return [(g.reduce((a, b) => a + b, 0) / g.length).toFixed(1), Math.max(...g)];
};

const ALAN = ["servis", "ortam", "surum", "sonuc", "dilim", "kuyruk", "bolge", "is", "adim"];
const MODEL = [["cekme", cekme, UZUN_SAYISI, kapsanan(cekme, "kisa")],  // kimlik envanterden gelir
  ["itme", itme, omur.length, 3]];                             // kimlik surecin kendi bildirimi, is sablonu sabit
console.log(`bolgesel olcum agi (kurgu): ${UZUN_SAYISI} uzun omurlu ornek, ${Object.keys(ORNEK).length} ortam,` +
  ` ${omur.length - UZUN_SAYISI} yeniden baslatma, ${kosum.length} gecelik dogrulama kosumu`);
console.log(`ornek basina ${seri(OLCUT_UZUN)} seri, kosum basina ${seri(OLCUT_KISA)} seri; pencere ${PENCERE} sn\n`);
console.log("model  uzun omur  kisa omur   kesif ort/azami   kimlik uzun  kimlik kisa");
const ozet = [];
for (const [ad, f, kimlikU, kimlikK] of MODEL) {
  const [ort, azami] = kesif(f), ku = kapsanan(f, "uzun"), kk = kapsanan(f, "kisa");
  const olcum = hepsi.reduce((t, o) => t + f(o).length * seri(o.sinif === "uzun" ? OLCUT_UZUN : OLCUT_KISA), 0);
  const seriSayisi = kimlikU * seri(OLCUT_UZUN) + kimlikK * seri(OLCUT_KISA);
  ozet.push([ad, ku, kk, olcum, seriSayisi, kimlikU === UZUN_SAYISI]);   // kimlik yeniden baslatmada korunuyor mu
  console.log(`${ad.padEnd(7)}${String(`${ku}/${toplam("uzun")}`).padStart(9)}` +
    `${String(`${kk}/${toplam("kisa")}`).padStart(11)}${String(`${ort} / ${azami} sn`).padStart(18)}` +
    `${String(`${kimlikU}/${omur.length}`).padStart(14)}${String(`${kimlikK}/${kosum.length}`).padStart(13)}`);
}

console.log("\nsoru kumesine karsi (12 soru)");
console.log("model  yanitlanan  bayt/saat  soru basina  yanitsiz kalan");
for (const [ad, ku, kk, olcum, seriSayisi, kararli] of ozet) {
  const kapsam = [ku / toplam("uzun") >= 0.9 && "uzun", kk / toplam("kisa") >= 0.9 && "kisa"].filter(Boolean);
  const alan = kararli ? [...ALAN, "ornek"] : ALAN;            // kimlik kararsizsa ornek etiketi yok
  const y = yanit(kapsam, alan), bayt = olcum * KAYIT_BAYT + seriSayisi * SERI_BAYT;
  console.log(`${ad.padEnd(7)}${String(`${y.length}/${SORU.length}`).padStart(9)}` +
    `${String(`${mb(bayt)} MB`).padStart(11)}${String(`${mb(bayt / y.length)} MB`).padStart(13)}  ` +
    SORU.filter((s) => !y.includes(s)).map(([k]) => k).join(" "));
}

const bos = Object.keys(OLCUT_UZUN).filter((a) => !SORU.some(([, , , o]) => o === a));
const bosSeri = bos.reduce((t, a) => t + seri({ [a]: OLCUT_UZUN[a] }), 0);
console.log(`\nhicbir soruyu yanitlamayan olcutler: ${bos.join(", ")}`);
console.log(`  ornek basina ${bosSeri}/${seri(OLCUT_UZUN)} seri (%${(100 * bosSeri / seri(OLCUT_UZUN)).toFixed(1)}),` +
  ` cekmede saatte ${mb(UZUN_SAYISI * bosSeri * (PENCERE / KAZIMA) * KAYIT_BAYT)} MB`);
const kacan = kosum.length - kapsanan(cekme, "kisa"), RAPOR = 7 * 3600, BASLANGIC = 2 * 3600;
const bekleme = kosum.reduce((t, o) => t + (RAPOR - BASLANGIC - o.bit), 0) / kosum.length / 3600;
console.log(`cekmede seri uretmeyen ${kacan} kosum: basarisizlik ancak sabah raporunda,` +
  ` ortalama ${bekleme.toFixed(1)} saat sonra`);
```

```
bolgesel olcum agi (kurgu): 29 uzun omurlu ornek, 3 ortam, 11 yeniden baslatma, 42 gecelik dogrulama kosumu
ornek basina 85 seri, kosum basina 7 seri; pencere 3600 sn

model  uzun omur  kisa omur   kesif ort/azami   kimlik uzun  kimlik kisa
cekme      40/40      13/42      14.6 / 27 sn         29/40        13/42
itme       40/40      42/42      10.0 / 10 sn         40/40         3/42

soru kumesine karsi (12 soru)
model  yanitlanan  bayt/saat  soru basina  yanitsiz kalan
cekme       8/12     9.7 MB       1.2 MB  S5 S6 S9 S12
itme        9/12    14.5 MB       1.6 MB  S8 S9 S12

hicbir soruyu yanitlamayan olcutler: surec-baslangic-zamani, cop-toplama-duraklamasi, dosya-tanitici-sayisi
  ornek basina 10/85 seri (%11.8), cekmede saatte 1.1 MB
cekmede seri uretmeyen 29 kosum: basarisizlik ancak sabah raporunda, ortalama 4.5 saat sonra
```

Uzun ömürlü tarafta iki model eşittir: kırk ömrün kırkı da her iki modelde kapsanır. Ayrım kısa
ömürlü tarafta açılır. Çekme temelli toplayıcı 42 doğrulama koşumunun yalnız **on üçünden** iki ya
da daha fazla ölçüm alabilir. Nedeni iki gecikmenin üst üste binmesidir: envanter otuz saniyede
bir yenilenir, kazıma on beş saniyede bir yapılır, koşumların ortalama ömrü ise otuz saniyenin
altındadır. Koşum, kendisini görecek olan turdan önce biter. Yirmi dokuz koşum hiçbir seri
üretmeden geçer ve **geçtikleri de görünmez** — eksik seri bir hata değil, yalnız bir yokluktur.

İtme tarafında bu sorun yoktur, çünkü kimse koşumu keşfetmek zorunda değildir: koşum kendi
verisini kendi gönderir ve her adım bitiminde bir kez daha gönderir. Kırk iki koşumun kırk ikisi
kapsanır.

Kimlik sütunları ayrımı tersine çevirir. Çekmede kimlik **envanterden** gelir; bir örnek yeniden
başladığında envanterdeki girdi aynı kaldığı için seri de aynı kalır — kırk ömür yirmi dokuz
kimlik altında toplanır ve yeniden başlatma serideki boşlukla görünür. İtmede kimlik **sürecin
kendi bildirimidir**; her yeni süreç kendine yeni bir kimlik üretir, kırk ömür kırk ayrı kimlik
yaratır ve yeniden başlayan bir örnek ile hiç görülmemiş yeni bir örnek birbirinden ayırt
edilemez. Kısa ömürlü tarafta aynı mekanizma ters yönde bozar: toplu iş şablonu iş adını sabit
yazdığı için kırk iki koşum **üç kimlik** altında birleşir ve tek tek koşumlar birbirine karışır.

## İki Modelin Yanıtsız Bıraktığı Sorular

Çekme sekiz soruyu yanıtlar, itme dokuz soruyu. Yanıtsız kalanlar aynı değildir ve bu, ders için
tablonun en önemli satırıdır.

Çekmede S5, S6 ve S9 düşer: gecelik işin kaç okuma işlediği, dün neden geç bittiği ve hangi
koşumun yavaş olduğu. Üçü de kısa ömürlü kaynak sınıfına bağlıdır ve o sınıf kapsam dışıdır. Bunun
bedeli son satırdadır: seri üretmeyen yirmi dokuz koşumdan biri başarısız olduğunda bunu gösteren
tek sinyal sabahki mutabakat raporudur; iş gece iki ile üç arasında koşarken rapor yediye kadar
beklenir — **ortalama dört buçuk saat**. Faturalama zincirinin başındaki bir doğrulama koşumu
sessizce düştüğünde o dört buçuk saat, düzeltilmesi gereken kayıt sayısına doğrudan çarpar.

İtmede S8 ve S9 düşer: hangi örneğin yeniden başladığı ve hangi doğrulama koşumunun yavaş olduğu.
İkisi de tek bir etiketin güvenilirliğine bağlıdır — `ornek`. Etiket teknik olarak vardır ve her
kayıtta yazılıdır; güvenilir olmayan şey, aynı örneğin iki farklı zamanda aynı değeri taşıyacağı
güvencesidir. Bu, toplamanın **hiç veri kaybetmeden** bir soruyu kapatabildiğini gösterir: veri
eksik değil, ölçülemez durumdadır.

S12 her iki modelde de yanıtsızdır ve bu ders boyunca öyle kalır. Bir faturanın hangi okumadan
üretildiğini sormak, tek bir işlemin dört servis arasındaki yolunu istemek demektir; ölçüt hattı
bu yolu taşıyamaz, çünkü taşımak için işlem kimliğini etiket yapmak gerekir ve o etiketin
kardinalitesi işlem sayısı kadardır.

## Hiçbir Soruyu Yanıtlamayan Ölçüt

Son blok, toplanan verinin hangi bölümünün karşılığı olmadığını sayar. Yedi ölçütün üçü — süreç
başlangıç zamanı, çöp toplama duraklaması ve dosya tanıtıcı sayısı — on iki sorunun hiçbirinde
geçmez. Örnek başına seksen beş serinin **onu** budur, yüzde on iki. Çekme modelinde saatte 1,1
megabayt, otuz günlük saklamada sekiz yüz megabayttan fazla eder ve karşılığında hiçbir soru
kapanmaz.

Bu üç ölçüt kötü değildir; birer sorusu olmadığı için maliyettir. Çöp toplama duraklaması
yarın bir soru kümesine girerse aynı bayt anlamlı olur. Ölçüyü kuran şey ölçütün kendisi değil,
onu isteyen sorunun varlığıdır.

Soru başına maliyet iki modeli aynı ölçekte karşılaştırmayı sağlar: çekme 1,2, itme 1,6 megabayt.
İtme daha fazla soru yanıtlar ama soru başına yüzde otuz daha pahalıdır, çünkü on saniyelik
gönderim aralığı on beş saniyelik kazımadan sık, kimlik çoğalması da seri sayısını kırk kimliğe
yayıyor. "Hangisi daha iyi" sorusunun yanıtı tek bir sayıda değil, bu iki sütunun birlikte
okunmasındadır.

## Özet

- Soru kümesi on iki sorudan oluşur; her soru bir kaynak sınıfına, bir ölçüte ve bir etiket
  kümesine bağlıdır. Ölçü birimi toplanan bayt değil, yanıtlanan sorudur.
- Çekme temelli toplama 42 kısa ömürlü koşumun 13'ünü kapsar; envanter yenileme (30 sn) ile
  kazıma (15 sn) gecikmeleri üst üste bindiği için koşum kendisini görecek turdan önce biter.
- İtme temelli toplama kısa ömürlünün 42/42'sini kapsar ama kimliği süreç bildirdiği için 40 ömür
  40 ayrı kimlik üretir; kısa ömürlü tarafta 42 koşum 3 kimlik altında birleşir.
- Çekme 8/12, itme 9/12 soru yanıtlar; yanıtsız kalanlar kesişmez — çekmede S5, S6, S9, itmede
  S8, S9. S12 (bir faturanın hangi okumadan üretildiği) iki modelde de yanıtsızdır.
- Toplanan ölçütlerin 10/85 serisi (%11,8) hiçbir soruyu yanıtlamaz; çekmede saatte 1,1 MB.
  Soru başına maliyet çekmede 1,2, itmede 1,6 MB.
- Kapsanmayan koşumun bedeli sayıya bağlanır: seri üretmeyen 29 koşumdan birinin başarısızlığı
  ortalama 4,5 saat sonra, sabah raporunda görünür.

## Sonraki Adım

Bu derste toplanan veri bir kutu gibi ele alındı: ölçüm sayısı, seri sayısı, bayt. Oysa serinin
kendisi bir yapıdır ve o yapının içinde bir karar durur — hangi etiketler var. Yanıtlanan sekiz
ya da dokuz sorunun her biri belirli bir etiketin varlığına bağlıydı; `ornek` etiketi düştüğünde
iki soru kapandı. Bir sonraki ders bu bağı ters yönden ölçer: bir etiket **eklemek** hangi soruyu
açıyor, kaç seriye ve kaç bayta mal oluyor, ve hangi etiket eklendiğinde hiçbir soru açılmıyor.
