İçeriğe geç
academia.sh

Ders 05 / 16

Önbellek Sunucusu

İki katmanlı önbellekte isabetin kenar ile kaynak arasında nasıl bölündüğü: kenarı üç düğüme bölmenin uygulamaya inen isteği elliden yüz kırk üçe çıkarması ve kaynak önbelleğinin onu ona indirmesi, geçersizleştirmenin yayılma penceresinin üç yüz altmış saniyeden on bir saniyeye inmesi, tazelik ayarının bu pencereye etkisi ve kişiye özel yanıtın paylaşılan önbelleğe düşmesiyle açılan paylaşılan anahtar yüzeyi.

İçindekiler

Son üç ders isteğin yolunu kurdu ve şifreledi: kim geldiği aktarıldı, şifre bir yerde sonlandı, sertifika kendi kendine tazeleniyor. Yolun tamamı her istek için baştan sona koşuyor.

Ölçüm ağının panosu her açılışta aynı bölge haritasını, aynı sayaç listesini ve aynı gecelik özet dosyasını istiyor. Bu isteklerin çoğu aynı yanıtı üretiyor. Yanıt bir yerde tutulabilir — ama “bir yer” iki ayrı yerdir. Kenar önbelleği istemciye yakın durur ve isteği ağın uzağına hiç göndermez. Kaynak önbelleği uygulamanın önünde durur ve uygulamanın aynı yanıtı iki kez üretmesini engeller.

Önbelleğin ne olduğu, isabet oranının nasıl hesaplandığı ve tazeliğin ne anlama geldiği daha önce ölçülmüştü; bu ders o mekaniği tekrarlamaz. Burada ölçülen üç şeydir: iki katman arasında isabetin nasıl bölündüğü, bir içerik değiştiğinde eskisinin kenarda kaç saniye daha durduğu ve yanlış bir önbellek anahtarının açtığı yüzey.

  • WS25. İstek akışı kendi üretecimizle üretilir; tohum 20260 görünürdür ve koşumdan koşuma aynı diziyi verir. İki bin istek, altı yüz saniyeye yayılır.
  • WS26. Beş içerik vardır ve ağırlıkları sabittir; biri (/fatura/ozet) kişiye özeldir, yani yanıtı isteği yapan aboneye göre değişir.
  • WS27. Bir abone hep aynı kenar düğümüne düşer: düğüm, abone kimliğinin düğüm sayısına bölümünden kalandır.
  • WS28. Varsayılan önbellek anahtarı yalnız yoldur; kimlik anahtara girmez. İki seçenek daha ölçülür: anahtara kimliği eklemek ve kişiye özel içeriği hiç saklamamak.
  • WS29. Geçersizleştirme yayınının üç kenar düğümüne ulaşma süresi kurgudur: iki, beş ve on bir saniye. Pencere en yavaş düğüme göre hesaplanır.
  • WS30. Model süre ölçmez; saniye değerleri tazelik ayarlarından ve kurgu gecikmelerden türer, eski yanıt alan istek sayısı değişen içeriğin trafik payından hesaplanır.
// onbellek/katman.mjs — model: iki katmanli onbellek (kenar + kaynak). Kurgu olcum aginin
// istek akisi kendi uretecimizle uretilir; tohum gorunur. Onbellek mekanigi yeniden
// tanimlanmaz, iki katman arasindaki isabet dagilimi ve gecersizlestirme penceresi olculur.
const DONEM = 600, ISTEK = 2000, ABONE = 6, TOHUM = 20260;
// [yol, agirlik, tur]
const ICERIK = [
  ["/bolge/harita", 40, "paylasik"], ["/sayac/liste", 25, "paylasik"],
  ["/gecelik/ozet", 15, "paylasik"], ["/varlik/logo", 10, "paylasik"],
  ["/fatura/ozet", 10, "kisiye-ozel"],
];
const TOPLAM = ICERIK.reduce((a, x) => a + x[1], 0);
const uretec = (tohum) => { let s = tohum >>> 0; return () => (s = (Math.imul(s, 1664525) + 1013904223) >>> 0) / 4294967296; };
const sec = (u) => { let e = u * TOPLAM; return ICERIK.find((x) => (e -= x[1]) < 0) ?? ICERIK[0]; };

function simule({ dugum, kaynakVar, kenarTazelik, kaynakTazelik, anahtar }) {
  const r = uretec(TOHUM);
  const kenar = Array.from({ length: dugum }, () => new Map());
  const kaynak = new Map();
  const s = { kenarIsabet: 0, kaynakIsabet: 0, uygulama: 0, sizanIstek: 0 };
  const sizanAbone = new Set();
  for (let i = 0; i < ISTEK; i += 1) {
    const t = Math.floor((i * DONEM) / ISTEK);
    const [yol, , tur] = sec(r());
    const abone = Math.floor(r() * ABONE);
    const ozel = tur === "kisiye-ozel";
    if (ozel && anahtar === "ozel-gecer") { s.uygulama += 1; continue; }   // ozel icerik hic saklanmaz
    const a = anahtar === "yol+kimlik" && ozel ? `${yol}#${abone}` : yol;
    const k = kenar[abone % dugum];
    const kayitla = (giris) => {                        // isabette kimin yaniti dondu
      if (ozel && giris.abone !== abone) { s.sizanIstek += 1; sizanAbone.add(giris.abone); }
    };
    const ke = k.get(a);
    if (ke && t - ke.t < kenarTazelik) { s.kenarIsabet += 1; kayitla(ke); continue; }
    const kk = kaynakVar ? kaynak.get(a) : undefined;
    if (kk && t - kk.t < kaynakTazelik) {
      s.kaynakIsabet += 1; kayitla(kk); k.set(a, { t, abone: kk.abone }); continue;
    }
    s.uygulama += 1;                                    // iki katman da isabetsiz: uygulama uretir
    if (kaynakVar) kaynak.set(a, { t, abone });
    k.set(a, { t, abone });
  }
  return { ...s, sizanAbone: sizanAbone.size };
}

const E = [8, 9, 14, 15, 16, 18, 14, 13];
const yaz = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](E[i])).join("");
console.log(yaz(["dugum", "kaynak", "anahtar", "kenar isabet", "kaynak isabet", "uygulamaya inen",
  "sizan istek", "sizan abone"]));
const AYAR = [
  [1, false, "yol"], [3, false, "yol"], [3, true, "yol"],
  [3, true, "yol+kimlik"], [3, true, "ozel-gecer"],
];
for (const [dugum, kaynakVar, anahtar] of AYAR) {
  const o = simule({ dugum, kaynakVar, kenarTazelik: 60, kaynakTazelik: 300, anahtar });
  console.log(yaz([dugum, kaynakVar ? "var" : "yok", anahtar, o.kenarIsabet, o.kaynakIsabet,
    o.uygulama, o.sizanIstek, o.sizanAbone]));
}

// --- Gecersizlestirmenin yayilma penceresi -------------------------------------
// Icerik kaynakta t=0'da degisti. Pencere, kenarda kac saniye eski icerik kaldigidir.
// Yayin gecikmesi kurgudur: uc kenar dugumune sirasiyla su saniyelerde ulasir.
const GECIKME = [2, 5, 11];
const DEGISEN = ICERIK[0];                              // degisen icerik: /bolge/harita
const HIZ = (ISTEK / DONEM) * (DEGISEN[1] / TOPLAM);    // o icerige gelen istek/saniye
function pencere(yontem, kenarTazelik, kaynakTazelik) {
  if (yontem === "yok") return kenarTazelik + kaynakTazelik;      // iki tazelik ust uste biner
  if (yontem === "kaynakta") return kenarTazelik;                 // kenar kendi suresini bekler
  if (yontem === "her katmanda") return Math.max(...GECIKME);
  return kenarTazelik;                                            // bir dugum yayini kacirdi
}
const P = [22, 16, 17, 20, 22];
const yaz2 = (h) => h.map((d, i) => String(d)[i ? "padStart" : "padEnd"](P[i])).join("");
console.log("\n" + yaz2(["gecersizlestirme", "kenar tazelik", "kaynak tazelik", "pencere(saniye)",
  "eski yanit alan istek"]));
for (const [y, kt, kk] of [["yok", 60, 300], ["yok", 10, 60], ["kaynakta", 60, 300],
  ["kaynakta", 10, 300], ["her katmanda", 60, 300], ["bir dugum kacirdi", 60, 300]]) {
  const p = pencere(y, kt, kk);
  console.log(yaz2([y, kt, kk, p, Math.round(p * HIZ)]));
}
dugum      kaynak       anahtar   kenar isabet   kaynak isabet   uygulamaya inen   sizan istek  sizan abone
1             yok           yol           1950               0                50           169            5
3             yok           yol           1857               0               143            95            6
3             var           yol           1857             133                10           179            2
3             var    yol+kimlik           1837             143                20             0            0
3             var    ozel-gecer           1664             107               229             0            0

gecersizlestirme         kenar tazelik   kaynak tazelik     pencere(saniye) eski yanit alan istek
yok                                 60              300                 360                   480
yok                                 10               60                  70                    93
kaynakta                            60              300                  60                    80
kaynakta                            10              300                  10                    13
her katmanda                        60              300                  11                    15
bir dugum kacirdi                   60              300                  60                    80

Kenarı Bölmenin Bedeli

İlk iki satır aynı iki bin isteği aynı tazelik ayarlarıyla geçiriyor. Değişen tek şey kenar düğümü sayısı.

Tek düğümde kenar isabeti bin dokuz yüz elli, uygulamaya inen istek elli. Kenar üç düğüme bölündüğünde isabet bin sekiz yüz elli yediye iniyor ve uygulamaya inen istek elliden yüz kırk üçe çıkıyor. Yaklaşık üç katı.

Nedeni doğrudan: her düğümün kendi önbelleği vardır ve aynı içeriği üç kez ayrı ayrı ister. Bir içerik yenilendiğinde artık bir istek değil, üç istek uygulamaya iner. Kenar düğümü sayısı bir ölçek kararıdır — daha çok düğüm, istemciye daha yakın yanıt demektir — ve uygulamaya inen yükü düğüm sayısı kadar çarpar.

Bu, iki katmanlı önbelleğin varlık nedenidir. Üçüncü satır kaynak önbelleğini ekliyor: kenar isabeti değişmiyor (bin sekiz yüz elli yedi), yüz otuz üç istek kaynak önbelleğinde karşılanıyor ve uygulamaya inen istek ona düşüyor. Üç düğümün çoğalttığı isteğin neredeyse tamamını kaynak önbelleği soğuruyor.

Sayılar birlikte okunduğunda kaynak önbelleğinin işi görünür oluyor: kenardan gelen isteğin kendisini azaltmıyor, o isteğin uygulamaya varmasını engelliyor. Üçüncü satırın uygulama yükü tek düğümlü birinci satırdan da düşüktür — kaynak önbelleği yalnız düğüm çoğalmasını değil, tek düğümün kendi tazelik dolumlarını da soğuruyor.

Yayılma Penceresi

İkinci tablo başka bir soruyu ölçüyor. Bölge haritası değişti; yeni harita ne zaman görünür olur?

Birinci satır varsayılan durumdur: geçersizleştirme yok, iki katman da kendi tazelik süresini bekliyor. Pencere altmış artı üç yüz, yani üç yüz altmış saniye. İki tazeliğin toplanmasının nedeni üst üste binmedir: kenar, kaynaktan bir kopya çektiğinde o kopya kaynakta üç yüz saniyeye kadar beklemiş olabilir ve kenar onu altmış saniye daha tutar. Pencere boyunca değişen içeriğe gelen dört yüz seksen istek eski haritayı alır.

İkinci satır tazelik ayarlarını kısaltıyor: altmış ve üç yüz yerine on ve altmış. Pencere yetmiş saniyeye, eski yanıt alan istek doksan üçe iniyor. Bedeli tabloda görünmüyor ama ilk tablodan okunabilir: tazelik kısaldıkça isabet düşer ve uygulamaya inen istek artar. Tazeliği kısaltmak pencereyi kapatmanın pahalı yoludur.

Üçüncü satır kaynağa geçersizleştirme gönderiyor. Kaynak önbelleği hemen temizleniyor, kenar kendi altmış saniyesini bekliyor: pencere altmış saniye, eski yanıt alan istek seksen. Üç yüz altmıştan altmışa inen bir kazanç, kaynağa gönderilen tek bir mesajla elde ediliyor.

Dördüncü satır kaynağa geçersizleştirme gönderirken kenar tazeliğini ona indiriyor: pencere on saniye. Beşinci satır geçersizleştirmeyi her katmana yayıyor: pencere en yavaş kenar düğümünün gecikmesine, on bir saniyeye iniyor ve kenar tazeliği artık pencereyi hiç belirlemiyor.

Buradaki sıra önemlidir. Tazelik ayarını kısaltmak pencereyi kapatır ve isabeti düşürür; geçersizleştirmeyi yaymak pencereyi kapatır ve isabete dokunmaz. Beşinci satır altmış saniyelik kenar tazeliğiyle çalışıyor — yani birinci satırın isabet oranıyla — ve penceresi on bir saniye.

Yayının Kaçtığı Yer

Altıncı satır beşincinin kapatamadığını gösteriyor. Geçersizleştirme her katmana yayınlanıyor ama bir kenar düğümü mesajı almıyor: ağ kesintisi, düğümün yeniden başlaması, kuyruğun taşması. O düğümde pencere kenar tazeliğine geri dönüyor: altmış saniye.

Bu, geçersizleştirmenin getirdiği yeni yüzeydir. Tazelik süresi bir üst sınır verir ve hiçbir şey yapılmasa da geçerlidir. Geçersizleştirme yayını üst sınır vermez; bir umut verir ve umut tutmadığında sistem sessizce üst sınıra döner. Sistemin durumu iki düğümde on bir saniye, bir düğümde altmış saniyedir ve dışarıdan bakan hiç kimse hangi düğüme düştüğünü bilmez.

Sonuç, tazeliğin geçersizleştirme yayınıyla birlikte korunması gerektiğidir. Yayın hızlı yolu verir, tazelik geri düşüş sınırını verir. Tazeliği sonsuza çekip her şeyi yayına bağlamak, kaçan tek bir mesajı süresiz eski içeriğe çevirir.

Paylaşılan Anahtar Yüzeyi

Son sütunlar dersin yüzey ölçümüdür. Varsayılan önbellek anahtarı yalnız yoldur ve /fatura/ozet kişiye özeldir: her abone kendi fatura özetini alır.

İlk satırda yüz altmış dokuz istek başka bir abonenin fatura özetini aldı; beş abonenin verisi başkalarına gitti. Üç düğümlü ikinci satırda sızan istek doksan beşe iniyor ama sızan abone sayısı altıya çıkıyor — bölünme sızıntıyı azaltmıyor, dağıtıyor.

Üçüncü satır en keskin olanıdır. Kaynak önbelleği eklendiğinde sızan istek yüz yetmiş dokuza çıkıyor ve sızan abone sayısı ikiye iniyor. Paylaşılan tek bir kaynak girdisi, iki abonenin faturasını üç kenar düğümüne birden dağıtıyor. Kaynak önbelleği sızıntıyı yoğunlaştırıyor: daha az kişinin verisi, daha çok kişiye.

Bu yüzeyin adı paylaşılan anahtar yüzeyidir. Açılması için bir hata gerekmez; varsayılan anahtarın yolu içermesi ve kimliği içermemesi yeter. Yanıtın kişiye özel olduğu bilgisi uygulamadadır, önbellekte değildir ve iki katman da bu bilgiyi sormaz.

Dördüncü satır anahtara kimliği ekliyor: sızan istek sıfır, sızan abone sıfır. Uygulamaya inen istek ondan yirmiye çıkıyor — altı ayrı abone için altı ayrı girdi tutulduğundan tazelik dolumları çoğalıyor. On isteklik bir bedelle yüz yetmiş dokuz sızıntı kapandı.

Beşinci satır kişiye özel içeriği hiç saklamıyor. Sızıntı yine sıfır, ama uygulamaya inen istek iki yüz yirmi dokuza çıkıyor. İki güvenli seçenek arasında yirmi kat fark var ve ikisi de aynı yüzeyi kapatıyor. Anahtarı doğru kurmak, önbelleklemeyi kapatmaktan yirmi kat ucuzdur.

Önbelleğin Kendi Yüzeyi

İki katman uygulamanın yükünü elliden ona indirdi ve bunu yaparken dört yeni kalem getirdi.

Birincisi saklanan yanıtın kendisidir. Kenarda ve kaynakta artık üretilmiş yanıtlar durur; bunlar diskte ya da bellekte bir yerdedir ve o yeri okuyabilen, uygulamanın verdiği yanıtları kimlik doğrulamadan okur. İkincisi geçersizleştirme kanalıdır: bir mesaj gönderip bir girdiyi silebilen bir uç, önceki derslerin saydığı yönetim ucu listesine iki kalem ekler — kenardaki bir uç ve kaynaktaki bir uç. Bu uç kimliksizse, dışarıdan gönderilen bir geçersizleştirme akışı bütün önbelleği boşaltabilir ve uygulamaya inen istek ondan iki bine çıkar.

Üçüncüsü anahtar kuralının kendisidir. Beşinci satırdan görüldüğü gibi kural bir yapılandırma satırıdır ve yanlış yazıldığında hata vermez; yalnız başka bir abonenin yanıtını döndürür. Dördüncüsü tazelik ayarının ikiye bölünmüş olmasıdır: pencerenin gerçek değeri iki ayrı katmandaki iki ayrı sayıdan çıkar ve hiçbir katman tek başına o değeri bilmez.

Dört kalemin hiçbiri “önbellek açıldı” cümlesinde görünmez. Kursun kuralı burada da geçerlidir: kapatılan yük, açılan yüzeyle birlikte yazılmadıkça karar savunulamaz. Uygulamaya inen isteği kırk kalem azaltan bir adım, dört kalem açık yüzey ekliyorsa iki sayı da rapora aynı satırda girmelidir.

Özet

  • Kenarı üç düğüme bölmek kenar isabetini bin dokuz yüz elliden bin sekiz yüz elli yediye indirdi ve uygulamaya inen isteği elliden yüz kırk üçe çıkardı; düğüm sayısı uygulama yükünü çarpar.
  • Kaynak önbelleği yüz otuz üç isteği karşılayarak uygulamaya inen isteği ona indirdi — tek düğümlü düzenden de düşük; kaynak katmanının işi kenarın çoğalttığı isteği soğurmaktır.
  • Geçersizleştirme yokken pencere iki tazeliğin toplamıdır: üç yüz altmış saniye ve dört yüz seksen eski yanıt. Kaynağa geçersizleştirme pencereyi altmışa, her katmana yayın on bir saniyeye indirdi.
  • Tazeliği kısaltmak pencereyi kapatır ve isabeti düşürür; geçersizleştirmeyi yaymak pencereyi kapatır ve isabete dokunmaz — ama yayını kaçıran bir düğümde pencere sessizce tazelik süresine geri döner.
  • Varsayılan anahtar yalnız yolu içerdiği için yüz yetmiş dokuz istek başka abonenin fatura özetini aldı; kaynak önbelleği sızıntıyı yoğunlaştırdı — iki abonenin verisi yüz yetmiş dokuz isteğe gitti.
  • Anahtara kimliği eklemek sızıntıyı sıfırladı ve uygulama yükünü ona değil yirmiye çıkardı; kişiye özel içeriği hiç saklamamak da sızıntıyı sıfırladı ama yükü iki yüz yirmi dokuza çıkardı.

Sonraki Adım

Bu ders trafiğe kenarda ve kaynakta iki kural koydu: neyin saklanacağı ve ne kadar tazelikle. Kuralların ikisi de isteğin yolunda durdu ve dışarıdan gelen trafiğe uygulandı.

Servisler birbirine de istek gönderir. Doğrulayıcı faturalamaya, faturalama iş emrine, iş emri bildirim geçidine bağlanır ve bu trafiğin hiçbiri kenar vekilden geçmez. Zaman aşımı, yeniden deneme, hangi servisin hangisini çağırabileceği — bu kurallar bugün her servisin kendi kodunda duruyor. Aynı kurallar her servisin yanına konan bir vekile taşınabilir. Sonraki ders iki yerleşimi aynı kural değişikliği üzerinde karşılaştırır: kural değiştiğinde kaç servise dokunulur, her isteğe kaç atlama ve kaç milisaniye eklenir, yan araba vekilinin kendisi ne tüketir ve hangi yeni yüzeyi getirir. Üç servisli bir sistemde bedelin kazançtan büyük olduğu nokta sayıyla gösterilir.

İ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