İçeriğe geç
academia.sh

Ders 06 / 30

Kapsül

Kümeye bildirilen en küçük dağıtım biriminin ölçüsü: bir arada tutulan üç şeyin ne kazandırdığı, iki süreci tek kapsülde ya da iki kapsülde paketlemenin ölçek birimi, arıza yayılımı, kaynak muhasebesi ve ağ turu cinsinden farkı.

İçindekiler

Küme kuruldu, uzlaşma döngüsü döner hâle geldi: bir yerde istenen durum durur, bir yerde gerçek durum ölçülür, aradaki fark bir düzeltmeye çevrilir. Bu döngünün ölçüsü çıkarıldı — kaç turda yakınsadığı, tur başına ne kadar iş yaptığı, gecikmiş bilgiyle kaç yanlış düzeltme ürettiği. Ama döngünün üzerinde çalıştığı şeyin kendisi hiç tanımlanmadı. Kümeye ne bildiriliyor? İstenen durum bir sayı değildir; bir nesnedir ve o nesnenin sınırları, uzlaştırıcının neyi tek parça sayıp neyi ayrı ayrı düzelteceğini belirler.

Bu konunun ilk kararı da orada başlar: kümeye bildirilebilecek en küçük parça nedir. Yanıt tek bir konteyner değildir. En küçük dağıtım birimi, birlikte taşınmayı bildiren bir konteyner kümesidir; bu birime bu kursta kapsül denir (İngilizce karşılığı pod). Bu ders kapsülün ne tuttuğunu sayar ve iki paketleme kararını dört ölçüyle karşılaştırır. Ölçülen şey node ile kurulan bir modeldir; gerçek bir küme koşturulmaz.

TN1 — bölgesel ölçüm ağı bu kursta bir küme üzerinde koşar: sayaç okumalarını toplayan, doğrulayan ve faturaya çeviren bu yazılım kurgudur. TN2 — bir kapsülün içindeki süreçler üç şeyi paylaşır: aynı ağ adı, aynı yerel dosya alanı, aynı yaşam süresi. TN3 — ayrı kapsüllerdeki iki süreç arasındaki her alışveriş bir ad çözümleme ve bir ağ turu ekler, aynı kapsülde bu sayı sıfırdır. TN4 — okuma toplayıcı altı, günlük dönüştürücü iki kopya gerektirir; doğrulayıcı ile yerel önbellek dörder, faturalama ile iş emri üçer. TN5 — kapsül içindeki bir süreç çökerse kapsülün tamamı yeniden başlar ve iki tur hizmet vermez. TN6 — kaynak isteği ve sınır kapsül düzeyinde bildirilir; içerideki süreçlerin ayrı hesabı tutulmaz.

Sınır Nerede Çizilir

Okuma toplayıcının yanında bir günlük dönüştürücü koşar: toplayıcının ürettiği ham satırları okur, biçimlendirir, dışarı verir. Bu iki süreç aynı kapsülde mi paketlenecek, ayrı kapsüllerde mi? Soru bir tercih gibi görünür; aşağıdaki model soruyu dört sayıya indirir.

// kapsul.mjs — iki paketleme kararinin olculmesi (MODEL; gercek kume kosturulmaz).
// TN1-TN6 varsayimlari koda gomulu; butun sayilar bu dosyadan cikar.

export const SURECLER = {
  'okuma-toplayici':    { kopya: 6, ortakDosya: true,  alisveris: 120 },
  'gunluk-donusturucu': { kopya: 2, ortakDosya: true,  alisveris: 120 },
  'dogrulayici':        { kopya: 4, ortakDosya: false, alisveris: 400 },
  'yerel-onbellek':     { kopya: 4, ortakDosya: false, alisveris: 400 },
  'faturalama':         { kopya: 3, ortakDosya: false, alisveris: 12 },
  'is-emri':            { kopya: 3, ortakDosya: false, alisveris: 12 },
};

export const TUR = 2;                                    // TN3: ad cozumleme + ag turu
export const PAYLASILAN = ['ag adi', 'yerel dosya alani', 'yasam suresi'];

// Iki paketleme karari, ayni sureci ayni yuk altinda tutar; degisen yalniz sinirdir.
export function paketle(a, b) {
  const A = SURECLER[a], B = SURECLER[b];
  const en = Math.max(A.kopya, B.kopya), top = A.kopya + B.kopya;
  const alisveris = Math.min(A.alisveris, B.alisveris);
  return {
    alisveris,
    birlikte: { kapsul: en, surec: 2 * en, fazla: 2 * en - top, olcekBirimi: 1,
      ariza: 2, muhasebe: en, surecHesabi: 0, tur: 0, ekBildirim: 0 },
    ayri: { kapsul: top, surec: top, fazla: 0, olcekBirimi: 2,
      ariza: 1, muhasebe: top, surecHesabi: top, tur: TUR * alisveris,
      ekBildirim: PAYLASILAN.length },
  };
}

// Devredilen karar: bu iki surec ayni kapsulde mi tasinacak?
export const BILGI = ['ortak dosya', 'alisveris sikligi', 'kopya orani'];
const ESIK = 100;

export function karar(k) {
  const eksik = BILGI.filter((x) => k[x] === undefined);
  if (eksik.length) return { sonuc: 'karar verilemez', not: `eksik: ${eksik.join(', ')}` };
  const sik = k['ortak dosya'] || k['alisveris sikligi'] >= ESIK;
  if (k['kopya orani'] !== 1 && sik) return { sonuc: 'catisma', not: 'iki olcut ters yonde' };
  if (k['kopya orani'] !== 1) return { sonuc: 'ayri kapsul', not: 'kopya orani 1 degil' };
  if (sik) return { sonuc: 'ayni kapsul', not: 'siki bagli, oran 1' };
  return { sonuc: 'ayri kapsul', not: 'seyrek alisveris' };
}

export function kayit(a, b) {
  const A = SURECLER[a], B = SURECLER[b];
  return { 'ortak dosya': A.ortakDosya && B.ortakDosya,
    'alisveris sikligi': Math.min(A.alisveris, B.alisveris),
    'kopya orani': Math.max(A.kopya, B.kopya) / Math.min(A.kopya, B.kopya) };
}

export const CIFTLER = [
  ['okuma-toplayici', 'gunluk-donusturucu', 'toplayici+donusturucu'],
  ['dogrulayici', 'yerel-onbellek', 'dogrulayici+onbellek'],
  ['faturalama', 'is-emri', 'faturalama+is-emri'],
];

if (import.meta.url === `file://${process.argv[1]}`) {
  const s = (x, n) => String(x).padStart(n);
  console.log(`${'cift'.padEnd(23)}${'sinir'.padEnd(12)}${s('kapsul', 7)}${s('surec', 6)}`
    + `${s('fazla', 6)}${s('olcek', 6)}${s('ariza', 6)}${s('hesap', 6)}${s('tur', 6)}`
    + `${s('bildirim', 9)}`);
  for (const [a, b, ad] of CIFTLER) {
    const p = paketle(a, b);
    for (const [sinir, r] of [['tek kapsul', p.birlikte], ['iki kapsul', p.ayri]]) {
      console.log(`${ad.padEnd(23)}${sinir.padEnd(12)}`
        + `${s(r.kapsul, 7)}${s(r.surec, 6)}${s(r.fazla, 6)}${s(r.olcekBirimi, 6)}`
        + `${s(r.ariza, 6)}${s(r.surecHesabi, 6)}${s(r.tur, 6)}${s(r.ekBildirim, 9)}`);
    }
  }

  console.log(`\npaylasilan kalem (tek kapsul): ${PAYLASILAN.join(', ')} = ${PAYLASILAN.length}`);
  console.log(`ayri kapsulde her biri ayri bir bildirim kalemine doner: ${PAYLASILAN.length}`);

  console.log(`\n${'cift'.padEnd(25)}${'karar'.padEnd(16)}gerekce`);
  for (const [a, b, ad] of CIFTLER) {
    const r = karar(kayit(a, b));
    console.log(`${ad.padEnd(25)}${r.sonuc.padEnd(16)}${r.not}`);
  }
  const eksikK = { ...kayit('faturalama', 'is-emri') };
  delete eksikK['kopya orani'];
  const r = karar(eksikK);
  console.log(`${'faturalama+is-emri (kor)'.padEnd(25)}${r.sonuc.padEnd(16)}${r.not}`);

  // Bilginin maliyeti: 'kopya orani' bilinmezse sistem yine de paketlemek zorundadir.
  let yanlis = 0, fazlaSurec = 0;
  for (const [a, b] of CIFTLER) {
    const k = kayit(a, b);
    const tam = karar(k);
    const korK = { ...k }; delete korK['kopya orani'];
    const kor = korK['ortak dosya'] || korK['alisveris sikligi'] >= ESIK
      ? 'ayni kapsul' : 'ayri kapsul';
    const dogruYer = tam.sonuc === 'ayni kapsul' ? 'ayni kapsul' : 'ayri kapsul';
    if (kor !== dogruYer) { yanlis++; fazlaSurec += paketle(a, b).birlikte.fazla; }
  }
  console.log(`\nkopya orani bilinmezse: ${CIFTLER.length} ciftin ${yanlis}'inde yanlis paketleme,`
    + ` ${fazlaSurec} gereksiz surec ornegi`);
}
cift                   sinir        kapsul surec fazla olcek ariza hesap   tur bildirim
toplayici+donusturucu  tek kapsul        6    12     4     1     2     0     0        0
toplayici+donusturucu  iki kapsul        8     8     0     2     1     8   240        3
dogrulayici+onbellek   tek kapsul        4     8     0     1     2     0     0        0
dogrulayici+onbellek   iki kapsul        8     8     0     2     1     8   800        3
faturalama+is-emri     tek kapsul        3     6     0     1     2     0     0        0
faturalama+is-emri     iki kapsul        6     6     0     2     1     6    24        3

paylasilan kalem (tek kapsul): ag adi, yerel dosya alani, yasam suresi = 3
ayri kapsulde her biri ayri bir bildirim kalemine doner: 3

cift                     karar           gerekce
toplayici+donusturucu    catisma         iki olcut ters yonde
dogrulayici+onbellek     ayni kapsul     siki bagli, oran 1
faturalama+is-emri       ayri kapsul     seyrek alisveris
faturalama+is-emri (kor) karar verilemez eksik: kopya orani

kopya orani bilinmezse: 3 ciftin 1'inde yanlis paketleme, 4 gereksiz surec ornegi

Birinci çift, kapsül sınırının neden bir tercih olmadığını gösteriyor. Toplayıcı altı, dönüştürücü iki kopya ister. Tek kapsülde ölçek birimi birdir: altı kapsül açılır, on iki süreç örneği koşar, dördü hiçbir yükü karşılamaz. Dört fazla süreç örneği, ölçek biriminin bir olmasının doğrudan bedelidir — dönüştürücü, ihtiyacı olmadığı hâlde toplayıcının ölçeğine binmiştir. İki kapsülde bu dört örnek yok olur, karşılığında iki yüz kırk ağ turu doğar: yüz yirmi alışverişin her biri bir ad çözümleme ve bir ağ turu öder.

İkinci çift aynı hesabın tersini veriyor. Doğrulayıcı ile yerel önbelleğin kopya sayıları eşit, bu yüzden tek kapsülde fazla süreç örneği sıfırdır; ayırmanın kazandırdığı hiçbir şey yoktur ve sekiz yüz ağ turu ödenir. Sıkı bağlı, aynı oranda ölçeklenen yardımcı süreçler kapsül sınırının içine girer; bu, sınırın var olma nedenidir. Üçüncü çift üçüncü durumu gösteriyor: eşit ölçek, ama seyrek alışveriş. Yirmi dört tur ucuzdur; ayırmak, arıza yayılımını ikiden bire indirmek ve süreç başına kaynak muhasebesi kazanmak için yeterli gerekçedir.

Kaynak muhasebesi sütunu TN6’nın doğrudan sonucudur. Tek kapsülde altı muhasebe kalemi vardır ama süreç başına hesap sıfırdır: kapsülün isteği ve sınırı iki sürecin toplamıdır, hangisinin ne kadar tükettiği bildirimde görünmez. İki kapsülde sekiz kalem ve sekiz süreç hesabı olur. Bu fark ölçekleme kararına girer — neyin büyüdüğünü bilmeyen bir sistem, ikisini birden büyütür.

Son satır bildirim bedelini sayıyor. Tek kapsülde paylaşılan üç kalem bedavadır çünkü sınırın kendisi onları verir. Ayırmak üçünü de bir bildirim kalemine çevirir: ağ adı bir servis nesnesine, yerel dosya alanı bir aktarım biçimine, ortak yaşam süresi de artık var olmayan bir güvenceye. Tek makinedeki bileşim dosyası da birden çok süreci tek dosyada toplar; farkı, orada birlikteliğin aynı makinede olmak demesi, kapsülde ise birlikte taşınmak, birlikte ölmek ve tek bir adı paylaşmak demesidir. Bileşim dosyasının başlatma dalgaları ve hazır olma denetimi ölçümü orada yapıldı; burada tekrarlanmaz, karşılaştırma girdisi olur.

Aynı Yaşam Süresinin Bedeli

Ölçek, tur ve muhasebe sayıları sabit bir tablodan okunur. Üçüncü paylaşılan kalem — aynı yaşam süresi — ancak zaman içinde görünür. İkinci koşum aynı arıza dizisini iki paketlemeye uygular.

// yasam.mjs — ayni yasam suresinin bedeli: ayni ariza dizisi iki paketlemeye uygulanir (MODEL).
import { SURECLER } from './kapsul.mjs';

const TOHUM = 20260801, TUR_SAYISI = 24, ONARIM = 2, SIKLIK = 0.35;
// Uretec kendi yazildi; 32 bitlik tam sayi islemleri, tohum gorunur.
const uret = (t) => () => { t ^= t << 13; t ^= t >>> 17; t ^= t << 5; return (t >>> 0) / 2 ** 32; };

// Gereken surec ornekleri: 6 toplayici + 2 donusturucu. Ariza dizisi bir kez uretilir.
const GEREKLI = [
  ...Array.from({ length: SURECLER['okuma-toplayici'].kopya }, (_, i) => ['toplayici', i]),
  ...Array.from({ length: SURECLER['gunluk-donusturucu'].kopya }, (_, i) => ['donusturucu', i]),
];
const rnd = uret(TOHUM);
const ARIZALAR = Array.from({ length: TUR_SAYISI },
  () => (rnd() < SIKLIK ? GEREKLI[Math.floor(rnd() * GEREKLI.length)] : null));

// Tek kapsul: kapsul i hem toplayici i hem donusturucu i tasir; biri duserse ikisi de duser.
// Iki kapsul: her surec ornegi kendi kapsulunde; ariza yalniz onu dusurur.
function kosum(birlikte) {
  const bosta = {};                                      // surec ornegi -> ne zamana kadar dusuk
  let dusen = 0, komsu = 0;
  const eksikTur = { toplayici: 0, donusturucu: 0 };
  for (let t = 0; t < TUR_SAYISI; t++) {
    if (ARIZALAR[t]) {
      const [rol, i] = ARIZALAR[t];
      // Kapsul i, tek kapsul sinirinda hem toplayici i hem donusturucu i tasir. TN5.
      for (const [r, k] of birlikte ? [['toplayici', i], ['donusturucu', i]] : [[rol, i]]) {
        const anahtar = `${r}#${k}`;
        if (!GEREKLI.some(([x, y]) => x === r && y === k)) continue;
        if ((bosta[anahtar] ?? -1) < t) { dusen++; if (r !== rol) komsu++; }
        bosta[anahtar] = t + ONARIM;
      }
    }
    for (const rol2 of ['toplayici', 'donusturucu']) {
      const ad = rol2 === 'toplayici' ? 'okuma-toplayici' : 'gunluk-donusturucu';
      const ayakta = Array.from({ length: SURECLER[ad].kopya }, (_, k) => `${rol2}#${k}`)
        .filter((a) => (bosta[a] ?? -1) < t).length;
      if (ayakta < SURECLER[ad].kopya) eksikTur[rol2]++;
    }
  }
  return { dusen, komsu, ...eksikTur };
}

const s = (x, n) => String(x).padStart(n);
console.log(`tohum ${TOHUM}, ${TUR_SAYISI} tur, ${ARIZALAR.filter(Boolean).length} ariza,`
  + ` onarim ${ONARIM} tur`);
console.log(`${'sinir'.padEnd(12)}${s('dusen', 7)}${s('komsu yuzunden', 16)}`
  + `${s('toplayici eksik', 17)}${s('donusturucu eksik', 19)}`);
for (const [ad, b] of [['tek kapsul', true], ['iki kapsul', false]]) {
  const r = kosum(b);
  console.log(`${ad.padEnd(12)}${s(r.dusen, 7)}${s(r.komsu, 16)}${s(`${r.toplayici} tur`, 17)}`
    + `${s(`${r.donusturucu} tur`, 19)}`);
}
tohum 20260801, 24 tur, 11 ariza, onarim 2 tur
sinir         dusen  komsu yuzunden  toplayici eksik  donusturucu eksik
tek kapsul       13               3           22 tur              7 tur
iki kapsul       10               0           20 tur              4 tur

On bir arıza iki paketlemede on üç ve on düşüş üretiyor. Aradaki üç fark ile üçüncü sütundaki üç sayı aynı şeyi söylüyor: tek kapsülde üç süreç örneği, kendisiyle ilgisi olmayan bir arıza yüzünden düştü. Bu üç düşüşün hiçbirinde dönüştürücünün ya da toplayıcının kendi kodunda bir sorun yoktu; komşusu çöktü, kapsül yeniden başladı, o da onunla gitti. İki kapsül sınırında bu sütun sıfırdır — arıza, bildirimde çizilen sınırın dışına çıkmaz.

Son sütun bunun hizmete yansımasıdır. Dönüştürücü, tek kapsülde yirmi dört turun yedisinde eksik kopyayla çalıştı, ayrı kapsülde dördünde. Üç turluk fark küçük görünür; asıl büyüyen oran değil nedendir: dönüştürücünün eksik turlarının neredeyse yarısı kendi arızasından değil, komşusunun arızasından gelir ve bu pay, kapsüle konan süreç sayısıyla artar. Aynı yaşam süresi bir kolaylık olarak bildirilir, bir kesinti kaynağı olarak ödenir.

Devredilen Karar ve Bilmediği Şey

Bu derste insandan sisteme geçen karar şudur: hangi süreçler tek parça olarak taşınacak. Karar verildikten sonra yerleştirme, yeniden başlatma ve ölçekleme bu parçanın üzerinden yürür; sistem kapsülün içine bakmaz. Kararın dayandığı bilgi kalemleri modelde adlandırılmıştır ve üç tanedir: ortak dosya kullanımı, alışveriş sıklığı, kopya oranı. Üçünün de bir kaynağı vardır — ilk ikisi ölçümden, üçüncüsü yük bildiriminden gelir.

Bilginin maliyeti üçüncü kalemde en açıktır. Kopya oranı bir ölçüm değil, bir tahmindir: iki sürecin gelecekteki yükü aynı yönde mi büyüyecek? Bu tahmin yazılmazsa sistem yine de paketlemek zorundadır ve modelin son satırı ne olduğunu söyler: üç çiftin birinde yanlış paketleme, dört gereksiz süreç örneği. Yanlışın kaynağı bir hata değil, bir boşluktur; kopya oranını bilmeyen bir kural, ucuz görünen seçeneği alır ve toplayıcı ile dönüştürücüyü aynı kapsüle koyar.

Birinci çiftin kararı ise bilgiyle bile çözülmüyor: iki ölçüt ters yönü gösterdiği için sonuç catisma çıkıyor. Ortak dosya ve sık alışveriş birlikteliği söylerken, üç kat kopya oranı ayrılığı söylüyor. Bu, devretmenin kazandırmadığı bir durumdur: sistem kuralı uygular, kural bir yanıt üretmez ve karar insana geri döner. Yanıt ancak girdilerden biri değiştirilirse çıkar — ya dört fazla süreç örneği kabul edilir, ya ortak dosya bir aktarıma çevrilip iki yüz kırk tur ödenir. Kararı devretmek, kararın dayandığı büyüklüklerden birini değiştirmeyi zorunlu kılar.

Özet

  • Kapsül, kümeye bildirilebilen en küçük dağıtım birimidir ve üç şeyi bir arada tutar: aynı ağ adı, aynı yerel dosya alanı, aynı yaşam süresi. Ayırmak bu üçünü üç ayrı bildirim kalemine çevirir.
  • Altı ve iki kopya isteyen iki süreç tek kapsülde paketlenirse ölçek birimi bire iner ve dört gereksiz süreç örneği doğar; ayrılırsa bu dört örnek yok olur, iki yüz kırk ağ turu eklenir.
  • Kopya oranı eşit olan çiftte ayırmanın kazancı sıfır, bedeli sekiz yüz turdur; eşit ölçekli ve seyrek konuşan çiftte ise yirmi dört tur karşılığında arıza yayılımı ikiden bire iner.
  • Kaynak muhasebesi kapsül düzeyindedir: tek kapsülde altı kalem tutulur, süreç başına hesap sıfırdır ve neyin büyüdüğü bildirimde görünmez.
  • Aynı arıza dizisinde tek kapsül on üç, iki kapsül on düşüş üretti; farkın tamamı komşu arızasıdır ve dönüştürücü eksik kopyayla dört tur yerine yedi tur çalıştı.
  • Devredilen karar üç bilgi kalemine dayanır; kopya oranı eksildiğinde üç çiftin birinde yanlış paketleme ve dört gereksiz süreç örneği doğar, ölçütler çakıştığında ise kural yanıt üretmez.

Sonraki Adım

Bu ders tek bir kapsülün sınırını çizdi ve kaç kopya gerektiğini bir varsayım olarak aldı: altı, dört, üç. Oysa o sayı da kümeye bildirilen bir şeydir ve bildirildiği anda yeni bir soru doğar — gerçek kopya sayısı istenenden saptığında kim, ne kadar sürede, hangi sırayla düzeltir. Dahası istenen kopya sayısı sabit kalırken kopyanın içeriği değişebilir; yeni bir sürüme geçmek, aynı anda kaç fazla ve kaç eksik kopyaya izin verildiğini bildirmeyi gerektirir. Sonraki ders bu iki nesneyi node ile yazar ve geçişi tur tur sayar: kaç turda tamamlandığı, kaç turunda kapasitenin altına düşüldüğü ve geri almanın kaç tur sürdüğü.

İ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