Ders 06 / 20
Geri Basınç
Aşırı yük sinyalinin servis sınırından geriye yayılması: yayılma derinliğinin sıfırdan sınıra kadar dört ayarda ölçülmesi, kısmi yayılmanın kaybı yalnız bir halka geriye taşıması, sinyal sınıra ulaştığında kabul edilip kaybolan yazmanın hiç kabul edilmeyen yazmaya dönüşmesi ve sınırsız tamponun kaybı bayatlığa çevirmesi.
İçindekiler
Bir önceki ders bütçeyi tek bir isteğin süresine kurdu ve o isteğin kaynağını zamanında geri almayı öğretti. Bütçenin dokunmadığı bir şey var: isteklerin gelme hızı. Yavaşlayan bir bağımlılık karşısında bütçe her isteği ayrı ayrı keser, ama bir sonraki istek yine gelir ve yine aynı yavaş adıma harcanır. Bütçe bir isteğin ne kadar bekleyeceğini söyler; sisteme iş veren tarafa hiçbir şey söylemez.
Bu ders o eksik bildirimi ele alır ve yazma yolunda sorar. Taşıyıcıdan gelen durum olayları sabit bir hızla akar; olay kütüğünü okuyup okuma modelini besleyen tüketici yavaşlarsa iş bir yerlerde birikir. Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursu bunu tek bir kuyrukta kurdu: sınırlı kuyruk bir gecikme bütçesi kararıdır, taşma politikaları vardır, engelleme yavaşlığı üreticiye geçirir ve akış dönüşünü yok sayan katman önündeki sınırı boşa çıkarır. O mekanik burada tekrarlanmaz. Buradaki soru zincirle ilgilidir: sinyal kaç halka geriye taşınır, taşınmadığı yerde iş nerede toplanır ve yayılma nerede durmak zorundadır.
Arıza Kipi ve Zincir
Yazma yolu dört parçadır: taşıyıcının bildirim ucu olayı gönderir, giriş servisi kabul eder, kütük yazıcısı kalıcılaştırır, izdüşüm tüketicisi okuma modelini günceller. Kaynak sistemin dışındadır — taşıyıcı başka bir kuruluşun sistemidir ve bu sistemin denetiminde değildir.
AY11 — izdüşüm tüketicisi geri kalıyor. Durmuyor, yanlış yazmıyor; işleme hızı turda 120 olaydan 60 olaya iniyor. Süre 20 dakika, sıklık ayda üç kez. Gerekçe: tüketici yavaşlaması genellikle izdüşüm şemasının değişmesinden ya da yeniden oluşturma işiyle çakışmadan doğar ve iş bitene kadar sürer. Duyarlılığı aşağıda hesaplanmıştır. Bu varsayım K01’in tablosuna eklenmez.
AY11 bir kesinti değildir; takip sorgusu yanıtlanmaya devam eder, yalnız okuduğu izdüşüm geride kalır. Bu yüzden K01’in aylık 43,2 dakikalık kesinti bütçesine yazılmaz. Kayıp yazma ise başka bir ölçüye girer ve eşiği bu kursun kurtarma konusunda konur.
Bir tur soyut bir adımdır; modelde bir saniyelik iş penceresine karşılık gelir ve bu çevrim katsayısı bir varsayımdır. Kaynağın hızı K01’in tepe yazma sayısıdır: turda 97,22 olay. Varış düz değil salınımlıdır — ortalaması 1,00 olan bir çarpan döngüsü, tepe saat içindeki dalgalanmayı temsil eder.
Yayılma Derinliği
Sinyal, tüketiciden geriye doğru taşınan tek bir bilgidir: “ardılım dolu, sana iş veremem.” Her halka bu bilgiye uyabilir ya da yok sayabilir. Modelde bu bir parametredir — derinlik, sinyalin tüketiciden kaç halka geriye taşındığı. Derinlik 0’da hiçbir halka uymaz, derinlik 3’te sinyal servis sınırına ulaşır ve taşıyıcının olayı kabul edilmez.
// geri/zincir.mjs — yazma yolunun MODELI. Tur soyut bir adimdir; cevrim katsayisi // varsayimdir (bir tur = bir saniye). Gercek kuyruk, kutuk ya da tuketici kurulmaz. export const K01 = { tepeYazma: 97.22 }; // K01: tasiyici durum olayi, tepe yazma/s // Halkalar kaynaktan uca dogru siralidir. `hiz` bir turda islenen olay sayisidir. export const HALKA = [ { ad: "giris", kap: 200, hiz: 250 }, // olay kabul ucu { ad: "kutuk", kap: 150, hiz: 150 }, // olay kutugu yazicisi { ad: "izdusum", kap: 100, hiz: 120 }, // okuma modelini besleyen tuketici ]; // Tepe saat icinde varisin salinimi: ortalamasi 1,00 olan bir carpan dongusu. export const SALINIM = [0.6, 0.6, 0.6, 2.2]; // Halka i, ardilinin doluluguna uyuyorsa durur; uymuyorsa olayi kaybeder. // derinlik: sinyalin tuketiciden geriye kac halka tasindigi. 3 = sinira kadar. const uyar = (i, derinlik) => derinlik >= HALKA.length - 1 - i; export function kosum({ turSayisi, derinlik, tuketimHizi, salinim = true, sinirsiz = false }) { const hiz = HALKA.map((h, i) => (i === HALKA.length - 1 ? tuketimHizi : h.hiz)); const kap = HALKA.map((h) => (sinirsiz ? Infinity : h.kap)); const tampon = HALKA.map(() => []); const s = { uretilen: 0, tamamlanan: 0, reddedilen: 0, enBuyukYas: 0, sinirDurdu: 0, kaybolan: HALKA.map(() => 0), duraklatilan: HALKA.map(() => 0), }; let birikim = 0; for (let t = 1; t <= turSayisi; t += 1) { for (let i = HALKA.length - 1; i >= 0; i -= 1) { // uctan kaynaga dogru bosalt let n = Math.min(hiz[i], tampon[i].length); while (n > 0) { if (i === HALKA.length - 1) { // son halka: is tamamlanir s.enBuyukYas = Math.max(s.enBuyukYas, t - tampon[i].shift()); s.tamamlanan += 1; n -= 1; continue; } if (tampon[i + 1].length < kap[i + 1]) { tampon[i + 1].push(tampon[i].shift()); n -= 1; continue; } if (uyar(i, derinlik)) { s.duraklatilan[i] += 1; break; } // ardil dolu: dur s.kaybolan[i + 1] += 1; tampon[i].shift(); n -= 1; // sinyal yok: kaybet } } const carpan = salinim ? SALINIM[(t - 1) % SALINIM.length] : 1; birikim += K01.tepeYazma * carpan; while (birikim >= 1) { // kaynak: tasiyici bildirim ucu birikim -= 1; s.uretilen += 1; if (tampon[0].length < kap[0]) { tampon[0].push(t); continue; } if (derinlik >= HALKA.length) { // sinirda reddet: olay kabul edilmez s.reddedilen += 1; s.sinirDurdu += 1; } else s.kaybolan[0] += 1; // kabul edildi, sonra kayboldu } } s.biriken = tampon.reduce((a, b) => a + b.length, 0); const bekleyen = tampon.flat(); s.bekleyenYas = bekleyen.length === 0 ? 0 : turSayisi - Math.min(...bekleyen); s.kayipToplam = s.kaybolan.reduce((a, b) => a + b, 0); return s; }
İki sayaç ayrı tutulur ve dersin bütün ayrımı buradadır. Kaybolan olay, sistemin kabul ettiği ve sonra düşürdüğü olaydır; taşıyıcı onu gönderilmiş sayar ve bir daha göndermez. Reddedilen olay, sınırda hiç kabul edilmeyendir; taşıyıcı bunu bilir ve kendi politikasıyla yeniden gönderir.
// geri/kosum.mjs — sinyalin geriye yayilma derinligi: iki gunde bes ayar import { K01, HALKA, kosum } from "./zincir.mjs"; const TUR = 1200; // AY11: 20 dakika, bir tur = bir saniye const ARIZASIZ = 120, YAVAS = 60; // izdusum tuketicisinin turdaki hizi const AYAR = [ ["sinirsiz tampon", { derinlik: 0, sinirsiz: true }], ["sinyal yok", { derinlik: 0 }], ["1 halka", { derinlik: 1 }], ["2 halka", { derinlik: 2 }], ["sinira kadar", { derinlik: 3 }], ]; console.log(`${TUR} tur, kaynak K01 tepe yazma ${K01.tepeYazma}/tur (salinimli, ortalama carpan 1.00)`); console.log(`halkalar: ${HALKA.map((h, i) => `${h.ad}(kap ${h.kap}, hiz ${i === 2 ? "tuketim" : h.hiz})`).join(" -> ")}\n`); for (const [rejim, hiz] of [["arizasiz: tuketim 120/tur", ARIZASIZ], ["AY11: tuketim 60/tur", YAVAS]]) { console.log(`-- ${rejim} --`); console.log(`${"ayar".padEnd(16)}${"tamamlanan".padStart(11)}${"reddedilen".padStart(11)}${"kaybolan".padStart(9)}` + `${"kayip yeri".padStart(20)}${"biriken".padStart(8)}${"bekleyen yas".padStart(13)}${"biten yas".padStart(10)}`); for (const [ad, y] of AYAR) { const r = kosum({ turSayisi: TUR, tuketimHizi: hiz, ...y }); console.log(`${ad.padEnd(16)}${String(r.tamamlanan).padStart(11)}${String(r.reddedilen).padStart(11)}` + `${String(r.kayipToplam).padStart(9)}${r.kaybolan.join("/").padStart(20)}${String(r.biriken).padStart(8)}` + `${String(r.bekleyenYas).padStart(13)}${String(r.enBuyukYas).padStart(10)}`); } console.log(); } const sinirsiz = kosum({ turSayisi: TUR, derinlik: 0, sinirsiz: true, tuketimHizi: ARIZASIZ }); const sinyalli = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: ARIZASIZ }); const duz = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: ARIZASIZ, salinim: false }); console.log(`-- arizasiz gunun bedeli (sinirsiz tampona gore) --`); console.log(`uretilen ${sinyalli.uretilen}, sinirda reddedilen gecerli olay ${sinyalli.reddedilen}` + ` = %${((sinyalli.reddedilen / sinyalli.uretilen) * 100).toFixed(2)}`); console.log(`salinim kapatilinca ayni ayar: ${duz.reddedilen} red -> reddin kaynagi ortalama yuk degil, salinimdir`); console.log(`sinirsiz tamponun bekleyen yasi ${sinirsiz.bekleyenYas} tur, sinira kadar sinyalde ${sinyalli.bekleyenYas} tur`); console.log(`duraklatilan halka-turu: ${sinyalli.duraklatilan.join("/")}; kaynagin durduruldugu olay ${sinyalli.sinirDurdu}`); console.log(`sinyal denetimi: ${HALKA.length} halka x ${K01.tepeYazma} olay/s = ${(HALKA.length * K01.tepeYazma).toFixed(2)} denetim/s`); console.log(`\n-- AY11'in duyarliligi: tuketici hizi (1200 tur) --`); console.log(`${"tuketim/tur".padStart(12)}${"acik/tur".padStart(10)}${"sinirsiz biriken".padStart(17)}` + `${"sinyalsiz kayip".padStart(16)}${"sinirda red".padStart(12)}${"kayip/red".padStart(10)}`); for (const h of [90, 60, 30]) { const a = kosum({ turSayisi: TUR, derinlik: 0, sinirsiz: true, tuketimHizi: h }); const y = kosum({ turSayisi: TUR, derinlik: 0, tuketimHizi: h }); const t = kosum({ turSayisi: TUR, derinlik: 3, tuketimHizi: h }); console.log(`${String(h).padStart(12)}${(K01.tepeYazma - h).toFixed(2).padStart(10)}${String(a.biriken).padStart(17)}` + `${String(y.kayipToplam).padStart(16)}${String(t.reddedilen).padStart(12)}` + `${(y.kayipToplam / t.reddedilen).toFixed(3).padStart(10)}`); }
1200 tur, kaynak K01 tepe yazma 97.22/tur (salinimli, ortalama carpan 1.00)
halkalar: giris(kap 200, hiz 250) -> kutuk(kap 150, hiz 150) -> izdusum(kap 100, hiz tuketim)
-- arizasiz: tuketim 120/tur --
ayar tamamlanan reddedilen kaybolan kayip yeri biriken bekleyen yas biten yas
sinirsiz tampon 116301 0 0 0/0/0 362 3 4
sinyal yok 82282 0 34064 4164/14950/14950 317 2 3
1 halka 97224 0 19114 4164/14950/0 325 3 4
2 halka 112124 0 4164 4164/0/0 375 3 4
sinira kadar 112124 4164 0 0/0/0 375 3 4
-- AY11: tuketim 60/tur --
ayar tamamlanan reddedilen kaybolan kayip yeri biriken bekleyen yas biten yas
sinirsiz tampon 71814 0 0 0/0/0 44849 460 460
sinyal yok 71814 0 44494 4164/14950/25380 355 3 4
1 halka 71814 0 44404 4164/40240/0 445 5 6
2 halka 71814 0 44399 44399/0/0 450 7 8
sinira kadar 71814 44399 0 0/0/0 450 7 8
-- arizasiz gunun bedeli (sinirsiz tampona gore) --
uretilen 116663, sinirda reddedilen gecerli olay 4164 = %3.57
salinim kapatilinca ayni ayar: 0 red -> reddin kaynagi ortalama yuk degil, salinimdir
sinirsiz tamponun bekleyen yasi 3 tur, sinira kadar sinyalde 3 tur
duraklatilan halka-turu: 598/897/0; kaynagin durduruldugu olay 4164
sinyal denetimi: 3 halka x 97.22 olay/s = 291.66 denetim/s
-- AY11'in duyarliligi: tuketici hizi (1200 tur) --
tuketim/tur acik/tur sinirsiz biriken sinyalsiz kayip sinirda red kayip/red
90 7.22 9029 34064 8579 3.971
60 37.22 44849 44494 44399 1.002
30 67.22 80753 80394 80303 1.001
Bütün sayılar hesap sınıfındadır: belirlenimli bir varış dizisi üzerinde sayılmışlardır.
Kısmi Yayılma Kaybı Taşır, Kaldırmaz
İkinci tablo dersin ana bulgusudur. AY11 altında kaybolan olay sayısı derinlik 0’da 44.494, derinlik
1’de 44.404, derinlik 2’de 44.399. Üç sayı birbirinin aynı. Değişen tek şey kayip yeri
sütunudur: kayıp önce izdüşümün kapısında (25.380), sonra kütüğün kapısında (40.240), sonra girişin
kapısında (44.399) oluyor.
Kısmi geri basınç hiçbir olay kurtarmıyor; yalnız kaybın yerini değiştiriyor. Karşılığında iki şey ödeniyor: biriken iş 355’ten 450’ye çıkıyor ve bekleyen olayın yaşı 3 turdan 7 tura yükseliyor. Yani sinyal, işi geriye tutar — tutmak da bir bedeldir.
Dördüncü satırda sayı sıfırlanıyor: sinyal servis sınırına ulaştığında 44.399 olay kaybolmuyor, reddediliyor. Tamamlanan olay sayısı değişmedi (71.814); tüketicinin kapasitesi neyse o. Değişen, o kapasiteye sığmayan 44.399 olayın ne olduğudur. Kaybolan olay taşıyıcı için gönderilmiş sayılır ve bir daha gelmez; reddedilen olay taşıyıcı için gönderilmemiştir ve yeniden gönderilebilir.
Geri basınç, servis sınırına ulaşmadıkça hiçbir olayı kurtarmaz. Zincirin tamamında uygulanmadıkça hiçbir yerinde uygulanmış sayılmayacağı arka plan işleri konusunda söylenmişti; bu tablo o cümlenin sayısıdır ve sınırın hangi halka olduğunu ekler — sinyalin durabileceği tek yer, sistemin dışıyla konuştuğu yerdir.
Yayılma Nerede Durmak Zorunda
Sinyal taşıyıcıya taşınamaz. Taşıyıcı başka bir kuruluşun sistemidir; bu sistem onu yavaşlatamaz, yalnız olayını kabul etmeyebilir. Yayılma bu yüzden zincirin dördüncü halkasında değil, üçüncüsünün dış kapısında biter ve orada biçim değiştirir: iç halkalarda bir bekletmedir, sınırda bir reddir.
Birinci tablo bunun ilk bedelini gösteriyor. Arızasız günde — tüketici üreticiden hızlıyken — sınıra kadar taşınan sinyal 4164 geçerli olayı reddediyor: üretilenin yüzde 3,57’si. Salınım kapatıldığında aynı ayar hiçbir olayı reddetmiyor. Demek ki reddin kaynağı ortalama yük değil, varışın anlık dalgalanmasıdır. Tampon dalgalanmayı yutmaya yetmediğinde geri basınç, yutulabilecek bir tepeyi redde çeviriyor.
Aynı satırda ikinci bir bedel var: duraklatılan halka-turu 598 ve 897. Bunlar bir halkanın işi olduğu hâlde ardılı dolu diye durduğu turlardır — kullanılmayan kapasite.
Sınırsız tampon satırı bu bedeli ödemez: arızasız günde 116.301 olay tamamlar, hiçbirini reddetmez. Bedeli AY11 satırında görünür. Orada da hiçbir olay kaybolmaz, ama 44.849 olay birikir ve en eski bekleyen olay 460 tur yaşındadır — yaklaşık yedi buçuk dakika. İzdüşüm o kadar geridedir ve takip sorgusu o kadar eski bir durumu gösterir. Sınırsız tampon kaybı yok etmez; onu bayatlığa çevirir.
Üç seçenek üç yere yazar: belleğe ve bayatlığa (sınırsız tampon), kayba (sinyalsiz sınırlı tampon), ya da kaynağa (sınıra kadar sinyal). Hangisinin seçileceği veriye bağlıdır — bir gönderinin durum olayı kaybolduğunda takip zinciri kalıcı olarak eksilir, bu yüzden ikinci seçenek bu akış için kabul edilebilir değildir.
Açık Büyüdükçe Kazanç Küçülür
Son tablo AY11’in duyarlılığıdır ve geri basıncın sınırını çizer. Tüketici hızı 90 olduğunda açık turda yalnız 7,22 olaydır; sinyalsiz düzen 34.064 olay kaybederken sınıra kadar sinyal yalnız 8579 olay reddeder — oran 3,971. Geri basınç burada işin dörtte üçünü kurtarıyor, çünkü tepeler arasındaki boşluklarda biriken iş eritiliyor.
Tüketici hızı 60’a inince oran 1,002’ye, 30’a inince 1,001’e düşüyor. Açık büyüdüğünde geri basınç hiçbir işi kurtarmıyor, yalnız kaybı redde çeviriyor. Bu yine değerlidir — reddedilen olay yeniden gönderilebilir — ama iki farklı kazanç olduğunun ve hangisinin geçerli olduğunun açık yazılması gerekir. Küçük açıklarda geri basınç bir soğurma mekanizması, büyük açıklarda bir etiketleme mekanizmasıdır.
Özet
- Geri basınç sinyali bir yayılma derinliği taşır: tüketiciden geriye kaç halkanın ardılının doluluğuna uyduğu. Derinlik 3, sinyalin servis sınırına ulaşması demektir.
- Kısmi yayılma hiçbir olay kurtarmaz: AY11 altında kaybolan olay derinlik 0, 1 ve 2’de sırasıyla 44.494, 44.404 ve 44.399 — aynı sayı. Değişen yalnız kaybın yeri, biriken iş (355 → 450) ve bekleyen olayın yaşıdır (3 → 7 tur).
- Sinyal sınıra ulaştığında 44.399 olay kaybolmaktan çıkıp reddedilmeye döner; kaybolan olay taşıyıcı için gönderilmiştir, reddedilen olay gönderilmemiştir ve yeniden gönderilebilir.
- Arızasız günün bedeli, salınımın yuttuğu tepelerdir: 4164 geçerli olay reddedilir (üretilenin yüzde 3,57’si) ve salınım kapatıldığında bu sayı sıfırlanır; ayrıca 598 ile 897 duraklatılmış halka-turu ve saniyede 291,66 sinyal denetimi.
- Sınırsız tampon kaybı yok etmez, bayatlığa çevirir: AY11’de 44.849 olay birikir ve en eski bekleyen olay 460 tur yaşındadır.
- Kazancın büyüklüğü açığa bağlıdır: turda 7,22 olaylık açıkta geri basınç kaybı 34.064’ten 8579’a indirir (oran 3,971), 37,22 olaylık açıkta oran 1,002’dir — orada kurtarma değil etiketleme yapar.
Sonraki Adım
Sinyal sınıra ulaştı ve orada bir redde dönüştü. Redde dönüşmesi kaçınılmazdı, ama reddin kendisi bu derste tasarlanmadı: 4164 geçerli olay reddedildiğinde hangileri olduğu, neye göre seçildiği ve karşı tarafa ne söylendiği hep aynı kaba kurala bağlıydı — tampon doluysa reddet. Okuma tarafında aynı soru daha keskindir. Uçta saniyede 513,89 istek var ve üçü aynı kapıdan geçiyor: takip sorgusu, taşıyıcı durum olayı, gün sonu ücretlendirme. Kapasite yetmediğinde hepsi birden mi kısılacak, yoksa biri korunup ötekiler mi kesilecek. Üstelik iki ayrı soru burada birbirine karışıyor — bilinen bir hızın üstünü kesmekle o anki kapasiteye göre reddetmek aynı şey değildir. Sonraki ders ikisini ayırır ve K01’in 513,89 istek/s tepesinde hangi isteğin korunduğunu sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.