---
title: 'Planlama ve Uygulama Akışı'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/planlama-ve-uygulama-akisi'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Planlama ve Uygulama Akışı

Kayıt ile durumu karşılaştırıp kalem kalem ekle, değiştir, yeniden oluştur ve sil kararı üreten bir planlayıcı yazılır, sonra planın kendisi ölçülür: kaç kalem planda yok ama uygulamada oluyor, kaç kalem planda olup gerçekleşmiyor, yeniden oluşturulacak denilen kalemlerin kaçı gerçekten yeniden oluşturuluyor ve planı gözden geçirmek kaç satır kaç dakika tutuyor.

Bir önceki ders plan kalemlerini kayıt biçimine göre saydı, ama planın kendisini hep hazır kabul
etti: kalemler bir yerden geliyordu. Bu ders o yeri kurar. Planlayıcı, bildirimsel sağlamanın en
somut vaadidir — değişiklik uygulanmadan önce ne olacağını gösteren bir liste. Vaadi ölçmenin yolu
da bellidir: listeyi üret, sonra uygula, sonra ikisini karşılaştır.

Daha önce sürekli koşan bir uzlaşma döngüsü ölçülmüştü: istenen durumla gerçek durumu her turda
karşılaştırıp farkı kendiliğinden kapatan bir denetleyici. Buradaki akış onun tersidir. Uygulama
**tetiklenir**; iki tetikleme arasında geçen sürede gerçek, kimseye sormadan kendi başına değişir.
Plan da işte o arada üretilir ve bu dersin bütün sapmaları o boşluktan çıkar.

Ölçüm **bölgesel ölçüm ağının** kaydı üzerindedir ve **kurgudur**; koşan şey `node` ile yazılmış
bir **planlayıcı modelidir**, hiçbir sağlayıcıya çağrı gitmez.

**BS37.** Planlayıcı kaydı **durumla** karşılaştırır, gerçekle değil. Durum geçen uygulamanın
yazdığı defterdir; gerçek sağlayıcıda o an durandır. İkisi ayrı kaynaktır.
**BS38.** Durum on üç kaynak taşır ve geçen uygulamadan kalmıştır.
**BS39.** Kayıt durumdan on bir noktada ayrılır: bir yeni kaynak, bir silinen kaynak, üç imaj
yükseltmesi ve altı alan değişikliği.
**BS40.** Gerçek durumdan üç noktada sapmıştır; üçü de kayıt dışı, elle yapılmış değişikliktir.
**BS41.** Planlayıcının şeması ile koşan sağlayıcının davranışı üç noktada ayrılır: planlayıcı
`boyut` değişikliğini yeniden oluşturma sayar ama sağlayıcı o alanı yerinde günceller; sağlayıcı
dizeleri büyük-küçük harf ayırmadan saklar; yeni yaratılan makineye kayıtta olmayan bir alan ekler.
Hesaplanan alanın değeri uygulamadan önce bilinmez, yalnız baktığı kaynağın yeniden oluşturulup
oluşturulmayacağından tahmin edilir.
**BS42.** Plan kalemi bir başlık satırı yazar; ekle, sil ve yeniden oluştur kalemlerinde kaynağın
bütün alanları, değiştir kaleminde yalnız değişen alanlar listelenir. Dikkatli okuma hızı dakikada
25 satırdır.


## Planlayıcı

```js
// plan.mjs — kayit ile durumu karsilastirip plan ureten planlayici, ve plani gercek
// uygulamayla karsilastiran olcum. Model; hicbir saglayiciya cagri gitmez.

const REF = (kaynak) => ({ ref: kaynak });      // hesaplanan alan: degeri uygulamadan once bilinmez

// BS38: durum — gecen uygulamanin yazdigi kayit. On uc kaynak.
const DURUM = {
  "ag.olcum": { blok: "10.20.0.0/16", bolge: "kuzey" },
  "altag.toplayici": { ag: "ag-01", blok: "10.20.1.0/24" },
  "guvenlik_kumesi.toplayici": { ag: "ag-01", giris: "10.20.1.0/24" },
  "veri_deposu.sayac": { altag: "altag-01", boyut: "orta", surum: "4.2" },
  "kuyruk.parti": { altag: "altag-01", saklama: 3 },
  "kuyruk.eski_parti": { altag: "altag-01", saklama: 3 },
  "makine.toplayici_kuzey_1": { altag: "altag-01", imaj: "temel-7", boyut: "orta" },
  "makine.toplayici_kuzey_2": { altag: "altag-01", imaj: "temel-7", boyut: "orta" },
  "makine.toplayici_dogu_1": { altag: "altag-01", imaj: "temel-7", boyut: "orta" },
  "nesne.toplayici_ayari": { depo: "olcum-yapilandirma", veri_adresi: "sayac-01.veri" },
  "dengeleyici.toplayici": { altag: "altag-01", algoritma: "sirayla" },
  "saglik_denetimi.toplayici": { hedef: "dengeleyici-01", aralik: 30 },
  "dns_kaydi.toplayici": { adres: "dengeleyici-01.adres", ttl: 300 },
};

// BS39: kayit — istenen. Durumdan on bir noktada ayriliyor.
const KAYIT = {
  ...DURUM,
  "veri_deposu.sayac": { altag: "altag-01", boyut: "buyuk", surum: "4.2" },
  "kuyruk.parti": { altag: "altag-01", saklama: 7 },
  "makine.toplayici_kuzey_1": { altag: "altag-01", imaj: "temel-9", boyut: "orta" },
  "makine.toplayici_kuzey_2": { altag: "altag-01", imaj: "temel-9", boyut: "orta" },
  "makine.toplayici_dogu_1": { altag: "altag-01", imaj: "temel-9", boyut: "orta" },
  "makine.toplayici_dogu_2": { altag: "altag-01", imaj: "temel-9", boyut: "orta" },
  "nesne.toplayici_ayari": { depo: "olcum-yapilandirma", veri_adresi: REF("veri_deposu.sayac") },
  "dengeleyici.toplayici": { altag: "altag-01", algoritma: "SIRAYLA" },
  "saglik_denetimi.toplayici": { hedef: "dengeleyici-01", aralik: 10 },
  "dns_kaydi.toplayici": { adres: "dengeleyici-01.adres", ttl: 60 },
};
delete KAYIT["kuyruk.eski_parti"];

// BS40: gercek — saglayicida gercekten duran. Durumdan uc noktada sapmis; plan bunlari gormez.
const GERCEK = {
  ...DURUM,
  "ag.olcum": { blok: "10.20.0.0/17", bolge: "kuzey" },          // elle daraltilmis
  "guvenlik_kumesi.toplayici": { ag: "ag-01", giris: "0.0.0.0/0" },  // elle acilmis
  "saglik_denetimi.toplayici": { hedef: "dengeleyici-01", aralik: 5 },  // elle dusurulmus
};

const YENIDEN_PLAN = ["imaj", "boyut", "altag"];   // BS41: planlayicinin elindeki sema
const YENIDEN_GERCEK = ["imaj", "altag"];          // saglayici boyutu yerinde guncelliyor
const NORM = (v) => (typeof v === "string" ? v.toLowerCase() : v);
const VARSAYILAN = { makine: { izleme: "acik" } };  // saglayici yeni kaynaga kendi ekliyor
const K = (v) => JSON.stringify(v);

// Ortak karsilastirici. gercekMi=false ise planlayici, true ise uygulama gozuyle bakar.
function karsilastir(kayit, taban, { gercekMi }) {
  const yeniden = gercekMi ? YENIDEN_GERCEK : YENIDEN_PLAN;
  const esit = gercekMi ? (a, b) => K(NORM(a)) === K(NORM(b)) : (a, b) => K(a) === K(b);
  const kalem = new Map();
  for (const [ad, y] of Object.entries(kayit)) {
    const e = taban[ad];
    const tum = Object.keys(y).length;
    if (!e) { kalem.set(ad, { karar: "ekle", alan: Object.keys(y), tum }); continue; }
    const alan = Object.keys(y).filter((k) => !y[k]?.ref && !esit(y[k], e[k]));
    const karar = alan.length
      ? (alan.some((k) => yeniden.includes(k)) ? "yeniden olustur" : "degistir") : null;
    kalem.set(ad, { karar, alan, tum });
  }
  for (const ad of Object.keys(taban))
    if (!kayit[ad]) kalem.set(ad, { karar: "sil", alan: [], tum: Object.keys(taban[ad]).length });
  // Hesaplanan alan: baktigi kaynak yeniden olusturuluyorsa deger degisir.
  for (const [ad, y] of Object.entries(kayit))
    for (const [k, v] of Object.entries(y))
      if (v?.ref && kalem.get(v.ref)?.karar === "yeniden olustur") {
        const kl = kalem.get(ad);
        kl.alan.push(k);
        kl.karar = kl.alan.some((a) => yeniden.includes(a)) ? "yeniden olustur" : "degistir";
      }
  for (const [ad, kl] of kalem) if (!kl.karar) kalem.delete(ad);
  return kalem;
}

const PLAN = karsilastir(KAYIT, DURUM, { gercekMi: false });
const UYGULAMA = karsilastir(KAYIT, GERCEK, { gercekMi: true });
// Saglayici varsayilani: yeni kaynak yaratilinca plan disi alan eklenir.
let varsayilanAlan = 0;
for (const [ad, kl] of UYGULAMA)
  if (kl.karar === "ekle") varsayilanAlan += Object.keys(VARSAYILAN[ad.split(".")[0]] ?? {}).length;

const say = (m, k) => [...m.values()].filter((v) => v.karar === k).length;
console.log("karar          plan  uygulama");
const kutuk = (ad, a, b) =>
  console.log(`${ad.padEnd(15)}${String(a).padStart(4)}${String(b).padStart(10)}`);
for (const k of ["ekle", "degistir", "yeniden olustur", "sil"])
  kutuk(k, say(PLAN, k), say(UYGULAMA, k));
kutuk("toplam", PLAN.size, UYGULAMA.size);

const planDisi = [...UYGULAMA.keys()].filter((a) => !PLAN.has(a));
const olmayan = [...PLAN.keys()].filter((a) => !UYGULAMA.has(a));
const ortak = [...PLAN.keys()].filter((a) => UYGULAMA.has(a));
const kararUyusmaz = ortak.filter((a) => PLAN.get(a).karar !== UYGULAMA.get(a).karar);
const planYeniden = [...PLAN].filter(([, v]) => v.karar === "yeniden olustur").map(([a]) => a);
const gercekYeniden = planYeniden.filter((a) => UYGULAMA.get(a)?.karar === "yeniden olustur");
const eskiYanlis = ortak.filter((a) => DURUM[a] && GERCEK[a] && K(DURUM[a]) !== K(GERCEK[a]));

console.log("\nplanin uygulamayi ongorme orani");
console.log(`  planda yok, uygulamada oldu : ${planDisi.length}  (${planDisi.join(", ")})`);
console.log(`  planda var, uygulamada yok  : ${olmayan.length}  (${olmayan.join(", ")})`);
console.log(`  ikisinde de var             : ${ortak.length}, karari uyusmayan ` +
  `${kararUyusmaz.length} (${kararUyusmaz.join(", ")})`);
console.log(`  yeniden olusturma orani     : ${gercekYeniden.length}/${planYeniden.length}`);
console.log(`  planin gosterdigi eski deger yanlis: ${eskiYanlis.length} kalem ` +
  `(${eskiYanlis.join(", ")})`);
console.log(`  planda hic gorunmeyen alan  : ${varsayilanAlan} (saglayici varsayilani)`);
const kesisim = ortak.length - kararUyusmaz.length;
const birlesim = new Set([...PLAN.keys(), ...UYGULAMA.keys()]).size;
console.log(`  tam isabet ${kesisim}/${birlesim} = %${Math.round((kesisim / birlesim) * 100)}`);

// BS42: plan kalemi 1 baslik satiri yazar; ekle/sil/yeniden olustur kaleminde kaynagin butun
// alanlari, degistir kaleminde yalniz degisen alanlar listelenir. Dikkatli okuma 25 satir/dakika.
const TUMU = ["ekle", "sil", "yeniden olustur"];
const satirSay = (m) => [...m.values()].reduce((s, v) =>
  s + 1 + (TUMU.includes(v.karar) ? v.tum : v.alan.length), 0);
const kararSatiri = (m) => [...m.values()]
  .filter((v) => v.karar === "yeniden olustur" || v.karar === "sil")
  .reduce((s, v) => s + 1 + v.tum, 0);

// Ayni kaydin N bolgede yinelenmis hali: adresler ve hesaplanan alan atiflari onekleniyor.
const olcekle = (obj, n) => Object.fromEntries(Array.from({ length: n }, (_, i) =>
  Object.entries(obj).map(([ad, y]) => [`b${i}_${ad}`, Object.fromEntries(
    Object.entries(y).map(([k, v]) => [k, v?.ref ? REF(`b${i}_${v.ref}`) : v]))])).flat());

console.log("\nplani okumanin bedeli");
console.log("bolge  kalem  satir  dakika  karar isteyen satir   %");
for (const n of [1, 3, 10, 30]) {
  const pl = karsilastir(olcekle(KAYIT, n), olcekle(DURUM, n), { gercekMi: false });
  const t = satirSay(pl), kr = kararSatiri(pl);
  console.log(`${String(n).padStart(5)}${String(pl.size).padStart(7)}${String(t).padStart(7)}` +
    `${(t / 25).toFixed(1).padStart(8)}${String(kr).padStart(21)}` +
    `${String(Math.round((kr / t) * 100)).padStart(4)}`);
}
```

```
karar          plan  uygulama
ekle              1         1
degistir          5         6
yeniden olustur   4         3
sil               1         1
toplam           11        11

planin uygulamayi ongorme orani
  planda yok, uygulamada oldu : 2  (ag.olcum, guvenlik_kumesi.toplayici)
  planda var, uygulamada yok  : 2  (nesne.toplayici_ayari, dengeleyici.toplayici)
  ikisinde de var             : 9, karari uyusmayan 1 (veri_deposu.sayac)
  yeniden olusturma orani     : 3/4
  planin gosterdigi eski deger yanlis: 1 kalem (saglik_denetimi.toplayici)
  planda hic gorunmeyen alan  : 1 (saglayici varsayilani)
  tam isabet 8/13 = %62

plani okumanin bedeli
bolge  kalem  satir  dakika  karar isteyen satir   %
    1     11     33     1.3                   19  58
    3     33     99     4.0                   57  58
   10    110    330    13.2                  190  58
   30    330    990    39.6                  570  58
```

Üst tablo ilk bakışta rahatlatıcıdır: plan on bir kalem, uygulama on bir kalem. Sayı tutuyor.
Alt bölüm o rahatlığı kaldırır — aynı sayıdaki iki liste **aynı liste değildir**. On üç ayrı adresin
sekizinde plan ile uygulama hem kalemde hem kararda birleşiyor. Tam isabet oranı yüzde 62.

Sapmanın kaynağı tek bir yapısal seçimdir: planlayıcı kaydı durumla karşılaştırır, uygulama ise
gerçeğe dokunur. Durum ile gerçek arasındaki her fark, plana **tanım gereği** giremez. Ölçüm ağında
üç kalem böyle: ağ bloğu biri tarafından daraltılmış, güvenlik kümesinin giriş kuralı sonuna kadar
açılmış, sağlık denetiminin aralığı elle düşürülmüş. Plan hiçbirini yazmaz. Uygulama ilk ikisini
sessizce geri alır — planda görünmeyen iki kalem — üçüncüsünde ise kalemi doğru gösterir ama **eski
değeri yanlış** gösterir: plan "30'dan 10'a" der, gerçekte 5'ten 10'a çıkılır.

Bu üçüncü tür özellikle sinsi olandır, çünkü kalem sayısını bozmaz. Planı okuyan kişi doğru sayıda
kalem görür, doğru kararları görür, yalnız her kalemin **nereden** başladığı konusunda yanıltılır.
Güvenlik kümesinin sonuna kadar açılmış olması da böyle geri alınır: kimse istemeden düzeltilir,
kimse fark etmeden kapanır ve o kuralın ne kadar süre açık kaldığı hiçbir yere yazılmaz.

## Planda Olup Gerçekleşmeyen Kalemler

Ters yöndeki iki kalem başka bir mekanizmadan gelir. `dengeleyici.toplayici` kalemi plandadır
çünkü kayıt algoritma değerini büyük harfle yazmıştır ve planlayıcı dizeleri birebir karşılaştırır.
Sağlayıcı aynı değeri harf ayrımı gözetmeden sakladığı için uygulamada hiçbir şey olmaz. Plan bir
değişiklik vaat etti, uygulama sıfır iş yaptı.

Bu kalem zararsız görünür ama bedeli vardır: her plan koşumunda yeniden çıkar. Kayıt ile durum
arasında kapanmayan bir fark, uzlaşmayan bir kalem olarak kalıcı hâle gelir ve planı okuyan kişi
onu her seferinde gözden geçirmek zorunda kalır. Zamanla böyle kalemler "her zaman çıkar, boş ver"
diye öğrenilir — ve o alışkanlık plandaki gerçek bir kalemi de aynı refleksle geçiştirir.

İkinci kalem daha derindir. `nesne.toplayici_ayari` kaydında veri deposunun adresi vardır ve bu
adres **hesaplanan bir alandır**: değeri ancak uygulamadan sonra bilinir. Planlayıcı bu alanı
tahmin edemez, yalnız şunu bilir — baktığı kaynak yeniden oluşturulacaksa adres de değişecektir.
Veri deposu planda yeniden oluşturma kalemidir, dolayısıyla ayar nesnesi de plana girer. Uygulamada
veri deposu yeniden oluşturulmaz, adresi değişmez ve ayar nesnesine dokunulmaz. Planlayıcı burada
yanlış bir veri değil, **yanlış bir varsayımın sonucunu** yazdı.

## Yeniden Oluşturulacak Denilen Kalemler

Yeniden oluşturma satırı bu kursun en pahalı kararıdır: yok etmek ve yeniden yaratmak geri alınamaz
ve önceki derste ölçüldüğü gibi kesinti üretir. Planın bu kalemdeki isabeti dörtte üçtür.

Kaçırılan kalem veri deposudur ve sebebi bir kayıt hatası değildir. Planlayıcının elindeki şema
`boyut` alanının yeniden oluşturma gerektirdiğini söylüyor; koşan sağlayıcı ise o alanı yerinde
güncelleyebiliyor. Şema ile davranış arasındaki bu tek satırlık fark, plana bakan kişiye kırk bir
günlük sayaç verisinin silineceğini gösterdi. Yanılma yönü şanslıdır — plan gerçekten olandan daha
kötüsünü vaat etti — ama yön bir güvence değildir; ters yöndeki bir şema farkı, planda "yerinde
değişecek" yazan bir kalemi uygulamada yeniden oluşturmaya çevirir.

Bu tek kalemin dalga etkisi de sayıya girer: ayar nesnesinin plana girmesinin **tek sebebi** veri
deposunun yeniden oluşturulacak sanılmasıydı. Yanlış bir yeniden oluşturma kararı, kendisi dışında
en az bir kalem daha üretti. Hesaplanan alana bakan kaynak sayısı arttıkça bu çarpan büyür.

Bir de hiç görünmeyen bir kalem var. Yeni yaratılan makineye sağlayıcı, kayıtta yazmayan bir alan
ekliyor. Plan üç alanlı bir kaynak yaratacağını söylüyor, ortaya dört alanlı bir kaynak çıkıyor.
Dördüncü alan bir sonraki uygulamada da plana girmez, çünkü kayıt o alanı hiç bilmez. **Kaydın
kapsamadığı altyapı** burada tam olarak bir alan genişliğindedir, ve o alanı kimse yönetmez.

## Planı Okumanın Bedeli

Alt tablo planın kendi maliyetini verir. Tek bölge için plan 33 satır ve dikkatli okumayla 1,3
dakika. Bu, gözden geçirilebilir bir metindir. Ölçüm ağı otuz bölgeye çıktığında aynı plan 990
satıra ve 39,6 dakikaya çıkar — ve bu, tek bir imaj yükseltmesinin planıdır.

Oranın sabit kalması dikkate değer: karar isteyen satırlar, yani yeniden oluşturma ve silme
kalemleri, her ölçekte planın yüzde 58'idir. Plan büyüdükçe sinyal oranı düşmez, ama **mutlak
gözden geçirme yükü** doğrusal büyür. Otuz bölgelik bir planda 570 satır geri alınamaz bir karar
taşır ve bunların hepsi aynı ekranda, aynı biçimde, aynı renkte akar.

Buradan çıkan işletim kuralı sayıya dayanır. Kırk dakikalık bir planı satır satır okuyan kimse
yoktur; okunmayan plan ise vaadini yerine getirmez. Planın gözden geçirilebilir kalması için ya
kaydın uygulama birimi küçültülür — otuz bölge tek seferde değil, bölge bölge uygulanır — ya da
plandan yalnız yeniden oluşturma ve silme kalemleri süzülüp önce onlar okunur. İkisi de kaydın
bölünmesiyle ilgilidir, ve o konu bu dersin sınırının dışındadır.

Son olarak planın öngörme oranı ile okuma bedeli birlikte okunmalıdır. Yüzde 62 isabetli bir liste,
otuz dakika okunduğunda bile uygulamanın tamamını anlatmaz. Planın değeri kesinlik değil, **karar
verilebilirliktir**: geri alınamaz kalemleri uygulamadan önce göstermesi. O işi dörtte üç isabetle
yapıyor, ve kaçırdığı çeyreğin sebebi kayıtta değil, planlayıcının şeması ile sağlayıcının
davranışı arasındaki farktadır.

## Özet

- Planlayıcı kaydı durumla karşılaştırır, uygulama gerçeğe dokunur; durum ile gerçek arasındaki her
  fark plana tanım gereği giremez. Sapmaların çoğunun kaynağı bu tek yapısal seçimdir.
- Plan 11 kalem, uygulama 11 kalem, ama 13 adresin yalnız 8'inde hem kalem hem karar uyuşuyor:
  tam isabet yüzde 62.
- Planda yok, uygulamada oldu: 2 kalem (elle daraltılmış ağ bloğu, sonuna kadar açılmış giriş
  kuralı). 1 kalem daha doğru göründü ama eski değeri yanlış gösterdi: plan 30'dan der, gerçek 5'tir.
- Planda var, uygulamada yok: 2 kalem — biri harf normalizasyonundan (her koşumda yeniden çıkar),
  biri hesaplanan alandan (yanlış yeniden oluşturma varsayımının dalga etkisi).
- Yeniden oluşturma isabeti 3/4. Kaçırılan kalem, planlayıcının şeması ile sağlayıcının davranışı
  arasındaki bir alanlık farktan geldi ve tek başına bir kalem daha üretti.
- Plan 1 bölgede 33 satır ve 1,3 dakika, 30 bölgede 990 satır ve 39,6 dakika; karar isteyen satır
  oranı her ölçekte yüzde 58 kalıyor, yani gözden geçirme yükü doğrusal büyüyor.

## Sonraki Adım

Bu ders planı, kayıtta yazılı olan kaynaklar için ölçtü. Ölçüm ağında ise kayıtta hiç yazmayan
kaynaklar da var: ilk kurulumda elle açılmış bir nesne deposu, bir DNS bölgesi, iki eski makine.
Onlar plana hiç girmez, çünkü planlayıcı yalnız kaydın ve durumun bildiğini karşılaştırır. Sonraki
ders bu kaynakları yönetime alır — **içe aktarma** — ve bedelini sayar: kalem başına kaç alan elle
eşleştiriliyor, içe aktarma sonrası ilk planda kaç kalem gereksiz değişiklik gösteriyor, kaynağı
kayıt dışı bırakmakla yönetime almak arasındaki fark ne.
