İçeriğe geç
academia.sh

Ders 08 / 16

Gürültülü Komşu

Paylaşılan bir kaynakta izolasyon eksikliğinin belirtiden tanınması: aynı gecikme artışını veren iki nedenin istek payı ile iş payının ayrıştırılmasıyla ayrılması, gürültü katsayısının 1,01'den 1,43'e çıkması, istek payı hiç değişmezken iş payının 0,1702'den 0,2415'e sıçraması ve pay ayırmanın karşılığında en büyük kiracının kendi gecikmesinin 0,47'den 2,96 tura çıkması.

İçindekiler

Buraya kadarki yedi kalıp tek bir sahibin işini ölçtü. Bir varsayım hiç sorulmadı: paylaşılan kaynağı kullanan herkesin aynı taraf olduğu. Gönderi takip ve ücretlendirme servisi tek bir müşteriye hizmet etmiyor; satıcılar aynı uçtan, aynı depodan ve aynı işçi havuzundan geçiyor.

Belirti şudur: küçük satıcıların gördüğü ortalama bekleme dört kata çıktı, ama uçtaki toplam istek hızı hiç değişmedi. K01’in tepe okuma hızı 416,67 istek/s yerinde; kapasite de aynı. Buna gürültülü komşu (noisy neighbor) denir: paylaşılan bir kaynakta bir kiracının (tenant) davranışı ötekilerin gördüğü başarımı değiştirir.

Aynı Belirti, İki Neden

Birinci neden: küçük satıcıların kendi hızı arttı. Kimse kimseyi rahatsız etmiyor; talep gerçekten büyüdü ve kuyruk buna göre uzadı. Bu bir gürültü değil, bir kapasite sorusudur.

İkinci neden: bir komşu payını büyüttü. Küçük satıcıların hızı hiç değişmedi; en büyük satıcı dönem taramasını sıklaştırdı ve paylaşılan havuzun kapasitesinin büyük bir bölümünü tüketmeye başladı.

İkisi de aynı belirtiyi verir. Ayıran ölçüm, kiracı başına istek payı ile iş payını ayrı ayrı saymaktır. Bir isteğin doğurduğu iş akıştan akışa yüzlerce kat değişir — altıncı ders bunu ölçtü: bir dönem taraması, satıcının kendi kayıt sayısıyla orantılı iş yapar. Payı istekle sayan bir ölçüm gürültüyü hiç göremez.

Paylaşılan Havuz

Aşağıdaki koşum bir modeldir: tur soyut bir adımdır (bir tur bir saniye; çevrim katsayısı varsayımdır) ve gerçek küme ya da kiracı kurulmaz. İki düzen karşılaştırılır — geldiği sırayla işleyen paylaşılan sıra ve iş koruyan dönüşümlü paylaştırma.

KK10 — satıcı hacmi. İki yüz satıcının gönderi hacmi sıraya göre çarpık dağılır ve toplamı K01’in günde 400.000 gönderi varsayımıdır. Gerekçe: tek bir büyük satıcının hacmi kuyruğun tamamını taşıyabilir. KK11 — birim ve kapasite. Bir takip sorgusu 1 birim, bir dönem taraması satıcının gönderi sayısının yüzde biri kadar birim; havuz turda 540 birim işler. KK12 — iki senaryo. A: beşinci sıradan sonraki satıcıların istek hızı 1,20 kat. B: en büyük satıcı taramasını beş kat sıklaştırıyor. İkisi de olağan talebi benzer ölçüde büyütür. Bu varsayımlar K01’in tablosuna eklenmez.

// kiraci/paylasim.mjs — paylasilan bir is havuzunun MODELI. Tur soyut bir adimdir
// (bir tur = bir saniye; cevrim katsayisi varsayim). Gercek kume ya da kiraci kurulmaz.
export const KAPASITE = 540;                  // birim/tur
export const KIRACI = 200;
export const ARA = 60;                        // donem istegi araligi (tur)
export const K01 = { tepeOkuma: 416.67, gunlukGonderi: 400_000 };

// KK10: satici hacmi carpik dagilir (pay ~ 1/sira), toplami K01'in gunluk gonderisidir.
export function saticilar(n = KIRACI) {
  const h = Array.from({ length: n }, (_, i) => 1 / (i + 1));
  const t = h.reduce((a, b) => a + b, 0);
  return h.map((x, i) => ({ ad: `S${i + 1}`, pay: x / t, gonderi: Math.round((x / t) * K01.gunlukGonderi) }));
}
// Bir donem taramasinin birimi saticinin kendi kayit sayisiyla orantilidir (06. dersin olcusu).
export const tarama = (s) => Math.max(1, Math.round(s.gonderi / 100));

export function kosum({ tur = 600, ayirma = false, buyukSik = false, kucukArtti = false, parca = 0 }) {
  const S = saticilar();
  const birikim = S.map(() => 0);
  const kuyruk = S.map(() => []), bas = S.map(() => 0);   // kiraci kuyrugu ve bas isaretcisi
  const sira = []; let basSira = 0;                       // paylasilan duzende genel varis sirasi
  const s = S.map(() => ({ istek: 0, birim: 0, biten: 0, gecikme: 0, enBuyuk: 0 }));
  const koy = (i, birim, t) => {          // parca > 0 ise buyuk istek parcalara bolunur
    const n = parca > 0 ? Math.ceil(birim / parca) : 1;
    for (let c = 0; c < n; c += 1) {
      const o = { k: i, kalan: Math.ceil(birim / n), varis: t };
      if (ayirma) kuyruk[i].push(o); else sira.push(o);
      s[i].istek += 1; s[i].birim += o.kalan;
    }
  };
  const bitir = (o, t) => {
    const g = t - o.varis;
    s[o.k].biten += 1; s[o.k].gecikme += g;
    s[o.k].enBuyuk = Math.max(s[o.k].enBuyuk, g);
  };

  for (let t = 1; t <= tur; t += 1) {
    S.forEach((x, i) => {
      const carpan = i >= 5 && kucukArtti ? 1.20 : 1;     // A: kucuk saticilarin kendi hizi artiyor
      birikim[i] += K01.tepeOkuma * x.pay * carpan;
      while (birikim[i] >= 1) { birikim[i] -= 1; koy(i, 1, t); }
      const sik = i === 0 && buyukSik ? 5 : 1;            // B: en buyuk komsu taramasini siklastiriyor
      if ((t + i) % Math.round(ARA / sik) === 0) koy(i, tarama(x), t);
    });

    let butce = KAPASITE;
    if (ayirma) {                             // pay ayirma: is koruyan donusumlu paylastirma
      for (let gecis = 0; gecis < 12 && butce > 0; gecis += 1) {
        const aktif = [];
        for (let i = 0; i < KIRACI; i += 1) if (bas[i] < kuyruk[i].length) aktif.push(i);
        if (aktif.length === 0) break;
        const pay = Math.max(1, Math.floor(butce / aktif.length));
        const bastan = t % aktif.length;                  // baslangic donuyor, sira kimseye kalmiyor
        for (let n = 0; n < aktif.length && butce > 0; n += 1) {
          const i = aktif[(bastan + n) % aktif.length];
          let kalanPay = pay;
          while (kalanPay > 0 && butce > 0 && bas[i] < kuyruk[i].length) {
            const o = kuyruk[i][bas[i]];
            const al = Math.min(o.kalan, kalanPay, butce);
            o.kalan -= al; kalanPay -= al; butce -= al;
            if (o.kalan === 0) { bitir(o, t); bas[i] += 1; }
          }
        }
      }
    } else {                                  // paylasilan sira: geldigi sirayla
      while (butce > 0 && basSira < sira.length) {
        const o = sira[basSira];
        const al = Math.min(o.kalan, butce);
        o.kalan -= al; butce -= al;
        if (o.kalan === 0) { bitir(o, t); basSira += 1; }
      }
    }
  }
  return { S, s };
}
// kiraci/olcum.mjs — istek payi ile is payinin ayrilmasi ve pay ayirmanin karsiligi
import { KAPASITE, KIRACI, ARA, K01, saticilar, tarama, kosum } from "./paylasim.mjs";

const EN = [10, 9, 11, 11, 10, 12, 12];
const yaz = (h) => console.log(h.map((x, i) => (i ? String(x).padStart(EN[i]) : String(x).padEnd(EN[i]))).join(" "));
const cizgi = () => console.log(EN.map((n) => "-".repeat(n)).join(" "));
const SEC = [0, 9, 49, 199];                          // S1, S10, S50, S200
const ort = (x) => (x.gecikme / x.biten).toFixed(2);
const kucukOrt = (r) => {                             // S6-S200 birlikte
  const k = r.s.slice(5);
  return (k.reduce((a, x) => a + x.gecikme, 0) / k.reduce((a, x) => a + x.biten, 0)).toFixed(2);
};

const S = saticilar();
const olagan = S.reduce((a, x) => a + K01.tepeOkuma * x.pay + tarama(x) / ARA, 0);
console.log(`kapasite ${KAPASITE} birim/tur, ${KIRACI} satici, olagan talep ${olagan.toFixed(2)} birim/tur` +
  ` (doluluk ${(olagan / KAPASITE).toFixed(4)}); en buyuk saticinin gunluk gonderisi ${S[0].gonderi},` +
  ` en kucugun ${S[KIRACI - 1].gonderi}; donem taramasi ${tarama(S[0])} ve ${tarama(S[KIRACI - 1])} birim\n`);

const GUN = [["arizasiz", {}], ["A: kucukler hizlandi", { kucukArtti: true }],
  ["B: en buyuk komsu taramayi siklastirdi", { buyukSik: true }]];
const PAYLASILAN = [], AYRILMIS = [];

for (const [ad, ek] of GUN) {
  const r = kosum(ek);
  PAYLASILAN.push(r); AYRILMIS.push(kosum({ ...ek, ayirma: true }));
  const ti = r.s.reduce((a, x) => a + x.istek, 0), tb = r.s.reduce((a, x) => a + x.birim, 0);
  console.log(`-- ${ad} --`);
  yaz(["satici", "istek", "istek payi", "is payi", "gurultu", "ort gecikme", "en buyuk"]);
  cizgi();
  for (const i of SEC) {
    const x = r.s[i];
    yaz([r.S[i].ad, x.istek, (x.istek / ti).toFixed(4), (x.birim / tb).toFixed(4),
      (x.birim / tb / (x.istek / ti)).toFixed(2), ort(x), x.enBuyuk]);
  }
  const k = r.s.slice(5);
  console.log(`S6-S200: ort gecikme ${kucukOrt(r)} tur, is payi ${(k.reduce((a, x) => a + x.birim, 0) / tb).toFixed(4)},` +
    ` istek payi ${(k.reduce((a, x) => a + x.istek, 0) / ti).toFixed(4)}\n`);
}

console.log("-- pay ayirma acikken: is koruyan donusumlu paylastirma --");
yaz(["gun", "S1 gec", "S10 gec", "S50 gec", "S200 gec", "S6-S200 ort", "S1 en buyuk"]);
cizgi();
GUN.forEach(([ad], g) => {
  const r = AYRILMIS[g];
  yaz([ad.split(":")[0], ...SEC.map((i) => ort(r.s[i])), kucukOrt(r), r.s[0].enBuyuk]);
});

console.log(`\nkarsiligi: B gununde S1'in ortalama gecikmesi ${ort(PAYLASILAN[2].s[0])} -> ${ort(AYRILMIS[2].s[0])} tur,` +
  ` en buyuk ${PAYLASILAN[2].s[0].enBuyuk} -> ${AYRILMIS[2].s[0].enBuyuk} tur`);
console.log(`arizasiz gunde bile S1 oder: ${ort(PAYLASILAN[0].s[0])} -> ${ort(AYRILMIS[0].s[0])} tur`);
console.log(`muhasebe: ${KIRACI} sayac, istek basina 1 dokunus; S1'in bolunemeyen istegi ${tarama(S[0])} birim,` +
  ` turdaki payi ${Math.floor(KAPASITE / KIRACI)} birim`);

console.log("\nayni B gunu, buyuk istek parcalanarak (pay ayirma yok):");
for (const parca of [681, 50]) {
  const r = kosum({ buyukSik: true, parca });
  console.log(`  en buyuk parca ${String(parca).padStart(3)} birim (turluk kapasitenin ${(parca / KAPASITE).toFixed(2)}'si)` +
    ` -> S6-S200 ort gecikme ${kucukOrt(r)} tur`);
}
kapasite 540 birim/tur, 200 satici, olagan talep 483.34 birim/tur (doluluk 0.8951); en buyuk saticinin gunluk gonderisi 68050, en kucugun 340; donem taramasi 681 ve 3 birim

-- arizasiz --
satici         istek  istek payi     is payi    gurultu  ort gecikme     en buyuk
---------- --------- ----------- ----------- ---------- ------------ ------------
S1             42541      0.1689      0.1702       1.01         0.10            2
S10             4263      0.0169      0.0170       1.01         0.20            2
S50              860      0.0034      0.0034       1.00         0.25            2
S200             222      0.0009      0.0008       0.95         0.33            2
S6-S200: ort gecikme 0.24 tur, is payi 0.6114, istek payi 0.6143

-- A: kucukler hizlandi --
satici         istek  istek payi     is payi    gurultu  ort gecikme     en buyuk
---------- --------- ----------- ----------- ---------- ------------ ------------
S1             42541      0.1506      0.1540       1.02         0.48            2
S10             5113      0.0181      0.0180       1.00         0.72            3
S50             1030      0.0036      0.0036       0.99         0.90            3
S200             265      0.0009      0.0009       0.95         1.12            3
S6-S200: ort gecikme 0.85 tur, is payi 0.6485, istek payi 0.6560

-- B: en buyuk komsu taramayi siklastirdi --
satici         istek  istek payi     is payi    gurultu  ort gecikme     en buyuk
---------- --------- ----------- ----------- ---------- ------------ ------------
S1             42581      0.1690      0.2415       1.43         0.47            3
S10             4263      0.0169      0.0156       0.92         0.85            3
S50              860      0.0034      0.0031       0.91         1.02            3
S200             222      0.0009      0.0008       0.87         1.23            3
S6-S200: ort gecikme 0.98 tur, is payi 0.5589, istek payi 0.6142

-- pay ayirma acikken: is koruyan donusumlu paylastirma --
gun           S1 gec     S10 gec     S50 gec   S200 gec  S6-S200 ort  S1 en buyuk
---------- --------- ----------- ----------- ---------- ------------ ------------
arizasiz        0.48        0.00        0.00       0.00         0.00            7
A               3.27        0.00        0.00       0.00         0.00           13
B               2.96        0.00        0.00       0.00         0.00            9

karsiligi: B gununde S1'in ortalama gecikmesi 0.47 -> 2.96 tur, en buyuk 3 -> 9 tur
arizasiz gunde bile S1 oder: 0.10 -> 0.48 tur
muhasebe: 200 sayac, istek basina 1 dokunus; S1'in bolunemeyen istegi 681 birim, turdaki payi 2 birim

ayni B gunu, buyuk istek parcalanarak (pay ayirma yok):
  en buyuk parca 681 birim (turluk kapasitenin 1.26'si) -> S6-S200 ort gecikme 0.98 tur
  en buyuk parca  50 birim (turluk kapasitenin 0.09'si) -> S6-S200 ort gecikme 1.00 tur

Gecikmeler ve paylar ölçüm sınıfındadır: belirlenimli bir varış dizisi üzerinde sayılmışlardır. Kapasite, birim maliyetleri ve satıcı dağılımı varsayım, K01’den gelen hızlar hesap sınıfındadır.

İstek Payı Gürültüyü Göstermiyor

İki senaryo aynı belirtiyi veriyor. Küçük satıcıların ortalama beklemesi arızasız günde 0,24 tur; A gününde 0,85, B gününde 0,98. Yalnız bu sayıya bakan biri iki günü ayırt edemez.

Paylara bakıldığında ayrım keskinleşiyor. A gününde küçük satıcıların istek payı 0,6143’ten 0,6560’a, iş payı 0,6114’ten 0,6485’e çıkıyor; ikisi birlikte hareket ediyor. En büyük satıcının gürültü katsayısı — iş payının istek payına oranı — 1,01’de kalıyor. Yükü büyüten, bekleyenlerin kendisidir.

B gününde küçük satıcıların istek payı hiç değişmiyor: 0,6143 iken 0,6142. Buna karşılık iş payları 0,6114’ten 0,5589‘a düşüyor. Kaybettikleri pay en büyük satıcıya geçiyor: onun iş payı 0,1702’den 0,2415‘e, gürültü katsayısı 1,01’den 1,43’e çıkıyor. İstek payı ise 0,1689 ile 0,1690 arasında, yani sabittir.

Ayrımı yapan ölçüm budur. İstek sayısıyla tutulan bir muhasebede B günü hiçbir kiracıda kıpırtı üretmez; en büyük satıcının fazladan gönderdiği şey birkaç istektir, ama o birkaç istek 681’er birim taşır. Küçük bir satıcının aynı isteği 3 birimdir: 227 kat fark. Payı istekle ölçen bir sistem gürültülü komşuyu göremez, çünkü ölçtüğü nicelik kaynağın tükendiği nicelik değildir.

Pay Ayırma ve Karşılığı

Dönüşümlü paylaştırma açıldığında küçük satıcıların beklemesi üç günde de 0,00 tura iniyor. Sıra artık geliş anına göre değil kiracıya göre veriliyor ve kalan bütçe boşa gitmiyor — düzen iş korur. Dayanıklılık ve Güvenilirlik kursundaki bölme kalıbı aynı sorunun sert çözümüdür: havuz baştan bölünür, komşuluk ortadan kalkar ve bedeli orada atıl kalan kaynak olarak ölçülmüştü. Buradaki pay ayırma kaynağı atıl bırakmaz; bedeli başka yerdedir.

Bedel en büyük kiracıdadır. B gününde S1’in kendi ortalama gecikmesi 0,47’den 2,96 tura, en büyük gecikmesi 3’ten 9 tura çıkıyor. Nedeni son satırda: bölünemeyen tek isteği 681 birim, turda düşen payı ise 2 birim. Arızasız günde bile ödüyor — 0,10’dan 0,48 tura — hiçbir şey bozulmamışken.

İkinci bedel muhasebedir: iki yüz sayaç tutulur ve her istek bir kayıt dokunuşu ekler. Kiracı sayısı arttıkça bu yük kiracı sayısıyla büyür.

Üçüncü ölçüm bir yanlış çözümü eliyor. Büyük isteği parçalara bölmek tek başına hiçbir şey değiştirmiyor: en büyük parça 681’den 50 birime indiğinde küçük satıcıların beklemesi 0,98’den 1,00 tura çıkıyor. Parçalar da art arda aynı sıraya giriyor. Çözen şey parçanın küçüklüğü değil, sıranın kiracılar arasında dönüşümlü verilmesidir.

Bir uyarı: pay ayırma belirtiyi giderir ama nedeni ayırt etmez. A gününde de küçük satıcıların beklemesi sıfırlanıyor ve bedeli yine S1 ödüyor (3,27 tur), oysa o günkü yükü büyüten S1 değildi. Ölçüm yapılmadan konan bir pay kuralı, yanlış kiracıyı cezalandırır.

Paylaşmanın Doğru Olduğu Koşul

Paylaşmak her ölçekte yanlış değildir ve sınırı iki sayıyla verilir.

Gürültü katsayısı bire yakın kaldığı sürece. Arızasız günde dört satıcının katsayısı 0,95 ile 1,01 arasında; havuz 0,8951 dolulukla çalışıyor ve ortalama bekleme 0,24 tur. Bu koşulda paylaşmak yalnız zararsız değil, kârlıdır: hiçbir kiracıya ayrılmış atıl kapasite yoktur.

Hiçbir tek istek turluk kapasiteyi aşmadığı sürece. S1’in taraması 681 birim, turluk kapasite 540 — oran 1,26. Bölünemeyen bir istek bir turdan uzun sürüyorsa, arkasındaki her kiracı en az bir tur bekler ve bu, hiçbir hız kuralıyla önlenemez.

Özet

  • Belirti küçük kiracıların beklemesinin artmasıdır; iki nedeni vardır — kendi hızları artmıştır ya da bir komşu payını büyütmüştür. İkisi de beklemeyi 0,24’ten 0,85 ve 0,98 tura çıkarıyor.
  • Ayıran ölçüm istek payı ile iş payının ayrıştırılmasıdır. A gününde ikisi birlikte büyüyor; B gününde istek payı 0,6143’ten 0,6142’ye, yani hiç değişmezken iş payı 0,5589’a düşüyor.
  • Gürültü katsayısı en büyük satıcıda 1,01’den 1,43’e çıkıyor ve iş payı 0,1702’den 0,2415’e sıçrıyor; istek payı sabit kalıyor. İstekle tutulan bir muhasebe gürültüyü göremez.
  • Pay ayırma küçük kiracıların beklemesini üç günde de 0,00 tura indiriyor; karşılığında S1’in gecikmesi 0,47’den 2,96 tura, arızasız günde 0,10’dan 0,48 tura çıkıyor ve 200 sayaç tutulur.
  • Büyük isteği parçalamak tek başına yetmiyor (0,98 → 1,00 tur); çözen şey sıranın kiracılar arasında dönüşümlü verilmesidir.
  • Paylaşmak, gürültü katsayısı bire yakın ve hiçbir tek istek turluk kapasiteyi aşmıyorken doğrudur; S1’in 681 birimlik taraması 540 birimlik turu 1,26 kat aşıyor.

Sonraki Adım

Bu dersin bütün ölçümleri bir sayıyı sabit tuttu: havuzun turda 540 birim işlediği. O sayının nereden geldiği hiç sorulmadı. Bir sürecin taşıyabileceği iş, işlemcisinin hızıyla değil, aynı anda kaç isteği ilerletebildiğiyle sınırlıdır ve bu sınır çoğu zaman işlemciden çok önce dolar. Sonraki ders belirtiyi oradan alır: işçi eklendiği hâlde verim artmıyor ve işlemci doluluğu düşük. Bunun da iki nedeni vardır — aşağı akış doymuştur ya da işçiler engelleyen çağrılarda bekliyordur. İkisini ayıran ölçü doluluk değil, işçi-turun ne kadarının beklemeye gittiğidir; ve o pay, engelleyen çağrının süresiyle eşzamanlılık sınırının çarpımından çıkar.

İ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