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.