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.