Ders 17 / 21
Çekme Tabanlı Dağıtım
Depodaki istenen durumu kümeye taşıyan iki düzen — hattın kümeye yazması ve küme içindeki ajanın depoyu okuması — aynı kalemlerde sayılır: yetki yüzeyi, bağlantı yönü, elle yapılan sapmanın fark edilme gecikmesi ve hat düştüğünde ne olduğu. Uzlaştırma turunun marjinal değeri 17 sapma, yanlış geri aldığı doğru müdahale 9 çıkar.
İçindekiler
Bir önceki ders istenen durumun depoda durmasının ne kazandırdığını saydı: kayıtsız değişiklik 63’ten 5’e, dönem sonunda sapan kalem 45’ten 1’e indi. O ölçümde sessiz kalan bir kalem vardı — depodaki yazıyı kümeye kim taşıyor. Şimdiye kadarki bütün düzeneklerde taşıyan taraf hattır: hat kümenin denetim düzlemine bağlanır, kimlik bilgisiyle kendini tanıtır ve nesneleri yazar. Buna itme denir.
İkinci bir yol vardır: kümenin içinde çalışan bir uzlaştırıcı ajan depoyu okur, kendi ortamının gerçek durumuyla karşılaştırır ve farkı kendisi kapatır. Buna çekme denir. Uzlaşma döngüsünün mekaniği küme mimarisi konusunda ölçülmüştü — periyot, gecikmeli görüntü, salınım — ve burada tekrarlanmaz. Bu dersin ölçtüğü tek şey kaynağın depo olmasının bu iki taşıma yönünde ne değiştirdiğidir.
Ölçüm yine bölgesel ölçüm ağı üzerindedir ve kurgudur; koşan şey node ile kurulmuş bir
modeldir.
DD7. Model 4 servis × 3 ortam = 12 ad alanı, 6 nesne türü, 72 nesne örneği ve 4 işlem taşır. DD8. İtmede tek özne — hat çalıştırıcısı — 12 ad alanının hepsinde yetkilidir. Çekmede her ortamda bir ajan vardır ve yalnız kendi ortamının 4 ad alanında yetkilidir. DD9. Otuz günde 60 elle değişiklik olur; üreteç kendi yazılmıştır, tohum 31337. Üç sınıf: dağıtımın her koşumda yazdığı alan, dağıtımın hiç yazmadığı alan, ajanın sahiplenmediği nesne. DD10. Elle değişikliklerin bir bölümü gerçek bir kesintiyi kapatan doğru müdahaledir; bir bölümü kısa ömürlüdür — operatör dakikalar içinde kendisi geri alır. DD11. Dağıtım takvimi yazılıdır: dört servis sırayla 720, 480, 2880 ve 4320 dakikada bir dağıtır. DD12. On ikinci günde 24 saatlik bir hat kesintisi olur; o pencerede dağıtım koşmaz, ajan koşar.
Yetki Yüzeyi ve Bağlantının Yönü
// yetki.mjs — itme ve cekme duzenlerinde yetki yuzeyi sayimi. Rastgelelik yok; sayim // bir modelin nesne agaci uzerinde yapilir, gercek bir kume degil. const SERVIS = ["toplayici", "dogrulayici", "faturalama", "isemri"]; const ORTAM = ["gelistirme", "hazirlik", "uretim"]; const NESNE = ["dagitim", "hizmet", "yapilandirma", "sir-basvurusu", "zamanli-is", "ag-kurali"]; const YAZMA = ["yaz", "sil", "yama"], ISLEM = ["oku", ...YAZMA]; const adAlani = ORTAM.flatMap((o) => SERVIS.map((s) => `${o}/${s}`)); const ornek = adAlani.flatMap((a) => NESNE.map((n) => `${a}/${n}`)); // nesne ornekleri const duzen = { itme: { // hat kumeye yazar ozne: "hat calistiricisi", kapsam: adAlani, disaAcik: ORTAM.length, // her ortamin denetim duzlemi disaridan erisilir hatElinde: ORTAM.length, // hattin tuttugu kume kimligi sayisi baglantiYonu: "hat -> kume (disaridan iceriye)", }, cekme: { // ajan depoyu okur ozne: "ortam basina bir ajan", kapsam: adAlani.filter((a) => a.startsWith("uretim/")), disaAcik: 0, hatElinde: 0, baglantiYonu: "kume -> depo (iceriden disariya)", }, }; const say = (k) => ({ yetkiKaydi: k.length * NESNE.length * ISLEM.length, yazmaKaydi: k.length * NESNE.length * YAZMA.length, yazilabilirOrnek: ornek.filter((o) => k.some((a) => o.startsWith(a + "/"))).length }); console.log(`model: ${SERVIS.length} servis x ${ORTAM.length} ortam = ${adAlani.length} ad alani, ` + `${NESNE.length} nesne turu, ${ornek.length} nesne ornegi, ${ISLEM.length} islem`); console.log("\n" + "duzen".padEnd(7) + "ozne".padEnd(23) + "ad alani".padStart(8) + "yetki".padStart(7) + "yazma".padStart(7) + "ele gecerse yazilabilir".padStart(24)); for (const [ad, d] of Object.entries(duzen)) { const s = say(d.kapsam); console.log(ad.padEnd(7) + d.ozne.padEnd(23) + String(d.kapsam.length).padStart(8) + String(s.yetkiKaydi).padStart(7) + String(s.yazmaKaydi).padStart(7) + String(s.yazilabilirOrnek).padStart(24)); } console.log("\n" + "duzen".padEnd(7) + "disa acik denetim duzlemi".padStart(25) + "hattin elindeki kume kimligi".padStart(29) + " baglanti yonu"); for (const [ad, d] of Object.entries(duzen)) console.log(ad.padEnd(7) + String(d.disaAcik).padStart(25) + String(d.hatElinde).padStart(29) + " " + d.baglantiYonu);
model: 4 servis x 3 ortam = 12 ad alani, 6 nesne turu, 72 nesne ornegi, 4 islem duzen ozne ad alani yetki yazma ele gecerse yazilabilir itme hat calistiricisi 12 288 216 72 cekme ortam basina bir ajan 4 96 72 24 duzen disa acik denetim duzlemi hattin elindeki kume kimligi baglanti yonu itme 3 3 hat -> kume (disaridan iceriye) cekme 0 0 kume -> depo (iceriden disariya)
Tablonun ilk okunuşu yanıltıcıdır. Çekme düzeninde ajan başına 96 yetki kaydı görünüyor, itmede 288; ama ortam başına bir ajan olduğu için toplam yetki kaydı çekmede de 3 × 96 = 288‘dir. Yetki yüzeyi küçülmüyor, bölünüyor. Değişen sayı son sütundur: ele geçen bir hat çalıştırıcısı 72 nesne örneğinin hepsine yazabilir, ele geçen bir ajan yalnız kendi ortamının 24’üne. Üç ortamın üretim olanı ayrı bir öznenin arkasındadır ve geliştirme ortamındaki bir sorun oraya erişemez.
İkinci tablo daha keskin bir farkı gösteriyor. İtmede üç denetim düzlemi dışarıdan erişilebilir olmalıdır ve hat üç küme kimliğini elinde tutar; çekmede ikisi de sıfırdır, çünkü bağlantıyı küme kurar. Bunun işletim karşılığı somuttur: itmede hattın koştuğu yer güvenlik sınırının içindeymiş gibi davranmak zorundadır — hat çalıştırıcısı üç üretim ortamına yazabilen bir öznedir. Çekmede hattın tek yetkisi depoya yazmaktır; kümeler onu tanımaz bile.
Bu bir kapı sayımı değildir, ama kapıların üzerinde durduğu zemini belirler: itmede depo tabanlı istenen durum ilkesi bir sözleşmedir — hat isterse kapıları atlayıp doğrudan yazabilir. Çekmede ilke bir kısıttır: kümenin dışından yazacak yetki yoktur.
Sapmayı Kim, Ne Zaman Kapatıyor
// sapma.mjs — 30 gunluk elle degisiklik akisi iki duzende sayilir: itme (hat kumeye yazar) // ve cekme (ajan depoyu okur). Model kosturulur; uretec kendi yazildi, tohum gorunur. const uretec = (t) => { let s = t >>> 0; // ayni dogrusal eslesmeli uretec return () => (s = (s * 1664525 + 1013904223) >>> 0) / 4294967296; }; const SURE = 30 * 1440, KESINTI = [17820, 19260]; // 12. gun, 24 saatlik hat kesintisi const TAKVIM = { toplayici: 720, dogrulayici: 480, faturalama: 2880, isemri: 4320 }; const SERVIS = Object.keys(TAKVIM); function olaylar(tohum = 31337, adet = 60) { const r = uretec(tohum), l = []; for (let i = 0; i < adet; i++) { const p = r(); l.push({ t: Math.floor(r() * SURE), servis: SERVIS[Math.floor(r() * 4)], sinif: p < 0.45 ? "yazilan" : p < 0.85 ? "yazilmayan" : "kapsamdisi", dogru: r() < 0.2, // gercek kesintiyi kapatan duzeltme omur: r() < 0.25 ? 5 + Math.floor(r() * 25) : Infinity });// operatorun kendi geri aldigi } return l; } const sonrakiDagitim = (servis, t) => { // kesinti penceresi atlanir const p = TAKVIM[servis]; for (let k = Math.floor(t / p) + 1; k * p <= SURE; k++) if (!(k * p >= KESINTI[0] && k * p < KESINTI[1])) return k * p; return null; }; function kos(l, U) { // U=null ise itme duzeni const s = { kapanan: 0, marjinal: 0, gecikme: 0, gorulmeyen: 0, kacan: 0, yanlis: 0, kalan: 0, pencereAcik: 0, pencereKapanan: 0 }; for (const o of l) { const kapanis = U === null ? (o.sinif === "yazilan" ? sonrakiDagitim(o.servis, o.t) : null) : (o.sinif === "kapsamdisi" ? null : (Math.floor(o.t / U) + 1) * U); if (o.omur !== Infinity && (kapanis === null || o.t + o.omur < kapanis)) { s.gorulmeyen++; continue; } const bitis = (kapanis === null || kapanis > SURE) ? SURE : kapanis; if (o.t < KESINTI[1] && bitis > KESINTI[0]) s.pencereAcik++; // kesinti boyunca acik sapma if (kapanis !== null && kapanis >= KESINTI[0] && kapanis < KESINTI[1]) s.pencereKapanan++; if (kapanis === null || kapanis > SURE) { s.kalan++; if (o.sinif === "kapsamdisi") s.kacan++; continue; } s.kapanan++; s.gecikme += kapanis - o.t; if (o.sinif === "yazilmayan") s.marjinal++; // itmenin hic kapatamayacagi sinif if (o.dogru) s.yanlis++; // dogru mudahale geri alindi/ezildi } s.ortGecikme = s.kapanan ? s.gecikme / s.kapanan : 0; s.yayilma = U === null ? 3 : U / 2 + 1; // isleme -> uygulama gecikmesi return s; } const G = [12, 9, 10, 13, 12, 9, 9, 8, 10]; const yaz = (h) => h.map((v, j) => j ? String(v).padStart(G[j]) : String(v).padEnd(G[0])).join(""); const l = olaylar(); console.log(`tohum 31337 | ${l.length} elle degisiklik / 30 gun | ` + `${l.filter((o) => o.dogru).length} tanesi gercek bir kesintiyi kapatan dogru duzeltme`); console.log(`sinif: yazilan ${l.filter((o) => o.sinif === "yazilan").length}, ` + `yazilmayan ${l.filter((o) => o.sinif === "yazilmayan").length}, ` + `kapsam disi ${l.filter((o) => o.sinif === "kapsamdisi").length}`); console.log("\n" + yaz(["duzen", "kapanan", "marjinal", "ort gecikme", "gorulmeyen", "kacan", "yanlis", "kalan", "yayilma"])); console.log(yaz(["itme", ...(({ kapanan, marjinal, ortGecikme, gorulmeyen, kacan, yanlis, kalan, yayilma }) => [kapanan, marjinal, ortGecikme.toFixed(0), gorulmeyen, kacan, yanlis, kalan, yayilma])(kos(l, null))])); for (const U of [1, 5, 15, 60, 240]) { const x = kos(l, U); console.log(yaz([`cekme U=${U}`, x.kapanan, x.marjinal, x.ortGecikme.toFixed(0), x.gorulmeyen, x.kacan, x.yanlis, x.kalan, x.yayilma.toFixed(1)])); } const kacanDagitim = SERVIS.reduce((a, sv) => a + Object.keys([...Array(SURE / TAKVIM[sv] | 0)]) .filter((k) => (+k + 1) * TAKVIM[sv] >= KESINTI[0] && (+k + 1) * TAKVIM[sv] < KESINTI[1]).length, 0); const i = kos(l, null), c = kos(l, 15); console.log(`\n24 saatlik hat kesintisi: ${kacanDagitim} planli dagitim kacti, ` + `ajan ${(KESINTI[1] - KESINTI[0]) / 15} tur kostu`); console.log(`pencere boyunca acik sapma — itme ${i.pencereAcik}, cekme(U=15) ${c.pencereAcik}; ` + `pencerede kapanan — itme ${i.pencereKapanan}, cekme ${c.pencereKapanan}`);
tohum 31337 | 60 elle degisiklik / 30 gun | 10 tanesi gercek bir kesintiyi kapatan dogru duzeltme sinif: yazilan 32, yazilmayan 17, kapsam disi 11 duzen kapanan marjinal ort gecikme gorulmeyen kacan yanlis kalan yayilma itme 26 0 1206 16 6 4 18 3 cekme U=1 49 17 1 5 6 9 6 1.5 cekme U=5 49 17 3 5 6 9 6 3.5 cekme U=15 48 17 8 6 6 9 6 8.5 cekme U=60 42 14 30 12 6 8 6 31.0 cekme U=240 39 12 135 15 6 7 6 121.0 24 saatlik hat kesintisi: 5 planli dagitim kacti, ajan 96 tur kostu pencere boyunca acik sapma — itme 11, cekme(U=15) 7; pencerede kapanan — itme 0, cekme 3
İtme satırı bir kapı gibi görünmez, çünkü değildir. Altmış elle değişikliğin 26’sı kapandı, ama kapanma bir fark etme değil bir üstüne yazmadır: bir sonraki dağıtım o alanı yeniden yazdığı için sapma silinir. Ortalama süre 1206 dakikadır — yirmi saat — ve bu sürenin tamamı dağıtım takvimine bağlıdır. Kimse sapmayı fark etmedi, kimse bir kayıt tutmadı; dönem sonunda 18 kalem sapmış durumda kaldı.
Uzlaştırma turunun kapı defteri bunun karşısında durur. Onbeş dakikalık periyotta 48 sapma kapandı, ortalama gecikme 8 dakika. Marjinal sütun bu kapının yalnız kendisinin yaptığı işi verir: dağıtımın hiç yazmadığı alanlardaki 17 sapma. Bunlar itme düzeninde otuz gün boyunca hiç kapanmayacak kalemlerdir — elle eklenmiş bir ağ kuralı, elle büyütülmüş bir kopya sayısı, elle kapatılmış bir zamanlı iş. Kapının değeri 48’de değil, 17’dedir.
Kaçırdığı da nettir: ajanın sahiplenmediği nesne türlerindeki 6 sapma bütün periyotlarda kaçtı ve
periyodu küçültmek bunu değiştirmedi. Kapsam bir ayar değil bir tanımdır; ajan neyi yönetmiyorsa
onu göremez. İkinci kaçırma sınıfı gorulmeyen sütunudur: iki tur arasında yapılıp operatörün
kendisi tarafından geri alınan değişiklikler. U=1’de 5, U=240’ta 15 tanesi hiç görülmedi. Uzun
periyotlu bir ajan yalnız yavaş değildir; kısa ömürlü müdahalelerin hiçbir kaydını tutmaz.
Uzlaştırma Turunun Yanlış Tuttuğu
yanlis sütunu bu kapının bedelidir. Otuz günde 10 elle değişiklik gerçek bir kesintiyi kapatan
doğru müdahaledir. Çekme düzeninde bunların 9’u ortalama 8 dakika içinde geri alındı — ajan
depodaki yazıya bakar, müdahalenin niye yapıldığını bilmez ve kesintiyi geri getirir. İtmede aynı
sayı 4’tür ve geri alma ortalama yirmi saat sonra, sessizce olur.
İkisi de yanlış tutmadır, ama biçimleri farklıdır ve karışıklık burada başlar. Çekmede yanlış tutma hızlı ve görünürdür: ajan bir kayıt bırakır, müdahaleyi yapan kişi sekiz dakika içinde geri alındığını görür ve doğru davranışı öğrenir — düzeltmeyi depoya işlemek. İtmede yanlış tutma yavaş ve sessizdir: müdahale yirmi saat çalışır, sonra bir dağıtım onu ezer ve kimse ilişkiyi kurmaz. Kapının sayısı çekmede iki kattır; kapının verdiği zarar itmede daha büyüktür, çünkü öğretmez.
Bu kapının doğru ayarı periyodu uzatmak değildir. U=240 satırında yanlış geri alma 9’dan 7’ye iner, ama marjinal değer de 17’den 12’ye düşer ve görülmeyen sapma 15’e çıkar. Kapının doğru ayarı kapsamdır: acil müdahalenin yapılacağı alanlar ajanın sahiplenmediği kümeye alınırsa hem yanlış geri alma hem de öğrenme kaybolur. Ölçüm bu takasın fiyatını verir — o alanlardaki sapmalar da artık kimsenin kapatmadığı 6 kalemin yanına eklenir.
Hat Düştüğünde ve Çekmenin Bedeli
Yirmi dört saatlik hat kesintisi iki düzenin dayanıklılığını ayırır. O pencerede 5 planlı dağıtım kaçtı; itme düzeninde pencere boyunca açık kalan 11 sapmanın hiçbiri kapanmadı, çünkü kapatan mekanizma dağıtımın kendisiydi. Ajan aynı pencerede 96 tur koştu ve açık 7 sapmanın 3’ünü kapattı. Ayrım şudur: itmede hat hem yeni değişikliği taşır hem sapmayı kapatır, dolayısıyla hattın kesintisi ikisini birden durdurur. Çekmede hat yalnız yeni değişikliği taşır; son bilinen durumu korumak hattan bağımsızdır. Yeni yayın iki düzende de durur — bu bir üstünlük değil, işlerin ayrılmasıdır.
Çekmenin faturası son sütundadır. İtmede bir işlemenin uygulanmaya dönüşmesi 3 dakika sürer; çekmede periyodun yarısı artı uygulama, yani U=15’te 8,5 ve U=240’ta 121 dakika. Uzlaştırma turunun marjinal değerini yüksek tutmak için periyodu kısaltmak gerekir, ama kısa periyot yayılmayı iyileştirirken depoya ve denetim düzlemine sabit bir okuma yükü bindirir. İkinci kalem ajanın kendisidir: ortam başına bir ajan, üç ayrı sürüm yükseltme penceresi, üç ayrı yetki kaydı kümesi ve ajanın kendisi düştüğünde bunu fark edecek ayrı bir gözlem. Depo tabanlı istenen durum ilkesi ajanla birlikte gelmez; ajan ilkenin uygulanma biçimlerinden yalnız biridir ve kendi bakımını ister.
Özet
- Toplam yetki kaydı iki düzende de 288’dir; çekmede yetki üç özneye bölünür ve ele geçen bir öznenin yazabildiği nesne örneği 72’den 24’e iner. Dışa açık denetim düzlemi 3’ten 0’a düşer.
- İtmede sapma fark edilmez, üstüne yazılır: 60 elle değişikliğin 26’sı ortalama 1206 dakika sonra silindi, 18’i dönem sonunda hâlâ duruyordu.
- Uzlaştırma turunun marjinal değeri 17 sapmadır — dağıtımın hiç yazmadığı alanlar. Kapının değeri kapattığı 48’de değil, itmenin asla kapatamayacağı 17’dedir.
- Kapı iki sınıfı kaçırır: ajanın sahiplenmediği 6 nesne (periyottan bağımsız) ve iki tur arasında yapılıp geri alınan değişiklikler (U=1’de 5, U=240’ta 15).
- Doğru bir acil müdahaleyi çekme 9 kez ortalama 8 dakikada geri aldı, itme 4 kez yirmi saat sonra sessizce ezdi; çekmenin yanlış tutması daha sık, itmeninki daha zararlıdır çünkü öğretmez.
- 24 saatlik hat kesintisinde itme 11 açık sapmanın 0’ını, ajan 7 açık sapmanın 3’ünü kapattı; bedeli yayılma gecikmesinin 3 dakikadan 8,5 dakikaya çıkması ve ortam başına bir ajanın bakımıdır.
Sonraki Adım
İki ders istenen durumun depoda durmasını ve oradan kümeye taşınmasını ölçtü. Kalan bir kalem vardır ve depoya girmesi baştan sorunludur: servislerin ihtiyaç duyduğu sırlar. Veritabanı bağlantısı, ölçüm ağının uzak uçlarına giden kimlik bilgileri ve imzalama anahtarları depoda düz metin olarak duramaz — ama depoda durmazlarsa istenen durum eksik kalır ve ajan uygulayamaz. Sonraki ders şifreli sır kaydını ölçer: anahtar nerede duruyor, kaç özne çözebiliyor, anahtar döndürüldüğünde kaç kayıt yeniden şifreleniyor ve kaç dosyaya dokunuyor, geçmişte kalan şifreli değerler ne kadar süre okunabilir kalıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.