İçeriğe geç
academia.sh

Ders 10 / 16

Yeniden Deneme Fırtınası

Arızayı büyüten geri bildirim döngüsünün dışarıdan tanınması: aynı çağrı hızı artışını veren iki nedenin uç hızı, tekil istek kimliği ve başarı oranıyla ayrılması, fırtınada çağrı hızının 4,00'ten 25,00'e çıkarken tekil kimliğin 4,00'te kalması, çağrı hızı ile başarı oranının çarpımının kapasite sınırında sabit kalması ve deneme iznini kısmanın 180 düşen isteğe mal olması.

İçindekiler

Dokuz kalıbın hepsi bir varsayımın üstünde durdu: bir isteğin bir kez yapıldığı. Uçtan gelen yük dışarıdan belirlenir, sistem onu yalnız taşır. Bu varsayım bir şey bozulduğu anda düşer.

Belirti şudur: bağımlılığa varan çağrı hızı altı katına çıktı. Yeniden deneme kararı, üstel geri çekilme, sarsıntı ve deneme bütçesi Uygulama Mimarisi, Önbellekleme, Kuyruklar ve Eşzamansız İşleme ve Dayanıklılık ve Güvenilirlik kurslarında kuruldu ve ölçüldü; hiçbiri yeniden hesaplanmaz. Çizelge bir girdidir. Buradaki soru tanıdır: böyle bir hız artışı dışarıdan nasıl görünür ve hangi ölçüt onu gerçek bir talep artışından ayırır.

Aynı Belirti, İki Neden

Birinci neden: dış talep gerçekten arttı. Uçtan gelen istek hızı yükselmiştir; bağımlılığa varan çağrı da onunla birlikte yükselir. Sistem sağlıklıdır, yalnız daha çok iş yapmaktadır.

İkinci neden: dış talep sabit, zincir yeniden deniyor. Bağımlılık bozulmuştur, çağrılar başarısız olmaktadır ve zincirin her katmanı kendi başına yeniden dener. İzinler çarpılır ve bağımlılığa varan yük artık dışarıdan değil, sistemin kendisinden gelir. Buna yeniden deneme fırtınası (retry storm) denir.

İkisi de bağımlılıkta aynı sayıyı büyütür. Çağrı hızına bakan bir uyarı ikisini ayıramaz.

Zincir

Aşağıdaki koşum bir modeldir: tur soyut bir adımdır ve gerçek küme kurulmaz. KK15 — zincir ve çizelge. Üç katman, katman başına üç deneme, denemeler arası dört tur, bağımlılığın olağan kapasitesi turda 12 çağrı, dış talep turda 4 istek. Gerekçe: çizelge önceki kurslarda kararlaştırıldı ve burada girdi olarak alınır; kapasite payı dış talebin üç katıdır. Arıza, kapasitenin 101–160 turları arasında 1 çağrıya inmesidir. Duyarlılığı deneme izni üzerinden verilir. Bu varsayımlar K01’in tablosuna eklenmez.

// firtina/zincir.mjs — uc katmanli zincirin MODELI. Tur soyut bir adimdir. Geri cekilme
// cizelgesi ve deneme butcesi burada hesaplanmaz; onceki kurslarda kararlastirilmis bir
// GIRDI olarak alinir (sabit aralik, katman basina sabit izin).
export const KK15 = { katman: 3, izin: 3, aralik: 4, kapasite: 12, disTalep: 4 };

export function kosum({ tur = 400, disTalep = KK15.disTalep, izin = KK15.izin,
                        arizaBas = 101, arizaSon = 160, arizaKapasite = 1 }) {
  const { katman, aralik, kapasite } = KK15;
  const uctan = [], cagri = [], basarili = [], dusen = [], kimlik = [];
  const aktif = [];                       // { id, sayac: [k0,k1,k2], zaman }
  let siradaki = 1, birikim = 0;

  for (let t = 1; t <= tur; t += 1) {
    birikim += typeof disTalep === "function" ? disTalep(t) : disTalep;
    let gelen = 0;
    while (birikim >= 1) {
      birikim -= 1; gelen += 1;
      aktif.push({ id: siradaki++, sayac: new Array(katman).fill(0), zaman: t });
    }
    uctan.push(gelen);

    const buTur = aktif.filter((r) => r.zaman === t);
    let jeton = t >= arizaBas && t <= arizaSon ? arizaKapasite : kapasite;
    let b = 0, d = 0;
    const gorulen = new Set();
    for (const r of buTur) {
      gorulen.add(r.id);                  // bagimlilik cagriyi gorur (reddedilse de)
      if (jeton > 0) { jeton -= 1; b += 1; aktif.splice(aktif.indexOf(r), 1); continue; }
      let k = katman - 1;                 // sayac odometresi: en derin katmandan yukari tasar
      while (k >= 0) {
        r.sayac[k] += 1;
        if (r.sayac[k] < izin) break;
        r.sayac[k] = 0; k -= 1;
      }
      if (k < 0) { d += 1; aktif.splice(aktif.indexOf(r), 1); }   // butun izinler tukendi
      else r.zaman = t + aralik;
    }
    cagri.push(buTur.length); basarili.push(b); dusen.push(d); kimlik.push(gorulen);
  }
  return { uctan, cagri, basarili, dusen, kimlik };
}

// Pencere ozeti: tekil kimlik pencerenin tamaminda sayilir, tur icinde degil.
export function pencere(r, bas, son) {
  const topla = (a) => a.slice(bas - 1, son).reduce((x, y) => x + y, 0);
  const n = son - bas + 1;
  const tekil = new Set();
  for (const s of r.kimlik.slice(bas - 1, son)) for (const id of s) tekil.add(id);
  const c = topla(r.cagri);
  return {
    uc: topla(r.uctan) / n, cagri: c / n, tekil: tekil.size / n,
    carpan: tekil.size === 0 ? 0 : c / tekil.size,
    basari: c === 0 ? 0 : topla(r.basarili) / c, dusen: topla(r.dusen),
  };
}
// firtina/olcum.mjs — ayni belirtiyi veren iki neden ve firtinayi ayirt eden olcutler
import { KK15, kosum, pencere } from "./zincir.mjs";

const EN = [24, 8, 10, 10, 8, 8];
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 satir = (ad, p) => yaz([ad, p.uc.toFixed(2), p.cagri.toFixed(2), p.tekil.toFixed(2),
  p.carpan.toFixed(2), p.basari.toFixed(4)]);

console.log(`zincir ${KK15.katman} katman, katman basina ${KK15.izin} deneme, aralik ${KK15.aralik} tur,` +
  ` bagimliligin olagan kapasitesi ${KK15.kapasite} cagri/tur, dis talep ${KK15.disTalep} istek/tur`);
console.log(`aritmetik ust sinir: ${KK15.izin}^${KK15.katman} = ${KK15.izin ** KK15.katman} cagri/istek;` +
  ` pencere 101-160 turlari\n`);

// Neden 1: dis talep gercekten artiyor, ariza yok. Neden 2: talep sabit, bagimlilik bozuluyor.
const organik = kosum({ disTalep: (t) => (t >= 101 && t <= 160 ? 8 : 4), arizaKapasite: KK15.kapasite });
const firtina = kosum({});
const denemesiz = kosum({ izin: 1 });

yaz(["durum", "uc/tur", "cagri/tur", "tekil/tur", "carpan", "basari"]);
cizgi();
for (const [ad, r] of [["talep artti", organik], ["firtina", firtina], ["denemesiz", denemesiz]]) {
  satir(`${ad}: once`, pencere(r, 1, 100));
  satir(`${ad}: sirasinda`, pencere(r, 101, 160));
  satir(`${ad}: sonra`, pencere(r, 161, 400));
}

// Geri donus: ariza bittikten sonra cagri hizinin olagan seviyeye inmesi kac tur suruyor.
const olagan = pencere(firtina, 1, 100).cagri;
const donus = (r) => {
  for (let t = 161; t <= 400; t += 1) if (r.cagri[t - 1] <= olagan * 1.1) return t - 160;
  return -1;
};
// Karsilanan cagri/tur = cagri hizi x basari orani; kapasite sinirinda bu carpim sabittir.
const carp = (r) => { const p = pencere(r, 101, 160); return (p.cagri * p.basari).toFixed(2); };
console.log(`\ncagri hizi x basari orani (karsilanan cagri/tur): talep artti ${carp(organik)},` +
  ` firtina ${carp(firtina)}, denemesiz ${carp(denemesiz)}`);
console.log(`olagan cagri hizi ${olagan.toFixed(2)}/tur; ariza 160. turda bitiyor`);
console.log(`geri donus ${donus(firtina)} tur (denemesiz duzende ${donus(denemesiz)} tur);` +
  ` firtinanin tepe cagri hizi ${Math.max(...firtina.cagri)}/tur = olaganin` +
  ` ${(Math.max(...firtina.cagri) / olagan).toFixed(2)} kati`);

// Duzeltmenin karsiligi: izin kisildiginda ayni arizada ne kazanilip ne kaybediliyor.
console.log(`\nizni kismanin karsiligi (ayni ariza, 101-400 turlari):`);
yaz(["izin", "cagri/tur", "carpan", "dusen istek", "donus", "basari"]);
cizgi();
for (const izin of [3, 2, 1]) {
  const r = kosum({ izin });
  const p = pencere(r, 101, 160), o = pencere(r, 1, 100).cagri;
  let g = -1;
  for (let t = 161; t <= 400; t += 1) if (r.cagri[t - 1] <= o * 1.1) { g = t - 160; break; }
  yaz([`katman basina ${izin}`, p.cagri.toFixed(2), p.carpan.toFixed(2),
    pencere(r, 101, 400).dusen, g, p.basari.toFixed(4)]);
}
zincir 3 katman, katman basina 3 deneme, aralik 4 tur, bagimliligin olagan kapasitesi 12 cagri/tur, dis talep 4 istek/tur
aritmetik ust sinir: 3^3 = 27 cagri/istek; pencere 101-160 turlari

durum                      uc/tur  cagri/tur  tekil/tur   carpan   basari
------------------------ -------- ---------- ---------- -------- --------
talep artti: once            4.00       4.00       4.00     1.00   1.0000
talep artti: sirasinda       8.00       8.00       8.00     1.00   1.0000
talep artti: sonra           4.00       4.00       4.00     1.00   1.0000
firtina: once                4.00       4.00       4.00     1.00   1.0000
firtina: sirasinda           4.00      25.00       4.00     6.25   0.0400
firtina: sonra               4.00       6.50       4.75     1.37   0.7308
denemesiz: once              4.00       4.00       4.00     1.00   1.0000
denemesiz: sirasinda         4.00       4.00       4.00     1.00   0.2500
denemesiz: sonra             4.00       4.00       4.00     1.00   1.0000

cagri hizi x basari orani (karsilanan cagri/tur): talep artti 8.00, firtina 1.00, denemesiz 1.00
olagan cagri hizi 4.00/tur; ariza 160. turda bitiyor
geri donus 25 tur (denemesiz duzende 1 tur); firtinanin tepe cagri hizi 49/tur = olaganin 12.25 kati

izni kismanin karsiligi (ayni ariza, 101-400 turlari):
izin                     cagri/tur     carpan dusen istek    donus   basari
------------------------ -------- ---------- ---------- -------- --------
katman basina 3             25.00       6.25          0       25   0.0400
katman basina 2             22.33       5.58         68       17   0.0448
katman basina 1              4.00       1.00        180        1   0.2500

Bütün sayılar belirlenimli bir koşumdan çıkan hesap sınıfındadır; zincir, çizelge ve arıza penceresi varsayım sınıfındadır.

Fırtına Dışarıdan Nasıl Görünür

İki senaryonun ortak yanı ilk bakışta ayırt edilemez: bağımlılığa varan çağrı hızı iki durumda da büyüyor. Ayrımı üç ölçüt yapıyor ve üçü de bağımlılıkta toplanabilir.

Uçtaki hız. Talep arttığında uç 4,00’ten 8,00’e çıkıyor; fırtınada 4,00’te kalıyor. Bir çağrı hızı artışı uçta karşılığı olmadan gerçekleşiyorsa, artan yükü sistemin kendisi üretiyordur.

Tekil istek kimliği. Bu, ölçütlerin en keskinidir. Talep arttığında bağımlılığın gördüğü tekil kimlik 4,00’ten 8,00’e çıkıyor — yeni istekler var. Fırtınada tekil kimlik 4,00’te sabit kalırken çağrı 25,00’e çıkıyor: aynı istekler yeniden ve yeniden geliyor. Çağrı sayısının tekil kimliğe oranı, gözlenen çağrı çarpanıdır ve burada 1,00’e karşı 6,25. Aritmetik üst sınır 27; gözlenen ondan küçüktür, çünkü denemeler zamana yayılmıştır.

Başarı oranı. Talep arttığında başarı 1,0000’de kalıyor. Fırtınada çağrı hızı altı katına çıkarken başarı 1,0000’den 0,0400’e düşüyor. Hız ve başarı ters yönde hareket ediyorsa, büyüyen şey iş değil, aynı işin tekrarıdır.

Dördüncü işaret zamandadır. Arıza 160. turda bitiyor, ama çağrı hızı olağan düzeye ancak 25 tur sonra iniyor; yeniden deneme yapmayan düzende bu süre 1 turdur. Fırtına, arızadan uzun yaşar.

Kapasite Sınırının İmzası

Bir sayı fırtınanın niteliğini de veriyor. Çağrı hızı ile başarı oranının çarpımı, bağımlılığın gerçekten karşıladığı çağrı sayısıdır. Fırtınada bu çarpım 1,00; yeniden deneme yapmayan düzende de 1,00. Yani yirmi beş kat daha çok çağrı, karşılanan çağrı sayısını hiç değiştirmiyor — bağımlılığın kapasitesi neyse odur ve denemeler yalnız kendi paylarını küçültüyor. Talep arttığı senaryoda aynı çarpım 8,00, yani uçtaki hızın kendisi.

Bu, denemenin ne zaman zararlı olduğunu söyleyen ayrımdır. Bağımlılık geçici bir hatayla tek tek çağrıları düşürüyorsa denemeler çarpımı büyütür ve iş biter. Bağımlılık kapasite sınırındaysa çarpım sabittir: her yeni deneme, başka bir isteğin denemesini düşürür. Dayanıklılık ve Güvenilirlik kursunun ölçtüğü çarpan bu ikinci durumda doğrudan bir arıza uzatıcısına dönüşür.

Düzeltmenin Karşılığında Büyüyen

Son tablo düzeltmenin bedelini sayıyor. Deneme izni katman başına 3’ten 2’ye indiğinde çağrı hızı 25,00’ten 22,33’e, geri dönüş 25 turdan 17 tura iniyor — ve 68 istek düşüyor. İzin 1’e indiğinde fırtına tümüyle kayboluyor (çağrı 4,00, çarpan 1,00, geri dönüş 1 tur), ama düşen istek 180’e çıkıyor.

Karşılık nettir: fırtınayı kısmak, arıza penceresinde hiç yanıtlanmayan istek demektir. Üç izinle tek bir istek bile düşmüyor; bedeli, bağımlılığın altı kat fazla çağrı görmesi ve arızanın yirmi beş tur uzamasıdır. Bu değiş tokuş bir ölçüm olmadan yapılamaz, çünkü iki ucu da sayıdır.

Yeniden Denemenin Doğru Olduğu Koşul

Yeniden deneme, çağrı çarpanı bağımlılığın kapasite payının altında kaldığı sürece doğrudur. Buradaki sayılarla: olağan çağrı hızı 4,00 ve kapasite 12 çağrı/tur, yani pay 3,00 kat. Gözlenen çarpan 6,25 bu payı aşıyor ve fırtına tam da bu yüzden oluşuyor. Çarpan payın altında kalsaydı denemeler bedelsiz olurdu.

İkinci koşul arızanın türüdür. Çağrı hızı ile başarı oranının çarpımı çağrı hızından bağımsız sabit kalıyorsa bağımlılık kapasite sınırındadır ve deneme hakkını artırmak hiçbir isteği daha kurtarmaz. Çarpım çağrı hızıyla birlikte büyüyorsa hata geçicidir ve deneme ucuzdur.

Özet

  • Belirti bağımlılığa varan çağrı hızının büyümesidir; iki nedeni vardır — dış talep artmıştır ya da zincir yeniden denemektedir. Çağrı hızına bakan bir ölçüm ikisini ayıramaz.
  • Uçtaki hız birinci nedende 4,00’ten 8,00’e çıkar, fırtınada 4,00’te kalır. Bağımlılığın gördüğü tekil istek kimliği birinci nedende 8,00’e çıkar, fırtınada 4,00’te sabit kalır.
  • Gözlenen çağrı çarpanı 1,00’e karşı 6,25; başarı oranı 1,0000’e karşı 0,0400. Hız ve başarı ters yönde hareket ediyorsa büyüyen şey iş değil, aynı işin tekrarıdır.
  • Fırtına arızadan uzun yaşar: kapasite 160. turda düzeldiği hâlde çağrı hızı 25 tur sonra olağana iniyor; yeniden deneme yapmayan düzende bu süre 1 tur.
  • Çağrı hızı ile başarı oranının çarpımı fırtınada da denemesiz düzende de 1,00; yirmi beş kat çağrı karşılanan çağrı sayısını değiştirmiyor. Bu, bağımlılığın kapasite sınırında olduğunun imzasıdır.
  • İzni kısmanın karşılığı düşen istektir: izin 3’te 0, 2’de 68, 1’de 180 istek düşüyor; buna karşılık geri dönüş 25 turdan 1 tura iniyor.

Sonraki Adım

Bu konu on belirtiyi on nedene bağladı ve her birinde ayrımı yapan şey aynı türden bir şey oldu: bir sayı. Hesabın hangi katmanda yapıldığı taranan kayıtla, ana iş parçacığındaki iş kaynak ayrımıyla, çağrı sayısı ile taşınan bayt arasındaki ödünleşim istek başına dokunuşla, gereksiz alanlar uçtan uca bayt sayısıyla, pahalı istemci kurulum işiyle, tek parça kalıcılık kendi sınıfına hizmet eden dizin payıyla, önbelleksizlik hesap tekrarıyla, gürültülü komşu iş payıyla, engelleyen çağrı bağımlılık doluluğuyla ve yeniden deneme fırtınası tekil istek kimliğiyle ayrıldı.

Bu on tanının hepsi tek bir koşula bağlıdır: o ölçüm var olmalıdır. Oysa hangi ölçütün toplanacağı bu konuda hiç tasarlanmadı. Tekil istek kimliği bağımlılıkta sayılıyor mu; iş payı kiracıya göre tutuluyor mu; bağımlılığın kendi doluluğu görülüyor mu; hesap çağrıları anahtarıyla birlikte kaydediliyor mu. Bunların hiçbiri kendiliğinden var olmaz; her biri bir tasarım kararıdır ve her birinin bir bedeli vardır. Sonraki konu o katmanı kurar: hangi ölçüt kategorileri eksiksiz bir izleme yüzeyi oluşturur, neyi ölçmeye değer, hangi eşik bir uyarı doğurur, yük nasıl sınanır ve ölçülen sayı kaç düğüme çevrilir.

İ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