Ders 17 / 20
Talep Fişi Kalıbı
Büyük yükün ileti dışında taşınması: teslim kanıtının iletiyi 40.220 bayta çıkarması, fişin ileti baytını 141,6 kat düşürmesi, kuyruk üzerindeki birikmenin 3016,5 MB'den 21,3 MB'ye inmesi, kanıtın saklama tarafında hiç küçülmemesi ve tek yazmanın ikiye bölünmesiyle doğan yetim yük ile sarkan fiş.
İçindekiler
Önceki iki ders iş akışının adımlarını doğru tuttu: yineleme bastırıldı, yarım kalan adımlar dengelendi. İş akışının taşıdığı veri hiç sorulmadı. Taşıyıcı bir teslimi bildirirken yanına teslim kanıtını koyar — alıcının imzası ya da teslim noktasının görüntüsü. Bu ek, K01’in 220 baytlık durum olayı kaydını başka bir mertebeye taşır ve o bayt kuyruğun içinden geçer, her tüketiciye kopyalanır, her yeniden teslimde yeniden taşınır.
Talep fişi (claim check), büyük yükü ayrı bir depoya yazıp iletide yalnız o yükün başvurusunu taşıyan yerleşimdir. Bu dersin ölçüleri dörttür: iletinin boyutu, kuyruk üzerinden geçen bayt, yükün ayrı depoda yaşama süresi ve fişin sarkması — yükün silinmiş, fişin elde kalmış olması.
İki Yazma, Tek İşlem Sınırı Yok
DD8 — teslim kanıtı 40.000 bayt. Gerekçesi: kanıt sıkıştırılmış bir imza görüntüsüdür ve K01’in 900 baytlık gönderi kaydının iki mertebe üstündedir. Duyarlılığı ileti baytı oranıyla zaten görünür. DD9 — talep fişi kaydı 64 bayt: depo adı, nesne anahtarı ve özet.
Kalıbın gizli maliyeti buradan başlar. İliştirilmiş yerleşimde tek bir yazma vardır: ileti kuyruğa gider ve kanıt onun içindedir. Fişli yerleşimde iki yazma vardır — önce kanıt depoya, sonra ileti kuyruğa — ve ikisinin ortak bir işlem sınırı yoktur. Veri Erişim Katmanı kursunun dağıtık işlem sorunu tam olarak budur. İki yeni arıza kipi doğar: yetim yük (kanıt yazıldı, ileti yazılamadı) ve sarkan fiş (ileti elde, kanıt silinmiş).
// fis/kuyruk.mjs — teslim kaniti tasiyan olay akisinin surec ici modeli. // Gercek kuyruk, depo ve ag yoktur: kuyruk bir dizi, yuk deposu bir kume, bayt sayilir. export const OLAY = 220, KANIT = 40_000, FIS = 64; // K01 V6; DD8 kanit; DD9 fis kaydi export function uretec(tohum) { // 32 bitlik dogrusal esitlikli uretec, tohum acik let s = tohum >>> 0; return () => { s = (Math.imul(s, 1103515245) + 12345) >>> 0; return s / 4294967296; }; } // yerlesim: "ilistir" = kanit iletinin icinde; "fis" = kanit depoda, ileti fis tasir // silme: "hemen" = tuketici isleyince siler; "sure" = yasam suresi doldurur export function kos({ n, yerlesim, silme, uretiCokme, onaysizCokme, tohum }) { const rnd = uretec(tohum); const fisli = yerlesim === "fis"; const ileti = fisli ? OLAY + FIS : OLAY + KANIT; const depo = new Set(), kuyruk = []; const s = { ileti, tasinanBayt: 0, teslim: 0, kayipOlay: 0, yetimYuk: 0, sarkanFis: 0, islenen: 0, depodaKalan: 0 }; for (let i = 0; i < n; i += 1) { if (fisli) depo.add(i); // once yuk yazilir const coktu = rnd() < uretiCokme; // sonra ileti yazilir; arasinda cokme if (coktu) { if (fisli) s.yetimYuk += 1; else s.kayipOlay += 1; continue; } kuyruk.push({ no: i, deneme: 0 }); } while (kuyruk.length > 0) { const m = kuyruk.shift(); s.tasinanBayt += ileti; s.teslim += 1; // her teslim iletiyi bastan tasir if (fisli && !depo.has(m.no)) { s.sarkanFis += 1; continue; } s.islenen += 1; if (fisli && silme === "hemen") depo.delete(m.no); if (rnd() < onaysizCokme && m.deneme === 0) kuyruk.push({ no: m.no, deneme: 1 }); } s.depodaKalan = fisli ? depo.size : 0; return s; }
Arıza senaryosu adıyla tanımlanır. DD10 — arıza penceresinde üreticinin iki yazma arasında çökme olasılığı 0,005, tüketicinin onaydan önce çökme olasılığı 0,01. Gerekçesi: birinci pencere iki uzak yazma arasındaki kısa aralık, ikincisi işleme ile onay arasındaki aralıktır ve ikincisi daha uzundur. İkisi de varsayımdır, K01’in tablosuna eklenmez.
// fis/olc.mjs — dort yerlesim, ariza yokken ve varken; ileti bayti ile sarkma sayilir import { kos, OLAY, KANIT, FIS } from "./kuyruk.mjs"; const N = 100_000; const DURUM = [["arizasiz gun", 0, 0], ["ariza penceresi (DD10)", 0.005, 0.01]]; const YER = [["ilistir", "-"], ["fis", "hemen"], ["fis", "sure"]]; console.log(`ileti bayti: ilistirilmis ${OLAY + KANIT}, fisli ${OLAY + FIS} ` + `(K01 V6 = ${OLAY} bayt olay, DD8 = ${KANIT} bayt kanit, DD9 = ${FIS} bayt fis)`); for (const [ad, uretiCokme, onaysizCokme] of DURUM) { console.log(`\n${ad}: ${N} teslim olayi, uretici cokme ${uretiCokme}, onaysiz cokme ${onaysizCokme}`); console.log(`${"yerlesim".padEnd(16)}${"teslim".padStart(9)}${"tasinan MB".padStart(12)}` + `${"kayip olay".padStart(12)}${"yetim yuk".padStart(11)}${"sarkan fis".padStart(12)}` + `${"islenen".padStart(9)}${"depoda".padStart(9)}`); for (const [yerlesim, silme] of YER) { const r = kos({ n: N, yerlesim, silme, uretiCokme, onaysizCokme, tohum: 20260730 }); console.log(`${`${yerlesim} ${silme}`.padEnd(16)}${String(r.teslim).padStart(9)}` + `${(r.tasinanBayt / 1e6).toFixed(2).padStart(12)}${String(r.kayipOlay).padStart(12)}` + `${String(r.yetimYuk).padStart(11)}${String(r.sarkanFis).padStart(12)}` + `${String(r.islenen).padStart(9)}${String(r.depodaKalan).padStart(9)}`); } }
ileti bayti: ilistirilmis 40220, fisli 284 (K01 V6 = 220 bayt olay, DD8 = 40000 bayt kanit, DD9 = 64 bayt fis) arizasiz gun: 100000 teslim olayi, uretici cokme 0, onaysiz cokme 0 yerlesim teslim tasinan MB kayip olay yetim yuk sarkan fis islenen depoda ilistir - 100000 4022.00 0 0 0 100000 0 fis hemen 100000 28.40 0 0 0 100000 0 fis sure 100000 28.40 0 0 0 100000 100000 ariza penceresi (DD10): 100000 teslim olayi, uretici cokme 0.005, onaysiz cokme 0.01 yerlesim teslim tasinan MB kayip olay yetim yuk sarkan fis islenen depoda ilistir - 100495 4041.91 492 0 0 100495 0 fis hemen 100495 28.54 0 492 987 99508 492 fis sure 100495 28.54 0 492 0 100495 100000
Bu sayılar ölçüm sınıfındadır: süreç içi bir modelden, tohumu 20260730 olan bir üreteçten gelirler.
Silme Politikası Bir Doğruluk Kararıdır
Üst tablo ileti baytını veriyor: iliştirilmiş yerleşim yüz bin olay için 4022,00 MB taşıyor, fişli yerleşim 28,40 MB. Oran, ileti baytlarının oranıdır ve arıza yokken başka hiçbir fark yok.
Alt tablo asıl ayrımı yapıyor ve dikkat isteyen sütun islenen. İliştirilmiş yerleşimde
üreticinin çökmesi 492 olayı tümden düşürüyor — kanıt ile olay tek yazmadaydı, ikisi birden
gitti. Fişli yerleşimde aynı çökme olayı yine kaybettiriyor ama depoda 492 yetim yük bırakıyor;
kayıp eşit, artık bir de çöp var.
İki silme politikası aynı arızada farklı davranıyor. Hemen silmede 987 yeniden teslim kanıtı bulamıyor ve sarkan fişe dönüşüyor; işlenen sayısı 99.508’de, yani her olay tam bir kez işlenmiş oluyor. Yaşam süresine bırakmada sarkan fiş sıfır, ama işlenen 100.495: 987 yeniden teslimin hepsi kanıtı buluyor ve işi yeniden yapıyor.
Bu, kalıbın en az fark edilen sonucudur. Yükün silinme anı, farkında olunmadan bir tekillik denetimine dönüşür: hemen silme yinelenen işlemeyi engeller ama yeniden teslimi bir hataya çevirir; yaşam süresine bırakma yeniden teslimi çalıştırır ve yinelenen yan etkiyi birinci dersin defterine havale eder. Doğru kurulum ikisini ayırmaktır — tekillik kararı defterde verilir, silme kararı depoda; yükün ömrü bir doğruluk mekanizması olarak kullanılmaz.
Hesaba Dönüş
DD11 — kanıt yaşam süresi 7 gün. Gerekçesi: teslim itirazı teslim gününden sonraki iş günü içinde gelir ve kanıt o pencerede istenir; itirazsız kanıt saklanmaz. Duyarlılığı 1 ve 30 günle verilir.
// fis/bedel.mjs — olculen ileti baytlarinin K01 olceginde kuyruga, saklamaya ve sarkmaya cevrilmesi const V3 = 400_000, V8 = 3, GUN = 86_400; // K01: gunluk gonderi, tepe carpani const YAZMA_MBIT = 0.17, ARTIS_MB = 976, SAKLAMA_GB = 712.48; // K01 hesaplari const BIRIKME = 525_000, OLAY_PAYI = 7; // M19/K03 mesaj kuyruklari: en yuksek birikme const ILISTIR = 40_220, FISLI = 284, KANIT = 40_000; // fis/olc.mjs olcumu; DD8 const teslim = (V3 / GUN) * V8; // her gonderi bir teslim olayi uretir console.log(`tepe teslim olayi ${teslim.toFixed(4)} olay/s (K01: gunde ${V3} gonderi, tepe carpani ${V8})`); console.log(`\n${"yerlesim".padEnd(12)}${"ileti bayt".padStart(12)}${"kuyruk Mbit/s".padStart(15)}` + `${"K01 yazma girisinin".padStart(21)}${"birikmede MB".padStart(14)}`); for (const [ad, b] of [["ilistir", ILISTIR], ["fis", FISLI]]) { const mbit = (teslim * b * 8) / 1e6, birikme = ((BIRIKME / OLAY_PAYI) * b) / 1e6; console.log(`${ad.padEnd(12)}${String(b).padStart(12)}${mbit.toFixed(4).padStart(15)}` + `${`${(mbit / YAZMA_MBIT).toFixed(2)} kat`.padStart(21)}${birikme.toFixed(1).padStart(14)}`); } console.log(`kuyruk bayti orani ${(ILISTIR / FISLI).toFixed(1)} kat; ` + `birikme ${(BIRIKME / OLAY_PAYI).toLocaleString("tr-TR")} kanitli ileti (M19/K03: ${BIRIKME.toLocaleString("tr-TR")} olay / ${OLAY_PAYI})`); console.log(`\n${"DD11 yasam suresi".padStart(18)}${"depoda kanit".padStart(14)}${"depoda GB".padStart(12)}` + `${"K01 saklamanin".padStart(16)}${"gunluk artisin".padStart(16)}`); for (const gun of [1, 7, 30]) { const adet = V3 * gun, gb = (adet * KANIT) / 1e9; console.log(`${`${gun} gun`.padStart(18)}${adet.toLocaleString("tr-TR").padStart(14)}` + `${gb.toFixed(2).padStart(12)}${`%${((100 * gb) / SAKLAMA_GB).toFixed(2)}`.padStart(16)}` + `${`${((gb * 1000) / ARTIS_MB).toFixed(2)} kat`.padStart(16)}`); } const SARKAN = 987 / 100_000, YETIM = 492 / 100_000; // fis/olc.mjs olcumu console.log(`\nariza penceresi K01 olceginde (gunde ${V3.toLocaleString("tr-TR")} teslim olayi):`); console.log(`sarkan fis ${(V3 * SARKAN).toFixed(0)}/gun, yetim yuk ${(V3 * YETIM).toFixed(0)}/gun`); console.log(`yetim yukun bayti ${((V3 * YETIM * KANIT) / 1e6).toFixed(1)} MB/gun, ` + `yasam suresi yoksa yilda ${((V3 * YETIM * KANIT * 365) / 1e9).toFixed(2)} GB`); console.log(`ilistirilmis yerlesimde ayni cokme ${(V3 * YETIM).toFixed(0)} olayi tumden dusuruyor`);
tepe teslim olayi 13.8889 olay/s (K01: gunde 400000 gonderi, tepe carpani 3)
yerlesim ileti bayt kuyruk Mbit/s K01 yazma girisinin birikmede MB
ilistir 40220 4.4689 26.29 kat 3016.5
fis 284 0.0316 0.19 kat 21.3
kuyruk bayti orani 141.6 kat; birikme 75.000 kanitli ileti (M19/K03: 525.000 olay / 7)
DD11 yasam suresi depoda kanit depoda GB K01 saklamanin gunluk artisin
1 gun 400.000 16.00 %2.25 16.39 kat
7 gun 2.800.000 112.00 %15.72 114.75 kat
30 gun 12.000.000 480.00 %67.37 491.80 kat
ariza penceresi K01 olceginde (gunde 400.000 teslim olayi):
sarkan fis 3948/gun, yetim yuk 1968/gun
yetim yukun bayti 78.7 MB/gun, yasam suresi yoksa yilda 28.73 GB
ilistirilmis yerlesimde ayni cokme 1968 olayi tumden dusuruyor
İki Günün Sayısı
Arızasız günün bedeli üç kalemdir. Her teslim olayı artık iki yazma ve tüketici tarafında bir fazladan okuma taşır; tek yazmanın atomikliği kaybedilmiştir. Depoda kanıt DD11 = 7 gün ile 112,00 GB durur, K01’in 712,48 GB’lık saklama satırının yüzde 15,72’si. Ve saklama tarafında kalıbın hiçbir kazancı yoktur: kanıt iliştirilmiş olsa da fişli olsa da aynı 40.000 baytı kaplar. Talep fişi bir saklama kararı değil, bir taşıma kararıdır.
Arızalı günün kazancı kuyruktadır. İliştirilmiş yerleşimde tepe teslim akışı kuyruğa 4,4689 Mbit/s bindiriyor — K01’in 0,17 Mbit/s’lik yazma girişinin 26,29 katı. Fişli yerleşimde 0,0316 Mbit/s, yani yazma girişinin 0,19 katı. Asıl fark birikmede görünüyor: Uygulama Katmanı ve Servis Etkileşimi kursunun ölçtüğü 525.000 olayın yedide biri kanıtlı ileti olduğuna göre kuyruk iliştirilmiş yerleşimde 3016,5 MB, fişli yerleşimde 21,3 MB taşımak zorunda. Kuyruğun sınırlı bir tampon olduğu bir tasarımda bu 141,6 katlık fark, aynı sınırda tutulabilen olay sayısının farkıdır.
Kazancın karşılığı yeni arıza kipleridir. K01 ölçeğinde arıza penceresinde günde 1968 yetim yük (78,7 MB) ve hemen silme politikasında 3948 sarkan fiş oluşuyor. Yaşam süresi olmadan yetim yükler yılda 28,73 GB’a çıkar; DD11 bir saklama parametresi değil, çöp toplama mekanizmasıdır. Sarkan fiş ise veri kaybı değildir — 3948’in hepsi zaten işlenmiş işin yeniden teslimidir — ama tüketici tarafında hata olarak görünür ve ölü ileti yolundan ayrılmazsa gerçek hataları gizler.
Özet
- Teslim kanıtı iletiyi 220 bayttan 40.220 bayta çıkarıyor; talep fişi 284 bayta indiriyor, oran 141,6 kat.
- Kuyruk yükü: tepe teslim akışı iliştirilmiş yerleşimde 4,4689 Mbit/s (K01 yazma girişinin 26,29 katı), fişli yerleşimde 0,0316 Mbit/s (0,19 katı).
- Birikmede fark büyüyor: 75.000 kanıtlı iletilik birikme 3016,5 MB yerine 21,3 MB tutuyor.
- Saklama tarafında kalıbın kazancı yok: kanıt DD11 = 7 gün ile 112,00 GB, K01 saklamasının yüzde 15,72’si; talep fişi taşıma kararıdır, saklama kararı değil.
- Kalıp tek yazmayı ikiye bölüyor ve iki yeni arıza kipi getiriyor: günde 1968 yetim yük (78,7 MB, yaşam süresi olmazsa yılda 28,73 GB) ve 3948 sarkan fiş.
- Silme politikası sessizce bir doğruluk kararıdır: hemen silmede işlenen 99.508 (tam bir kez), yaşam süresine bırakmada 100.495 (987 yinelenen işleme); ikincisi tekillik defterine dayanır.
Sonraki Adım
Kanıt kuyruktan çıktı ama yolun tamamı hâlâ servisin içinden geçiyor. Taşıyıcı kanıtı servise yüklüyor, servis depoya yazıyor; alıcı kanıtı görmek istediğinde servis depodan okuyup istemciye aktarıyor. Kuyruktan kaldırılan 40.000 bayt, servisin isteğe bağlı yolunda iki kez geçmeye devam ediyor ve depo yavaşladığında servisin kendi işçilerini tutuyor. Sonraki ders bu baytı servisin üzerinden de kaldırmayı ele alır: istemciye doğrudan kaynak erişimi için verilen sınırlı yetki, servisin üzerinden geçmeyen bayt, açılan yetki penceresi ve kapsamı daraltmanın kaça mal olduğu.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.