---
title: 'Veri Kaynakları'
source: 'https://academia.sh/tr/kurslar/kod-olarak-altyapi/veri-kaynaklari'
course: 'Kod Olarak Altyapı'
language: tr
updated: '2026-08-17T18:09:06+00:00'
license: 'CC BY-SA 4.0'
---

# Veri Kaynakları

Kaydın dışında duran altyapıya okuyarak bağlanmanın bedeli sayılır: kaç veri kaynağı, günde kaç okuma, ne kadar süre, ve okunan bir değer değiştiğinde kaç kaynağın yeniden hesaplanıp kaçının yeniden oluşturulduğu. Sapma taramasının kaydın yönettiği kalemlerle sınırlı kalması ve kayıt dışı bir değişikliğin taramada neden hiç görünmediği ölçülür.

Bir önceki ders hedefteki her kaynağı kaydın kurduğunu varsaydı. Gerçek bir ortamda bu doğru
değildir: ağın omurgası, temel imaj, kimlik tanımları, sertifikalar ve bölge kotaları çoğunlukla
başka ekiplerin elindedir. Kayıt onları yaratmaz, silmez, güncellemez — yalnız **okur**. Okuyan
yapının adı **veri kaynağı**dır ve bedeli üç ayrı yerde birikir: her plan koşumunda yapılan okuma
sayısı ve süresi, okunan bir değer değiştiğinde tetiklenen yeniden hesaplama, ve sapma taramasının
bu kalemleri hiç görmemesi.

Ölçüm **bölgesel ölçüm ağının** batı ortamı üzerindedir ve **kurgudur**; kayıt dışı altyapı, veri
kaynakları, okuma süreleri ve bağımlılık yayılımı `node` ile kurulmuş bir **modeldir**.

**BS13.** Kayıt sekiz kaynağı yönetir; beş veri kaynağı kaydın dışındaki kalemleri okur ve bu
kalemlerin sahibi başka ekiplerdir.
**BS14.** Bir veri kaynağı okunduğunda bütün alanlarını getirir; alan tek tek seçilemez.
**BS15.** Her plan koşumu her veri kaynağını bir kez okur ve sonuç önbelleğe alınmaz.
**BS16.** Hat günde altı, elle plan günde dört kez koşar.
**BS17.** Okunan bir değer değiştiğinde onu girdi alan her kaynak yeniden hesaplanır; değer o
kaynağın zorlayan listesindeyse kaynak yeniden oluşturulur ve yeniden oluşturma aşağıya yayılır.
**BS18.** Sapma taraması yalnız kaydın yönettiği kaynakları hedefteki karşılıklarıyla karşılaştırır.

## Kaydın Dışındaki Altyapı

```js
// dis.mjs — kaydin disinda duran kurgu altyapi ve onu okuyan veri kaynaklari (model).
export const DIS = {                                // baska ekiplerin yonettigi kalemler
  ag: { alt_ag: "alt-ag-7", mtu: 1500, gecit: "gecit-a" },
  imaj: { surum: "temel-2", yas_gun: 34 },
  kimlik: { izin: 12 },
  sertifika: { bitis_gun: 41 },
  kota: { makine_ust: 24, kuyruk_ust: 16 },
};
export const OKUMA_MS = { ag: 120, imaj: 340, kimlik: 90, sertifika: 210, kota: 60 };
export const SAHIP = { ag: "ag ekibi", imaj: "imaj ekibi", kimlik: "guvenlik ekibi",
  sertifika: "guvenlik ekibi", kota: "bulut yonetimi" };

export function okuyucuYap() {                      // her okuma sayilir, suresi toplanir
  const sayac = {}, sure = { ms: 0 };
  return { sayac, sure,
    oku(ad) { sayac[ad] = (sayac[ad] || 0) + 1; sure.ms += OKUMA_MS[ad]; return { ...DIS[ad] }; },
    toplam: () => Object.values(sayac).reduce((a, b) => a + b, 0) };
}
```

```js
// kayit.mjs — kaydin yonettigi kaynaklar; girdi listesi neyi okuduklarini, zorlayan hangi
// girdinin degismesinin kaynagi yeniden olusturdugunu soyler.
export const KAYNAK = {
  "makine.toplayici": { girdi: ["ag.alt_ag", "imaj.surum", "kota.makine_ust"],
    zorlayan: ["ag.alt_ag", "imaj.surum"] },
  "makine.dogrulayici": { girdi: ["ag.alt_ag", "imaj.surum"], zorlayan: ["ag.alt_ag", "imaj.surum"] },
  "kuyruk.sayac": { girdi: ["kota.kuyruk_ust", "ag.alt_ag"], zorlayan: ["ag.alt_ag"] },
  "kuyruk.uyari": { girdi: ["kota.kuyruk_ust"], zorlayan: [] },
  "veri_deposu.olcum": { girdi: ["ag.alt_ag", "makine.toplayici"], zorlayan: ["ag.alt_ag"] },
  "ag_kurali.toplayici": { girdi: ["ag.gecit", "makine.toplayici"],
    zorlayan: ["ag.gecit", "makine.toplayici"] },
  "uc_nokta.olcum": { girdi: ["sertifika.bitis_gun", "veri_deposu.olcum"], zorlayan: ["veri_deposu.olcum"] },
  "kimlik_baglama.toplayici": { girdi: ["kimlik.izin", "makine.toplayici"], zorlayan: ["makine.toplayici"] },
};

export function yayil(kok) {                        // bir deger degisince kim yeniden hesaplanir
  const hesap = new Set(), yeni = new Set(), sira = [[kok, true]];
  while (sira.length) {
    const [x, xYeni] = sira.shift();
    for (const [k, r] of Object.entries(KAYNAK)) {
      if (!r.girdi.includes(x) || hesap.has(k)) continue;
      hesap.add(k);
      const kYeni = xYeni && r.zorlayan.includes(x);
      if (kYeni) yeni.add(k);
      sira.push([k, kYeni]);
    }
  }
  return { hesap, yeni };
}
```

İki dosya iki ayrı dünyayı tanımlar. Birincisi kaydın yönetmediği kalemleri ve her birinin sahibini
tutar; ikincisi kaydın yönettiği kaynakları ve her birinin hangi dış değeri okuduğunu. Aradaki tek
bağ okuma yönündedir: kayıt dış dünyadan değer alır, dış dünyaya değer yazmaz. Bu tek yönlülük
dersin bütün ölçülerinin kaynağıdır.

## Okumanın Bedeli ve Yayılması

```js
// olc.mjs — okumanin bedeli, bir dis degerin yayilmasi ve sapma taramasinin kapsami.
import { DIS, OKUMA_MS, SAHIP, okuyucuYap } from "./dis.mjs";
import { KAYNAK, yayil } from "./kayit.mjs";

const disAlan = new Set(Object.entries(DIS).flatMap(([a, v]) => Object.keys(v).map((f) => `${a}.${f}`)));
const kullanilan = new Set(Object.values(KAYNAK).flatMap((r) => r.girdi).filter((g) => disAlan.has(g)));
const yaz = (...s) => console.log(s.map((x, i) => String(x).padEnd(i ? 13 : 26)).join("").trimEnd());

console.log(`kayit ${Object.keys(KAYNAK).length} kaynak yonetiyor; ` +
  `${Object.keys(DIS).length} veri kaynagi ${disAlan.size} dis alan getiriyor, ` +
  `${kullanilan.size} tanesi gercekten kullaniliyor`);
yaz("veri kaynagi", "alan", "kullanilan", "okuma ms", "duran kaynak", "sahip");
for (const [a, v] of Object.entries(DIS)) {
  const alan = Object.keys(v).filter((f) => kullanilan.has(`${a}.${f}`));
  const duran = new Set(alan.flatMap((f) => [...yayil(`${a}.${f}`).hesap]));
  yaz(a, Object.keys(v).length, alan.length, OKUMA_MS[a], duran.size, SAHIP[a]);
}

const PLAN_GUNLUK = 10;                             // gunde 6 hat kosumu + 4 elle plan
const o = okuyucuYap();
for (let i = 0; i < PLAN_GUNLUK; i++) for (const a of Object.keys(DIS)) o.oku(a);
console.log(`\ngunde ${PLAN_GUNLUK} plan: ${o.toplam()} dis okuma, ${(o.sure.ms / 1000).toFixed(1)} sn; ` +
  `plan basina ${Object.keys(DIS).length} dis + ${Object.keys(KAYNAK).length} kaynak okumasi`);
console.log(`yilda ${o.toplam() * 365} dis okuma, ${((o.sure.ms * 365) / 60000).toFixed(0)} dakika`);
const tekSure = Object.values(OKUMA_MS).reduce((a, b) => a + b, 0);
console.log(`gunde bir kez onbelleklense: ${Object.keys(DIS).length} okuma, ${(tekSure / 1000).toFixed(2)} sn; ` +
  `dis degisikligin gorunmesi icin beklenen sure ${(24 / PLAN_GUNLUK).toFixed(1)} saat yerine 24 saat`);

console.log(`\ndegisen dis deger        okuyan  yeniden hesaplanan  yeniden olusturulan`);
for (const alan of [...kullanilan].sort()) {
  const { hesap, yeni } = yayil(alan);
  const dogrudan = Object.values(KAYNAK).filter((r) => r.girdi.includes(alan)).length;
  console.log(`  ${alan.padEnd(23)}${String(dogrudan).padStart(4)}` +
    `${String(hesap.size).padStart(18)}${String(yeni.size).padStart(20)}`);
}

const SAPAN = ["ag.alt_ag", "kota.makine_ust"];     // dis kalemde birileri degisiklik yapti
const etki = SAPAN.reduce((s, a) => { const { hesap, yeni } = yayil(a);
  hesap.forEach((x) => s.hesap.add(x)); yeni.forEach((x) => s.yeni.add(x)); return s; },
  { hesap: new Set(), yeni: new Set() });
const kalem = Object.keys(KAYNAK).length + Object.keys(DIS).length;
console.log(`\nsapma taramasi ${Object.keys(KAYNAK).length}/${kalem} kalemi karsilastiriyor ` +
  `(kapsam %${Math.round((Object.keys(KAYNAK).length / kalem) * 100)}); ` +
  `${Object.keys(DIS).length} veri kaynagi hic karsilastirilmiyor`);
console.log(`${SAPAN.length} dis alan degisti -> tarama sonucu "sapma yok"; ` +
  `sonraki plan ${etki.hesap.size} kaynagi yeniden hesaplar, ${etki.yeni.size} kaynagi yeniden olusturur`);
```

```
kayit 8 kaynak yonetiyor; 5 veri kaynagi 9 dis alan getiriyor, 7 tanesi gercekten kullaniliyor
veri kaynagi              alan         kullanilan   okuma ms     duran kaynak sahip
ag                        3            2            120          7            ag ekibi
imaj                      2            1            340          6            imaj ekibi
kimlik                    1            1            90           1            guvenlik ekibi
sertifika                 1            1            210          1            guvenlik ekibi
kota                      2            2            60           7            bulut yonetimi

gunde 10 plan: 50 dis okuma, 8.2 sn; plan basina 5 dis + 8 kaynak okumasi
yilda 18250 dis okuma, 50 dakika
gunde bir kez onbelleklense: 5 okuma, 0.82 sn; dis degisikligin gorunmesi icin beklenen sure 2.4 saat yerine 24 saat

degisen dis deger        okuyan  yeniden hesaplanan  yeniden olusturulan
  ag.alt_ag                 4                 7                   7
  ag.gecit                  1                 1                   1
  imaj.surum                2                 6                   4
  kimlik.izin               1                 1                   0
  kota.kuyruk_ust           2                 2                   0
  kota.makine_ust           1                 5                   0
  sertifika.bitis_gun       1                 1                   0

sapma taramasi 8/13 kalemi karsilastiriyor (kapsam %62); 5 veri kaynagi hic karsilastirilmiyor
2 dis alan degisti -> tarama sonucu "sapma yok"; sonraki plan 7 kaynagi yeniden hesaplar, 7 kaynagi yeniden olusturur
```

Birinci tablo bağın genişliğini verir. Beş veri kaynağı toplam dokuz dış alan getirir, ama kaydın
gerçekten kullandığı alan yedidir: ağın azami paket boyutu ile imajın yaşı okunur, hiçbir kaynağa
girmez. Bu, veri kaynağının alan seçemeyen yapısından gelir — okuma kalem başınadır, alan başına
değil. Okuma süreleri de eşit değildir: imaj kaynağı üç yüz kırk milisaniye, kota kaynağı altmış
milisaniye sürer; en pahalı kaynak en az kullanılan alanı getirendir.

İkinci ölçü tekrar sıklığıdır. Günde on plan koşumu **elli dış okuma** ve sekiz buçuk saniye eder;
yılda on sekiz bin iki yüz elli okuma ve elli dakika. Bu süre tek başına küçüktür, ama iki şeyi
gizler. Birincisi, her plan aynı zamanda sekiz yönetilen kaynağı da okur; plan üretmenin maliyeti
kaynak sayısıyla değil, kaynak artı veri kaynağı sayısıyla büyür. İkincisi, okumanın ucuzlatılması
tazeliğe mal olur: günde bir kez önbelleğe alınırsa okuma elliden beşe, süre sekiz buçuk saniyeden
sekiz yüz milisaniyeye iner, ama dış bir değişikliğin fark edilmesi için beklenen süre iki buçuk
saatten yirmi dört saate çıkar. **Okuma sıklığı doğrudan bir tazelik ölçüsüdür ve düşürülmesi
sapmanın görünmezlik penceresini uzatır.**

Üçüncü tablo yayılmayı verir ve dersin en sert sayısı buradadır. Alt ağ kimliğini dört kaynak
doğrudan okur, ama o değer değiştiğinde **yedi kaynak yeniden hesaplanır ve yedisi de yeniden
oluşturulur** — sekiz kaynaklı bir kayıtta neredeyse tamamı. Yayılmanın nedeni zincirdir: alt ağ
değişince toplayıcı makineler yeniden oluşturulur, onların kimliği değişince ağ kuralı ve kimlik
bağlaması yeniden oluşturulur, veri deposu yeniden oluşturulunca uç nokta da yeniden oluşturulur.
İmaj sürümü altı kaynağı yeniden hesaplatır, dördünü yeniden oluşturur. Buna karşılık kota üst
sınırı beş kaynağı yeniden hesaplatır ama **hiçbirini yeniden oluşturmaz**; sertifika ile kimlik
izni birer kaynakta kalır. Aynı tabloda okunan bir değerin ucuz mu pahalı mı olduğu görünür:
belirleyici olan kaç kaynağın okuduğu değil, okunan alanın zorlayan listelerinde geçip geçmediğidir.

Dördüncü sütun kesinti riskini verir. Ağ ya da kota kaynağı okunamaz hâle gelirse yedişer kaynak
planlanamaz; imaj kaynağı için altı, kimlik ve sertifika için birer kaynak. **Kayıt, yönetmediği
beş kalemin erişilebilirliğine bağımlıdır ve bu bağımlılığın sahibi kayıt değildir.** Sahipler
sütunu bunu adıyla yazar: ağ ekibi, imaj ekibi, güvenlik ekibi, bulut yönetimi. Kaydı değiştirmeye
yetkili ekip ile kaydın okuduğu değeri değiştirmeye yetkili ekip aynı değildir.

## Taramanın Görmediği Yer

Son iki satır kaydın kapsamını sayar. Sapma taraması on üç kalemin sekizini karşılaştırır; kapsam
yüzde altmış ikidir. Karşılaştırılmayan beş kalem, kaydın okuduğu ama yönetmediği kalemlerdir ve
karşılaştırılmamalarının nedeni basittir: **tarama, kaydın söylediği ile gerçeği karşılaştırır;
kayıt bu beş kalem hakkında hiçbir şey söylemez.** Kayıtta istenen bir değer yoksa, gerçeğin ondan
saptığı da söylenemez.

Bunun sonucu son satırdadır. Ağ ekibi alt ağ kimliğini, bulut yönetimi de makine üst sınırını
değiştirir. Sapma taraması koşar ve **sapma yok** der; yönettiği sekiz kaynağın hepsi kayıttaki
hâliyle uyumludur, çünkü hiçbiri değişmemiştir. Aynı anda bir sonraki plan koşumu yedi kaynağı
yeniden hesaplayacak ve yedisini birden yeniden oluşturacaktır. İki cümle aynı ortam için aynı anda
doğrudur: sapma yoktur, ve altyapının yedi kalemi değişmek üzeredir. Aradaki fark, sapmanın kaydın
kapsamı içinde tanımlı olmasıdır — **kaydın kapsamadığı bir değişiklik sapma değildir, sürprizdir.**

Bu ölçünün pratik karşılığı, dış kalemlerin sayısını ve yayılma çapını bilmektir. Yedi kullanılan
dış alandan ikisi tek başına yedi kaynağı yeniden oluşturabilecek durumdadır; üçü hiçbir yeniden
oluşturma tetiklemez. Okunan her yeni dış değer taramanın kapsamını düşürür ve sürpriz yüzeyini
büyütür; okunmayan her dış değer ise kayda elle kopyalanmak zorundadır ve bu kez kopyanın kendisi
sapar.

## Okumak mı, Kopyalamak mı

```js
// kopya.mjs — dis degeri okumak ile kayda kopyalamak: 90 gunluk kurgu takvim (model).
import { DIS } from "./dis.mjs";
import { KAYNAK, yayil } from "./kayit.mjs";

const TAKVIM = [                                    // dis kalemlerde kim ne zaman degisiklik yapti
  [12, "imaj.surum"], [30, "kota.makine_ust"], [40, "ag.alt_ag"],
  [55, "imaj.surum"], [70, "kota.makine_ust"], [78, "ag.gecit"],
];
const TAZELEME = [30, 60, 90], GUN = 90;            // kopyayi elle gozden gecirme gunleri
const disAlan = new Set(Object.entries(DIS).flatMap(([a, v]) => Object.keys(v).map((f) => `${a}.${f}`)));
const kopya = new Set(Object.values(KAYNAK).flatMap((r) => r.girdi).filter((g) => disAlan.has(g)));

let okuYeni = 0, kopyaYeni = 0, yanlisGun = 0, gecikme = 0;
for (const [gun, alan] of TAKVIM) {
  const { hesap, yeni } = yayil(alan), t = TAZELEME.find((g) => g >= gun) ?? GUN;
  okuYeni += yeni.size; kopyaYeni += yeni.size;
  gecikme += t - gun; yanlisGun += (t - gun) * hesap.size;
}
console.log(`${GUN} gunde ${TAKVIM.length} dis degisiklik; kopyalanacak alan ${kopya.size}`);
console.log(`okuyarak    : gecikme 0 gun, ${okuYeni} yeniden olusturma, kayit-gercek uyumsuz 0 kaynak-gun`);
console.log(`kopyalayarak: ortalama gecikme ${(gecikme / TAKVIM.length).toFixed(1)} gun, ` +
  `${kopyaYeni} yeniden olusturma, uyumsuz ${yanlisGun} kaynak-gun`);
console.log(`her iki yolda da sapma taramasinin karsilastirdigi kalem sayisi ${Object.keys(KAYNAK).length}; ` +
  `${Object.keys(DIS).length} dis kalem iki yolda da disarida kalir`);
```

```
90 gunde 6 dis degisiklik; kopyalanacak alan 7
okuyarak    : gecikme 0 gun, 16 yeniden olusturma, kayit-gercek uyumsuz 0 kaynak-gun
kopyalayarak: ortalama gecikme 12.5 gun, 16 yeniden olusturma, uyumsuz 390 kaynak-gun
her iki yolda da sapma taramasinin karsilastirdigi kalem sayisi 8; 5 dis kalem iki yolda da disarida kalir
```

Okumanın alternatifi, dış değerleri kayda elle yazmaktır. Kurgu takvim doksan günde altı dış
değişiklik içerir ve iki yol da sonunda aynı on altı yeniden oluşturmayı üretir — dış dünya
değiştiyse altyapı er ya da geç değişecektir. Fark zamanlamadadır. Okuyan kayıt değişikliği bir
sonraki plan koşumunda alır; kopyalayan kayıt ayda bir gözden geçirmeye bağlıdır ve ortalama **on
iki buçuk gün** geriden gelir. Bu gecikmenin karşılığı **üç yüz doksan kaynak-gündür**: kaydın
gerçeği yanlış anlattığı süre boyunca kaç kaynağın etkilendiğinin toplamı.

Kopyalamanın görünen kazancı okuma yükünün sıfırlanmasıdır; görünmeyen bedeli, yedi alanın kayıtta
donmuş bir kopyasının tutulmasıdır. Bu kopya sapma taramasına girer, ama taramanın karşılaştırdığı
şey kaydın kendi kopyasıyla ondan kurulmuş kaynaktır — dış kalemin gerçek değeri iki yolda da
karşılaştırılmaz. **Kopyalamak taramanın kapsamını genişletmez, yalnız sapmanın adını değiştirir:**
okuyan kayıtta sürpriz, kopyalayan kayıtta eskimiş kayıt.

## Özet

- Kayıt 8 kaynak yönetti; 5 veri kaynağı 9 dış alan getirdi, bunların yalnız 7'si kullanıldı — 2
  alan her plan koşumunda okundu ama hiçbir kaynağa girmedi.
- Günde 10 plan koşumu 50 dış okuma ve 8,2 saniye tuttu; yılda 18.250 okuma ve 50 dakika. Günde bir
  önbellekleme okumayı 5'e indirir, görünmezlik penceresini 2,4 saatten 24 saate çıkarır.
- Alt ağ kimliği değişince 8 kaynağın 7'si yeniden hesaplandı ve **7'si yeniden oluşturuldu**; imaj
  sürümü 6 kaynağı hesaplattı, 4'ünü yeniden oluşturdu. Kota üst sınırı 5 kaynağı hesaplattı ama
  hiçbirini yeniden oluşturmadı: belirleyici olan okuyan sayısı değil, alanın zorlayan listesinde
  geçip geçmediğidir.
- Ağ ya da kota kaynağı okunamazsa 7'şer kaynak planlanamaz; kayıt, sahibi başka ekipler olan 5
  kalemin erişilebilirliğine bağımlıdır.
- Sapma taraması 13 kalemin 8'ini karşılaştırdı (kapsam %62). 2 dış alan değiştiğinde tarama "sapma
  yok" dedi, aynı anda sonraki plan 7 kaynağı yeniden oluşturacak durumdaydı.
- 90 günde 6 dış değişiklik iki yolda da 16 yeniden oluşturma üretti; kopyalayan kayıt ortalama 12,5
  gün geriden geldi ve 390 kaynak-gün boyunca gerçeği yanlış anlattı.

## Sonraki Adım

Buraya kadar kayıt tek bir ortamı anlattı ve okuduğu değerler dışarıdan geldi. Aynı kaydın üç
ortamda koşması gerektiğinde soru değişir: hangi değer ortama göre değişmeli, hangisi her ortamda
aynı kalmalı, ve bu ayrımı kim yazacak. Bir sonraki ders parametreleştirmeyi ölçer: aynı tanım üç
ortama uygulanınca kaç değer ortama göre değişiyor, kaçı değişmemesi gerektiği hâlde değişebilir
durumda duruyor, girdi yüzeyi büyüdükçe yanlış değer verme olasılığı nasıl artıyor, ve çıktılar
başka tanımlara kaç bağımlılık yaratıyor.
