İçeriğe geç
academia.sh

Ders 26 / 27

Sunucu İmajı Üretimi

Her açılışta yapılandırma ile önceden pişmiş imaj yan yana ölçülür: açılış süresi, açılışta dışarıya yapılan çağrı sayısı ve bir bağımlılık düştüğünde kaç makinenin açıldığı sayılır; bir güvenlik düzeltmesi geldiğinde kaç imajın yeniden piştiği, yayılma penceresinin kaç gün olduğu ve imajın içerik kaydının kaç bileşeni kaçırdığı ölçülür.

İçindekiler

Önceki ders kaydı çalışan bir makineye taşımanın iki yolunu ölçtü. İkisi de aynı sıralamayı varsaydı: makine önce boş açılır, sonra yapılandırılır. Yayılma süresi de kısmi başarısızlık da bu sıralamadan geldi — makine iş almaya başlamıştı ve kayda henüz uymuyordu.

Sıralama tersine çevrilebilir: ayarlar makineye açılıştan sonra taşınmak yerine, makinenin açıldığı imajın içine önceden konabilir. Bu ders üç yolu tür olarak yan yana koyar — her açılışta yapılandır, önceden pişmiş imaj ve karma (pişmiş taban artı açılışta uygulanan küçük ayar). M22/K02 temel imajın baytını ve güncelleme yükünü ölçmüştü; o ölçüm tekrarlanmaz. Burada ölçülen imajın boyutu değil, imaj üretim akışıdır.

AD31. Filo, bölgesel ölçüm ağının — su sayaçlarından okuma toplayan kurgu yazılımın — 6 rolde ve 3 ortamda koşan 50 makinesidir. AD32. Üç yolun açılış adımları ve saniyeleri kurgudur; her adımın hangi bağımlılığa kaç çağrı yaptığı yazılıdır. AD33. Bağımlılıkların açılış anında ayakta olma olasılıkları 0,995 ile 0,999 arasındadır ve ani talep artışında aynı anda 40 makine açılır. AD34. Sayılar kendi üretecimizden gelir; tohumlar 2026081120260814 görünürdür ve büyüklük mertebesidir. AD35. Bir imaj 7–19 dakikada pişer, üstüne 6 dakika sınama biner; imaj üretici aynı anda 3 imaj pişirir, filo günde 12 makine değiştirir. AD36. İmajın içerik kaydı yalnız doğrudan bileşenleri yazar, dolaylı gelenleri yazmaz; tam yeniden pişirme döngüsü 30 gündür.

Açılışta Ne Oluyor

Üç yol aynı servisi açar. Her açılışta yapılandıran yol paketleri açılış anında indirir ve kurar; pişmiş imaj yolu bunları imajın içinde hazır bulur; karma yol imajı hazır bulur ama ortama göre değişen ayarı açılışta çeker.

// olcum-agi/acilis.mjs — ayni servisin uc acilis yolu (model; urun degil tur)
export const uretec = (tohum) => () =>
  (tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648;

// Dis bagimlilik turleri ve her birinin acilis aninda ayakta olma olasiligi (kurgu).
export const AYAKTA = {
  "ad cozumleyici": 0.999, "paket deposu": 0.995, "yapilandirma sunucusu": 0.995,
  "sir deposu": 0.998, "imaj deposu": 0.997,
};

// Adim: [ad, saniye, bagimlilik ya da null, o adimda yapilan cagri sayisi].
export const YOL = {
  "her acilista": [
    ["cekirdek acilisi", 12, null, 0], ["ad cozumleme", 2, "ad cozumleyici", 1],
    ["paket listesi", 9, "paket deposu", 1], ["14 paket kurulumu", 128, "paket deposu", 14],
    ["yapilandirma cekme", 11, "yapilandirma sunucusu", 1], ["sir cekme", 6, "sir deposu", 1],
    ["servis baslatma", 8, null, 0],
  ],
  "pismis imaj": [
    ["imaj cekme", 19, "imaj deposu", 1], ["cekirdek acilisi", 12, null, 0],
    ["sir cekme", 6, "sir deposu", 1], ["servis baslatma", 8, null, 0],
  ],
  "karma": [
    ["imaj cekme", 19, "imaj deposu", 1], ["cekirdek acilisi", 12, null, 0],
    ["ortam ayari cekme", 7, "yapilandirma sunucusu", 1], ["sir cekme", 6, "sir deposu", 1],
    ["servis baslatma", 8, null, 0],
  ],
};

export const olc = (ad) => {
  const adim = YOL[ad];
  const cagri = adim.reduce((t, [, , , c]) => t + c, 0);
  const basari = adim.reduce((t, [, , b, c]) => t * (b ? AYAKTA[b] ** c : 1), 1);
  const bagli = [...new Set(adim.filter(([, , b]) => b).map(([, , b]) => b))];
  return { ad, sure: adim.reduce((t, [, s]) => t + s, 0), cagri, basari, bagli };
};

if (import.meta.url === `file://${process.argv[1]}`) {
  const YENI = 40;   // ani talep artisinda ayni anda acilan makine (kurgu)
  console.log("yol".padEnd(14) + "acilis".padEnd(9) + "dis cagri".padEnd(11) +
    "bagimlilik".padEnd(12) + "acilis basarisi".padEnd(17) + `${YENI} makinede acilmayan`);
  for (const ad of Object.keys(YOL)) {
    const o = olc(ad);
    console.log(o.ad.padEnd(14) + `${o.sure} sn`.padEnd(9) + String(o.cagri).padEnd(11) +
      `${o.bagli.length} tur`.padEnd(12) + `%${(100 * o.basari).toFixed(1)}`.padEnd(17) +
      (YENI * (1 - o.basari)).toFixed(1));
  }
  console.log("\nbir bagimlilik dustugunde acilan makine (40 makinede):");
  const sut = Object.keys(YOL);
  console.log("dusen".padEnd(24) + sut.map((a) => a.padEnd(14)).join("").trimEnd());
  for (const b of Object.keys(AYAKTA))
    console.log((b.padEnd(24) + sut.map((ad) =>
      (olc(ad).bagli.includes(b) ? "0/40" : "40/40").padEnd(14)).join("")).trimEnd());
}
yol           acilis   dis cagri  bagimlilik  acilis basarisi  40 makinede acilmayan
her acilista  176 sn   18         4 tur       %92.0            3.2
pismis imaj   45 sn    2          2 tur       %99.5            0.2
karma         52 sn    3          3 tur       %99.0            0.4

bir bagimlilik dustugunde acilan makine (40 makinede):
dusen                   her acilista  pismis imaj   karma
ad cozumleyici          0/40          40/40         40/40
paket deposu            0/40          40/40         40/40
yapilandirma sunucusu   0/40          40/40         0/40
sir deposu              0/40          0/40          0/40
imaj deposu             40/40         0/40          0/40

Açılış süresi 176 saniyeden 45 saniyeye iner — yaklaşık dört kat. Ama asıl fark ikinci sütundadır: 18 dış çağrı 2’ye düşer. Bu, süreden bağımsız bir niceliktir; her çağrı ayrı bir başarısızlık noktasıdır ve talep artışında hepsi aynı anda yapılır. Kırk makinelik bir açılışta beklenen açılmayan makine sayısı 3,2’den 0,2’ye iner; pişmiş imaj yolu açılışı hızlandırmaktan çok açılışı bağımsızlaştırır.

Alt tablo bunun sınırını yazar. Sır deposu satırında üç yol da sıfırdır: hassas değer imaja pişirilemez — pişirilirse imajı okuyabilen herkes sırrı da okur. Pişmiş yol on sekiz çağrının on altısını kaldırır, on yedincisini kaldıramaz. İmaj deposu satırı takasın öteki yüzüdür: pişmiş yol dört bağımlılığı ikiye indirirken yeni bir bağımlılık edinir. Her açılışta yapılandıran yolun tek üstünlüğü budur; imaj deposu düşse de açılmaya devam eder.

Kayıt ile gerçek arasındaki fark burada da vardır. Her açılışta yapılandıran yolda kayıt “şu paketler kurulacak” der; gerçekte kurulan, paket deposunun o gün sunduğudur ve iki farklı gün açılan iki makine aynı içeriği almaz. Pişmiş yolda kayıt bir kez gerçeğe çevrilir ve imaja donar.

Düzeltme Geldiğinde Kaç İmaj Pişiyor

Donmuş içeriğin bedeli, içeriği değiştirmenin artık bir üretim adımı gerektirmesidir. Güvenlik düzeltmesi geldiğinde her açılışta yapılandıran yol hiçbir şey pişirmez; pişmiş yol etkilenen bütün imajları yeniden pişirir. Kaç imajın piştiği, ortamın nereye yazıldığına bağlıdır.

// olcum-agi/pisirme.mjs — bir guvenlik duzeltmesi geldiginde kac imaj yeniden pisiyor (model)
import { uretec } from "./acilis.mjs";

export const ROL = 6, ORTAM = 3;    // olcum aginin alti rolu, uc ortami (kurgu)
const KOL = 3, SINAMA = 6;          // es zamanli pisirme kolu; imaj basina sinama (dk)
const MAKINE = 50, DEGISIM = 12;    // filo ve gunluk makine degistirme kapasitesi

// Saf pismis yolda her rol her ortam icin ayri pisirilir; karma yolda ortam ayari
// acilista uygulandigi icin rol basina tek imaj yeter.
export const IMAJ = { "her acilista": 0, "pismis imaj": ROL * ORTAM, "karma": ROL };

// Duzeltme, bileseni tasiyan rollere dokunur; taban bileseni butun rollerdedir.
const duzeltmeler = (tohum = 20260811) => {
  const r = uretec(tohum);
  return ["cekirdek kutuphane", "sifreleme kutuphanesi", "ad cozumleyici eklentisi",
    "kabuk", "sikistirma kutuphanesi"].map((ad) =>
      ({ ad, rol: r() < 0.4 ? ROL : 1 + Math.floor(r() * (ROL - 1)) }));
};

// Pencere = pisirme duvar saati + filonun yenilenmesi (gunde DEGISIM makine).
export const pencere = (n, tohum = 20260812) => {
  const r = uretec(tohum);
  const tek = Array.from({ length: n }, () => 7 + Math.round(r() * 12) + SINAMA);
  let duvar = 0;
  for (let i = 0; i < n; i += KOL) duvar += Math.max(...tek.slice(i, i + KOL));
  return { duvar, toplam: tek.reduce((t, v) => t + v, 0), tur: Math.ceil(n / KOL),
    gun: duvar / 1440 + MAKINE / DEGISIM };
};

if (import.meta.url === `file://${process.argv[1]}`) {
  console.log(`${ROL} rol, ${ORTAM} ortam, ${MAKINE} makine; ` +
    `imaj sayisi: saf ${IMAJ["pismis imaj"]}, karma ${IMAJ["karma"]}\n`);
  console.log("duzeltme".padEnd(26) + "dokundugu rol".padEnd(15) +
    "saf pismis".padEnd(12) + "karma".padEnd(8) + "her acilista");
  let saf = 0, kar = 0;
  for (const f of duzeltmeler()) {
    saf += f.rol * ORTAM; kar += f.rol;
    console.log(f.ad.padEnd(26) + `${f.rol}/${ROL}`.padEnd(15) +
      `${f.rol * ORTAM} imaj`.padEnd(12) + `${f.rol} imaj`.padEnd(8) + "0 imaj");
  }
  console.log("toplam".padEnd(41) + `${saf} imaj`.padEnd(12) + `${kar} imaj`.padEnd(8) + "0 imaj");

  console.log("\nen genis duzeltme (butun roller) icin yayilma penceresi:");
  console.log("yol".padEnd(14) + "pisen imaj".padEnd(12) + "tur".padEnd(6) +
    "duvar saati".padEnd(13) + "pisirici dakika".padEnd(17) + "pencere");
  for (const [ad, n] of Object.entries(IMAJ)) {
    const p = pencere(n);
    console.log(ad.padEnd(14) + String(n).padEnd(12) + String(p.tur).padEnd(6) +
      `${(p.duvar / 60).toFixed(1)} sa`.padEnd(13) + String(p.toplam).padEnd(17) +
      `${p.gun.toFixed(2)} gun`);
  }
}
6 rol, 3 ortam, 50 makine; imaj sayisi: saf 18, karma 6

duzeltme                  dokundugu rol  saf pismis  karma   her acilista
cekirdek kutuphane        6/6            18 imaj     6 imaj  0 imaj
sifreleme kutuphanesi     3/6            9 imaj      3 imaj  0 imaj
ad cozumleyici eklentisi  4/6            12 imaj     4 imaj  0 imaj
kabuk                     6/6            18 imaj     6 imaj  0 imaj
sikistirma kutuphanesi    6/6            18 imaj     6 imaj  0 imaj
toplam                                   75 imaj     25 imaj 0 imaj

en genis duzeltme (butun roller) icin yayilma penceresi:
yol           pisen imaj  tur   duvar saati  pisirici dakika  pencere
her acilista  0           0     0.0 sa       0                4.17 gun
pismis imaj   18          6     2.1 sa       334              4.26 gun
karma         6           2     0.7 sa       117              4.20 gun

İlk tablo ortamın nereye yazıldığının bedelini gösterir. Ortam imaja pişirilirse her rol üç kez pişer: beş düzeltme 75 imaj pişirmesi üretir. Ortam açılışta uygulanırsa aynı beş düzeltme 25 pişirme ister. Aradaki üç kat, karma yolun açılışta ödediği tek ek çağrının karşılığıdır.

İkinci tablo yaygın bir beklentiyi düzeltir. Önceden pişmiş imajın tazeliği geciktirdiği düşünülür; sayılınca gecikme 0,09 gündür — 4,26 güne karşı 4,17 gün. Pişirme duvar saati 2,1 saattir ve pencerenin yüzde ikisinden azını tutar. Pencereyi belirleyen pişirme değil, filonun yenilenmesi: 50 makine günde 12 değiştirilebildiği için düzeltme dört günden önce her makineye ulaşamaz ve bu, üç yolun ortak bedelidir. Değişmez altyapı disiplini makineyi yerinde yamamak yerine değiştirmeyi gerektirir; pencere o kuralın fiyatıdır.

Pişirici dakika sütunu yinelenen bedeldir: aynı düzeltme saf pişmiş yolda 334, karma yolda 117 pişirici dakikası harcar. İmaj üretici de bakılması gereken bir altyapı parçasıdır; kapasitesi düşerse pencere doğrudan uzar.

İmajın İçinde Ne Var

Yeniden pişecek imajlara bir kayıt karar verir: imajın içerik kaydı, hangi imajın hangi bileşeni taşıdığını yazar. Bu kayıt eksikse yeniden pişirme kümesi de eksik olur ve eksikliği kimse görmez, çünkü pişirme başarıyla biter.

// olcum-agi/tazelik.mjs — imajin icerik kaydi ile gercek icerigi arasindaki fark (model)
import { uretec } from "./acilis.mjs";
import { ROL, ORTAM } from "./pisirme.mjs";

const BILESEN = ["cekirdek kutuphane", "sifreleme kutuphanesi", "sikistirma kutuphanesi",
  "ad cozumleyici eklentisi", "sertifika deposu", "saat dilimi verisi", "kabuk",
  "yerellestirme verisi", "matematik kutuphanesi", "surum uyumluluk katmani",
  "kayit kutuphanesi", "metin ayristirici", "ag istemcisi", "zamanlayici"];
const DONGU = 30;                          // tam yeniden pisirme dongusu (gun)
const ROL_MAKINE = [5, 6, 7, 9, 11, 12];   // rol basina makine; toplam 50

// Her rol imaji: kayitta yazan dogrudan bilesenler + kayda girmeyen dolayli bilesenler.
const katalog = (tohum = 20260813) => {
  const r = uretec(tohum);
  return Array.from({ length: ROL }, (_, i) => {
    const kayitli = BILESEN.filter(() => r() < 0.4);
    const dolayli = BILESEN.filter((b) => !kayitli.includes(b) && r() < 0.35);
    return { kayitli, gercek: [...kayitli, ...dolayli], makine: ROL_MAKINE[i] };
  });
};

// Bes ayri guvenlik duzeltmesi: bilesenler yerine konmadan secilir, gun uretecten gelir.
const duzeltme = (tohum = 20260814) => {
  const r = uretec(tohum), havuz = [...BILESEN];
  return Array.from({ length: 5 }, () => ({
    bilesen: havuz.splice(Math.floor(r() * havuz.length), 1)[0],
    gun: 1 + Math.floor(r() * DONGU),
  }));
};

const k = katalog(), d = duzeltme();
const kayitli = k.reduce((t, i) => t + i.kayitli.length, 0);
const gercek = k.reduce((t, i) => t + i.gercek.length, 0);
console.log(`${ROL} rol imaji, ${BILESEN.length} bilesen turu; icerik kaydi ${kayitli} girdi ` +
  `yaziyor, imajlarda ${gercek} girdi var: ${gercek - kayitli} girdi kayit disi ` +
  `(%${(100 * (gercek - kayitli) / gercek).toFixed(0)})\n`);
console.log("duzeltme".padEnd(26) + "kayitta".padEnd(10) + "gercekte".padEnd(10) +
  "kacirilan".padEnd(11) + "yamasiz makine".padEnd(16) + "makine-gunu");
let toplamGun = 0, toplamKacan = 0;
for (const f of d) {
  const kayitta = k.filter((i) => i.kayitli.includes(f.bilesen));
  const gercekte = k.filter((i) => i.gercek.includes(f.bilesen));
  const kacan = gercekte.filter((i) => !kayitta.includes(i));
  const makine = kacan.reduce((t, i) => t + i.makine, 0);
  const gun = makine * (DONGU - f.gun);
  toplamGun += gun; toplamKacan += kacan.length;
  console.log(f.bilesen.padEnd(26) + `${kayitta.length} imaj`.padEnd(10) +
    `${gercekte.length} imaj`.padEnd(10) + `${kacan.length} imaj`.padEnd(11) +
    `${makine}/50`.padEnd(16) + String(gun));
}
console.log(`\nbes duzeltmede kacirilan imaj: ${toplamKacan} (saf pismis yolda ` +
  `${toplamKacan * ORTAM}); yamasiz makine-gunu: ${toplamGun}`);
console.log(`kacirilan imajlar ancak ${DONGU} gunluk tam yeniden pisirmede kapaniyor`);
6 rol imaji, 14 bilesen turu; icerik kaydi 32 girdi yaziyor, imajlarda 52 girdi var: 20 girdi kayit disi (%38)

duzeltme                  kayitta   gercekte  kacirilan  yamasiz makine  makine-gunu
matematik kutuphanesi     6 imaj    6 imaj    0 imaj     0/50            0
kabuk                     3 imaj    5 imaj    2 imaj     23/50           322
sertifika deposu          2 imaj    2 imaj    0 imaj     0/50            0
sifreleme kutuphanesi     1 imaj    3 imaj    2 imaj     14/50           126
saat dilimi verisi        0 imaj    0 imaj    0 imaj     0/50            0

bes duzeltmede kacirilan imaj: 4 (saf pismis yolda 12); yamasiz makine-gunu: 448
kacirilan imajlar ancak 30 gunluk tam yeniden pisirmede kapaniyor

Başlık satırı bu dersin sayısıdır. İçerik kaydı altı imaj için 32 bileşen girdisi yazar; imajların içinde 52 girdi vardır. 20 girdi, yüzde 38’i kayıt dışıdır — başka bir bileşenle birlikte gelen bileşenler. Kayıt yanlış değildir; eksiktir.

Eksikliğin bedeli üçüncü ve dördüncü sütunda görünür. kabuk düzeltmesinde kayıt 3 imajın etkilendiğini söyler, gerçekte 5 imaj etkilenmiştir; 2 imaj yeniden pişirilmez ve o imajlardan açılan 23 makine yamasız kalır. sifreleme kutuphanesi düzeltmesinde kayıt 1 imaj der, gerçek 3’tür. Beş düzeltmede toplam 4 imaj kaçırılır ve 448 yamasız makine-günü birikir. Bu makineler bir sonraki 30 günlük tam yeniden pişirmeye kadar açıkta durur, çünkü onları kimse aramamaktadır.

Son satırın ortam boyutu da vardır: aynı eksiklik saf pişmiş yolda 4 değil 12 imaj kaçırır. Ortamı imaja pişirmek yalnız pişirme yükünü üçe katlamaz, kaydın her eksikliğini de üçe katlar.

Bu, üç yolun ölçüsünü tamamlar. Her açılışta yapılandıran yolda yeniden pişirme kümesi diye bir şey olmadığı için yanlış da hesaplanamaz; düzeltme paket deposuna girdiği anda her makinenin bir sonraki açılışında gelir. Pişmiş imaj açılışı bağımsızlaştırır ve içeriği dondurur — karşılığında envanteri bir kayda çevirir ve o kaydın eksikliği sessiz bir güvenlik açığıdır. Kaydın kapsamadığı 20 girdi, bu kursun baştan beri saydığı şeydir.

Özet

  • Açılış süresi 176 saniyeden 45 saniyeye, dış çağrı sayısı 18’den 2’ye iner; 40 makinelik bir açılışta beklenen açılmayan makine 3,2’den 0,2’ye düşer.
  • Hiçbir yol sır deposu çağrısından kurtulamaz — hassas değer imaja pişirilemez; pişmiş yol bağımlılık sayısını dörtten ikiye indirirken imaj deposunu yeni bir bağımlılık olarak edinir.
  • Ortam imaja pişirilirse beş düzeltme 75 imaj pişirmesi, açılışta uygulanırsa 25 pişirme ister; pişirici dakika 334’e karşı 117’dir.
  • Yayılma penceresi 4,26 güne karşı 4,17 gündür: pişirmenin katkısı 0,09 gün, pencereyi belirleyen filonun günde 12 makine değişebilmesidir.
  • İçerik kaydı 32 girdi yazar, imajlarda 52 girdi vardır; yüzde 38’lik eksiklik beş düzeltmede 4 imajı (saf pişmiş yolda 12) yeniden pişirme kümesinin dışında bırakır ve 448 yamasız makine-günü biriktirir.
  • Pişmiş imaj sapmayı açılıştan kaldırır ama envanteri bir kayda çevirir; o kaydın eksikliği sessizdir, çünkü pişirme başarıyla biter.

Sonraki Adım

Bu dersin ölçtüğü akış artık bir yapı adımıdır: imaj derlenir, sınanır, sürümlenir ve ortamlara çıkar. Aynı şey altyapı kaydı için de geçerlidir — plan üretilir, statik denetimden ve politika taramasından geçer, fiyatlanır, uygulanır. Bu konunun dersleri bu adımları ayrı ayrı saydı, ama hepsi elle çalıştırıldı.

M22/K04 uygulama değişikliğini kapılardan geçirmiş, kapının neyi yakalayıp neyi kaçırdığını ölçmüştü; o ölçü tekrarlanmaz, uygulanır. Sonraki ders altyapı değişikliğini aynı hattan geçirir ve sorar: bu kursta sayılan denetimler bir hatta dizildiğinde kaç değişiklik hangi kapıda durur, kaç değişiklik bütün kapılardan geçip yine de sapma üretir ve hattın kendisi kaç dakika ekler?

İ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