İçeriğe geç
academia.sh

Ders 03 / 20

Bölme Kalıbı

Kaynak havuzunun akışlara göre ayrıştırılması: tek havuzda bir yavaş bağımlılığın bütün havuzu tüketmesiyle bölmeli düzenin aynı arıza senaryosunda karşılaştırılması, bölmenin komşu akışı algılamaya hiç bağlamadan koruması, bölmenin arızasız günde atıl kalan yuva ve düşen doluluk cinsinden bedeli ve bölme boyutunun iki gün arasındaki değiş tokuşu.

İçindekiler

Devre kesici bulaşmayı kesti ama koruması algılamadan sonra başlıyordu: eşik dolana kadar bozuk bağımlılık paylaşılan havuzdan yuva çekmeyi sürdürdü, oran 0,50 kuralında 220 yuva-tur. Eşiği düşürmek bu payı küçültüyor ama yanlış açılmayı büyütüyordu. Bu dersin sorusu şudur: bulaşmayı algılamaya hiç bağlamadan kesmek mümkün mü.

Mümkündür ve yolu havuzu bölmektir. Bölme kalıbı (bulkhead), çağıranın kaynaklarını akışlara ya da bağımlılıklara göre ayrı havuzlara ayırmaktır; bir akış yalnız kendi havuzunu tüketebilir ve tükettiğinde komşu akış hiçbir şey hissetmez. Adı gemi gövdesinin su geçirmez bölmelerinden gelir: bir bölme dolduğunda gemi batmaz, o bölme dolmuş olur. Buradaki bölme, Kabuk Programlama kursundaki dosya bölmeyle ve Trafik Katmanı kursundaki bölme kalanıyla aynı sözcüktür ama ayrı kavramdır: burada bölünen şey kaynak havuzudur.

Kesiciden farkı tek cümleyle söylenebilir. Kesici bağımlılığın bozuk olduğunu anlar ve çağrıyı durdurur; bölme hiçbir şey anlamaz, yalnız bozuk akışın tüketebileceği kaynağı baştan sınırlar. Biri karar verir, öteki sınır koyar.

Aynı Havuz, İki Düzen

Aşağıdaki koşum yine bir modeldir. 01. dersin ağ geçidi yuva havuzu ele alınıyor; tek fark varışların artık düzgün değil, tohumlu bir üreteçten çekilen Poisson varışları olmasıdır. Bunun nedeni bölmenin bedelinin ancak dalgalı varışta görünmesidir: düzgün akışta her akış kendi payını tam doldurur ve paylaşmanın bir kazancı yoktur.

Arıza senaryosu 01. dersteki senaryodur — taşıyıcı doğrulaması yavaşlıyor, olay bacağının tutuşu 6 turdan 22 tura çıkıyor, AY3’e göre ayda 3 kez ve 10 dakika sürüyor.

// bolme/kosum.mjs — tek havuz ile bolmeli duzenin ayni ariza senaryosunda karsilastirilmasi.
// MODELDIR: tur soyut bir adim, varislar tohumlu bir uretecten Poisson, bagimliligin kipi parametre.
const TOPLAM = 32, CEVRIM = 100, T = 4000, BAS = 1000;   // AY2, AY1; 40 s kosum, ariza 10. saniyede
const TAKIP = 416.67, OLAY = 97.22;                      // K01: tepe okuma ve tepe yazma istek/s
const TUTUS = { takip: 4, olay: 6 }, YAVAS = 22;         // 01. ders: ag gecidinin bacak sureleri

function kosum({ bolme, kip }) {                         // bolme: null ise tek havuz
  let s = 20260801 % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const poisson = (lam) => { const L = Math.exp(-lam); let k = 0, p = 1;
    do { k += 1; p *= rast(); } while (p > L); return k - 1; };
  const havuz = bolme === null ? { ortak: TOPLAM } : { takip: bolme, olay: TOPLAM - bolme };
  const yer = Object.fromEntries(Object.keys(havuz).map((h) => [h, []]));   // dolu yuvalarin bitis turu
  const ad = (akis) => (bolme === null ? "ortak" : akis);
  const c = { takipYanit: 0, takipDusen: 0, olayYanit: 0, olayDusen: 0, atil: 0, doluTur: 0 };

  for (let t = 0; t < T; t += 1) {
    for (const h of Object.keys(havuz)) yer[h] = yer[h].filter((x) => x > t);
    c.doluTur += Object.values(yer).reduce((a, x) => a + x.length, 0);
    const gelen = [];
    for (let n = poisson(TAKIP / CEVRIM); n > 0; n -= 1) gelen.push("takip");
    for (let n = poisson(OLAY / CEVRIM); n > 0; n -= 1) gelen.push("olay");
    for (let i = gelen.length - 1; i > 0; i -= 1) {
      const j = Math.floor(rast() * (i + 1));
      [gelen[i], gelen[j]] = [gelen[j], gelen[i]];
    }
    for (const akis of gelen) {
      const h = ad(akis);
      const sure = akis === "olay" && kip === "yavaslama" && t >= BAS ? YAVAS : TUTUS[akis];
      if (yer[h].length < havuz[h]) { yer[h].push(t + sure); c[`${akis}Yanit`] += 1; continue; }
      c[`${akis}Dusen`] += 1;
      for (const o of Object.keys(havuz)) if (o !== h) c.atil += havuz[o] - yer[o].length;
    }
  }
  return c;
}

const b = (x, n = 2) => x.toFixed(n);
const OLCUT = ["takipYanit", "takipDusen", "olayYanit", "olayDusen", "atil"];
const BASLIK = ["takip yanit", "takip dusen", "olay yanit", "olay dusen", "atil yuva"];
console.log(`model: ${T} tur (${T / CEVRIM} s), ariza ${BAS}. turda, toplam ${TOPLAM} yuva; ` +
  `varislar Poisson (tohum 20260801), takip ${(TAKIP / CEVRIM).toFixed(4)} ve olay ${(OLAY / CEVRIM).toFixed(4)} varis/tur`);

console.log(`\n${"duzen".padEnd(22)}${"gun".padEnd(12)}` + BASLIK.map((x) => x.padStart(13)).join("") +
  `${"ortalama dolu yuva".padStart(20)}`);
const r = {};
for (const [ad, bolme] of [["tek havuz (32)", null], ["bolmeli (24/8)", 24]])
  for (const kip of ["saglikli", "yavaslama"]) {
    const k = kosum({ bolme, kip });
    r[`${ad}|${kip}`] = k;
    console.log(`${ad.padEnd(22)}${kip.padEnd(12)}` + OLCUT.map((x) => String(k[x]).padStart(13)).join("") +
      `${b(k.doluTur / T).padStart(20)}`);
  }

const ts = r["tek havuz (32)|saglikli"], bs = r["bolmeli (24/8)|saglikli"];
const ty = r["tek havuz (32)|yavaslama"], by = r["bolmeli (24/8)|yavaslama"];
const olcek = (600 * CEVRIM) / (T - BAS);          // AY3: 10 dakikalik arizaya olcekleme
console.log(`\narizasiz gunun bedeli: takip dusen ${ts.takipDusen} -> ${bs.takipDusen}, olay dusen ` +
  `${ts.olayDusen} -> ${bs.olayDusen}; ortalama dolu yuva ${b(ts.doluTur / T)} -> ${b(bs.doluTur / T)} ` +
  `(doluluk ${b(ts.doluTur / T / TOPLAM, 3)} -> ${b(bs.doluTur / T / TOPLAM, 3)}); atil yuva ${ts.atil} -> ${bs.atil}`);
console.log(`arizali gunun kazanci: takip dusen ${ty.takipDusen} -> ${by.takipDusen} ` +
  `(%${b((100 * (ty.takipDusen - by.takipDusen)) / ty.takipDusen, 1)} az), olay dusen ` +
  `${ty.olayDusen} -> ${by.olayDusen}; AY3'un 10 dakikasinda kurtarilan takip istegi ` +
  `${((ty.takipDusen - by.takipDusen) * olcek).toFixed(0)}`);

console.log(`\n${"takip/olay yuvasi".padEnd(20)}${"arizasiz takip dusen".padStart(21)}` +
  `${"arizasiz olay dusen".padStart(20)}${"yavaslamada takip dusen".padStart(24)}` +
  `${"yavaslamada olay dusen".padStart(23)}`);
for (const bolme of [null, 28, 24, 20, 16]) {
  const s = kosum({ bolme, kip: "saglikli" }), y = kosum({ bolme, kip: "yavaslama" });
  const etiket = bolme === null ? `tek havuz (${TOPLAM})` : `${bolme}/${TOPLAM - bolme}`;
  console.log(`${etiket.padEnd(20)}${String(s.takipDusen).padStart(21)}${String(s.olayDusen).padStart(20)}` +
    `${String(y.takipDusen).padStart(24)}${String(y.olayDusen).padStart(23)}`);
}
const g36 = kosum({ bolme: 27, kip: "saglikli" });
console.log(`duyarlilik: 24/8 yerine 27/5 olsaydi arizasiz gunde takip dusen ${bs.takipDusen} -> ` +
  `${g36.takipDusen}, olay dusen ${bs.olayDusen} -> ${g36.olayDusen}; olay bolmesi ` +
  `${b(((OLAY / CEVRIM) * TUTUS.olay) / 8, 3)} dolulukta calisirken 5 yuvada ` +
  `${b(((OLAY / CEVRIM) * TUTUS.olay) / 5, 3)} olur`);
model: 4000 tur (40 s), ariza 1000. turda, toplam 32 yuva; varislar Poisson (tohum 20260801), takip 4.1667 ve olay 0.9722 varis/tur

duzen                 gun           takip yanit  takip dusen   olay yanit   olay dusen    atil yuva  ortalama dolu yuva
tek havuz (32)        saglikli            16542           78         3931           27            0               17.31
tek havuz (32)        yavaslama           13966         2654         3358          600            0               24.00
bolmeli (24/8)        saglikli            16448          172         3552          406         4239               16.77
bolmeli (24/8)        yavaslama           16448          172         1947         2011        19196               18.90

arizasiz gunun bedeli: takip dusen 78 -> 172, olay dusen 27 -> 406; ortalama dolu yuva 17.31 -> 16.77 (doluluk 0.541 -> 0.524); atil yuva 0 -> 4239
arizali gunun kazanci: takip dusen 2654 -> 172 (%93.5 az), olay dusen 600 -> 2011; AY3'un 10 dakikasinda kurtarilan takip istegi 49640

takip/olay yuvasi    arizasiz takip dusen arizasiz olay dusen yavaslamada takip dusen yavaslamada olay dusen
tek havuz (32)                         78                  27                    2654                    600
28/4                                   11                1754                      11                   2876
24/8                                  172                 406                     172                   2011
20/12                                 868                  37                     868                   1416
16/16                                2591                   0                    2591                    942
duyarlilik: 24/8 yerine 27/5 olsaydi arizasiz gunde takip dusen 172 -> 26, olay dusen 406 -> 1303; olay bolmesi 0.729 dolulukta calisirken 5 yuvada 1.167 olur

Bu sayılar ölçüm sınıfındadır ve tohuma bağlıdır.

Bölme Arızalı Günü Değiştirmiyor

İlk tablonun okunması dördüncü satırdan başlamalı, çünkü orada bir sayı çifti tekrar ediyor. Bölmeli düzende takip sorgusunun düşen istek sayısı sağlıklı günde 172, yavaşlama gününde de 172. Aynı sayı. Bağımlılık yavaşlasa da yavaşlamasa da takip akışı için hiçbir şey değişmiyor — çünkü olay akışının tüketebileceği yuva sayısı sekizle sınırlıdır ve o sekiz yuva takip akışının yirmi dördüne hiçbir koşulda dokunamaz.

Tek havuzda ise aynı arıza takip sorgusunun 2654 isteğini düşürüyor. Bölme bunu 172’ye indiriyor: yüzde 93,5 az. AY3’ün 10 dakikalık yavaşlamasına ölçeklendiğinde 49.640 kurtarılan takip isteği eder. Ve bu koruma hiçbir algılamaya bağlı değildir; kesicinin dokuz turluk algılama penceresi burada yoktur, çünkü karar verilmiyor.

Kalıbın ne yapmadığı da aynı satırda. Bölmeli düzende olay akışının düşen isteği 600’den 2011’e çıkıyor. Bölme olay akışını kurtarmıyor, tersine daha erken boğuyor; kurtardığı şey komşudur. Kalıbın adı bunu zaten söylüyor — su alan bölme dolmaya devam eder.

Arızasız Günün Bedeli: Kaybedilen Paylaşım

İlk iki satır bedeli veriyor ve bedel küçük değildir. Sağlıklı günde tek havuz 78 takip ve 27 olay isteği düşürüyor; toplam 105. Aynı gün bölmeli düzende 172 takip ve 406 olay isteği düşüyor; toplam 578. Hiçbir arıza yokken bölme, düşen istek sayısını 5,5 katına çıkarıyor.

Nedeni atil yuva sütunundadır. Bölmeli düzende bir istek düştüğünde öteki bölmede boş duran yuva sayısı toplanıyor ve sağlıklı günde bu toplam 4239 ediyor: 4239 kez bir istek, komşu bölmede boş yuva dururken reddedildi. Tek havuzda bu sayı tanımı gereği sıfırdır, çünkü boş yuva kimin olduğuna bakmaz. Ortalama dolu yuva 17,31’den 16,77’ye, doluluk 0,541’den 0,524’e iniyor — aynı işi daha az kaynakla değil, aynı kaynağı daha az kullanarak yapıyor.

Kaybedilen şeyin adı paylaşımdır: dalgalı iki akış tek havuzu paylaştığında birinin tepesi ötekinin çukuruyla örtüşür ve toplam tepe, tepelerin toplamından küçük olur. Bölme bu örtüşmeyi yasaklar. Arızasız günün bedeli budur ve doğrudan ölçülebilir: 94 fazladan düşen takip isteği, 379 fazladan düşen olay isteği, 0,017 düşen doluluk.

Bölme Boyutu İki Günü Birbirine Karşı Koyuyor

İkinci tablo boyut seçimini gösteriyor ve seçimin tek bir doğrusu olmadığını.

28/4 bölmesi takip akışını neredeyse kusursuz koruyor: yavaşlamada yalnız 11 istek düşüyor, tek havuzun 2654’üne karşı. Bedeli arızasız gündedir — olay akışının dört yuvası yetmiyor ve sağlıklı günde 1754 olay düşüyor. 16/16 bölmesi tersini yapıyor: olay akışı arızasız günde hiç düşmüyor, buna karşılık takip akışı 2591 istek kaybediyor, yani tek havuzdaki arıza günü kadar. Bölme yanlış boyutlandırıldığında arızasız günde arızalı gün kadar zarar verir.

24/8 ikisinin arasındadır ve seçilme gerekçesi ölçülebilir: olay akışının ortalama yükü 0,9722 varış/tur çarpı 6 tur, yani 5,83 yuva; sekiz yuva bunun 1,37 katıdır. Duyarlılık satırı payın daraltılmasının bedelini veriyor — 27/5’te takip düşen 172’den 26’ya iner ama olay düşen 406’dan 1303’e çıkar, çünkü olay bölmesinin doluluğu 0,729’dan 1,167’ye, yani kapasitenin üstüne geçer. Bir bölme, kendi akışının olağan yükünü taşıyamayacak kadar küçültülürse arıza beklemeden arızalanır.

Bölme ile kesici birbirinin yerine geçmez. Bölme bulaşmayı algılamasız keser ama bozuk bağımlılığa yapılan çağrıyı kesmez: bölmeli yavaşlama koşumunda olay akışı hâlâ bozuk bağımlılığı çağırıyor ve kendi sekiz yuvasını tüketiyor. Kesici o çağrıları durdurur ama önce anlaması gerekir. İkisi ayrı sayıyı oynatır — bölme komşunun düşen isteğini, kesici bozuk bağımlılığa yapılan çağrıyı.

Özet

  • Bölme kalıbı çağıranın kaynak havuzunu akışlara göre ayırır; bir akış yalnız kendi havuzunu tüketebilir. Kesiciden farkı karar vermemesidir — sınır baştan konur, algılama gerekmez.
  • Bölme arızalı günü komşu akış için görünmez kılıyor: bölmeli düzende takip sorgusunun düşen isteği sağlıklı günde de yavaşlama gününde de 172. Tek havuzda aynı arıza 2654 istek düşürüyor; kazanç yüzde 93,5, AY3’ün 10 dakikasında 49.640 istek.
  • Bölme bozuk akışı kurtarmaz, daha erken boğar: olay akışının düşen isteği 600’den 2011’e çıkıyor.
  • Arızasız günün bedeli kaybedilen paylaşımdır: düşen istek 105’ten 578’e (5,5 kat), doluluk 0,541’den 0,524’e; 4239 kez bir istek komşu bölmede boş yuva dururken reddediliyor.
  • Boyut iki günü birbirine karşı koyar: 28/4 yavaşlamada yalnız 11 takip isteği düşürür ama arızasız günde 1754 olay isteği; 16/16 olay akışını hiç düşürmez ama arızasız günde 2591 takip isteği kaybettirir.
  • Bölme kendi akışının olağan yükünü taşımalıdır: olay akışı 5,83 yuva ister, 8 yuva bunun 1,37 katıdır; 5 yuvada doluluk 1,167 olur ve bölme arıza olmadan arızalanır.

Sonraki Adım

Bölme ile kesici birlikte bir sınır çiziyor: bozuk bağımlılık kendi bölmesinde kalıyor ve bir süre sonra hiç çağrılmıyor. İkisi de aynı varsayımın üstünde duruyor — başarısız olan çağrı bir kez yapılıyor. Oysa gerçek bir çağıran başarısızlığı öyle karşılamaz; yeniden dener, çünkü hataların çoğu geçicidir ve ikinci deneme çoğu zaman başarılı olur. Yeniden deneme bu iki kalıbın ölçtüğü her şeyi değiştirir: bölmedeki yuvalar daha hızlı tükenir, kesicinin penceresine daha çok başarısızlık düşer ve en önemlisi bozuk bağımlılık, kendisini zaten zorlayan sistemden daha çok istek alır. Sonraki ders bu çarpanı ölçer: zincirin her katmanı denerse bağımlılığa varan istek kaça katlanır, fırtına arızayı nasıl uzatır ve deneme hakkı zincirin hangi katmanına verilmelidir.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat