---
title: 'Bulutta Depolama ve Veri'
source: 'https://academia.sh/tr/kurslar/bulut-depolama'
language: tr
updated: '2026-08-17T04:38:59+00:00'
license: 'CC BY-SA 4.0'
lessons: 14
outcomes:
    - 'Depolama türünü erişim örüntüsüne göre seçer ve bedelini sayar'
    - 'Yönetilen veri servisinde devredilen kararı kalem kalem çıkarır'
    - 'Veri aktarımı ve çıkış maliyetini tasarım kararına bağlar'
---

# Bulutta Depolama ve Veri

Verinin kiralanması ve devredilen kararlar: kova, nesne ve anahtar modeli, erişim sıklığına göre depolama sınıfları, sürümleme ile yaşam döngüsü kurallarının otomatik geçişi, blok depolamanın birim türleri ve giriş çıkış başarımı, paylaşımlı dosya sistemi, arşivin geri getirme süresi, süreli erişim veren imzalı bağlantılar, yönetilen ilişkisel veritabanında yedekleme, yama ve devralma otomasyonu, okuma kopyaları, bölüm anahtarı ve kapasite modeliyle yönetilen anahtar değer servisi, ikincil dizinler ve değişim akışları, yönetilen önbellek servisi, bölge ve internet çıkış ücretleri ile anlık görüntü ve zaman noktasına dönüş.

## Depolama Türleri

Verinin nereye konacağı: kova, nesne ve anahtar modelinin dosya sisteminden farkı, erişim sıklığına göre depolama sınıflarının fiyat ve geri getirme dengesi, sürümleme ile yaşam döngüsü kurallarının otomatik geçişi ve silmesi, blok depolamanın birim türleri ve giriş çıkış bütçesi, paylaşımlı dosya sisteminin çok yazarlı kullanımı, arşiv katmanının geri getirme süresi ve süreli erişim veren imzalı bağlantılar.

### Nesne Depolama

Source: https://academia.sh/tr/kurslar/bulut-depolama/nesne-depolama

Kova, nesne ve anahtar modelinin dosya sisteminden kalem kalem ayrılması: dizin yerine önek, yeniden adlandırma yerine kopyalama, kısmi güncellemenin olmaması ve listelemenin ücretli bir işlem olması; her farkın istek sayısına ve bayta çevrilmesi ve anahtar düzeninin geri alınamayan kalem olarak sayılması.

Önceki kurs makineyi ve ağı kiralayarak bitti: örnekler açıldı, alt ağlara yerleşti, filtreden geçti
ve dışarıya açıldı. Bir soru açıkta kaldı — bütün bu makinelerin üzerinde koşan şeyin **verisi**
nerede duruyor. Yerel disk cevabı değildir: örnek kapandığında disk de gider, ölçekleme grubunda
hangi örneğin hangi veriyi tuttuğu bilinmez. Kiralanan katmanda verinin kendi yeri vardır ve o yer
seçildiğinde bir dizi karar sağlayıcıya geçer.

Bu kursun ölçüsü budur: her ders **hangi kararın devredildiğini, hangisinin elde kaldığını**, elde
kalanların hangisinin **geri alınamadığını** ve verinin **çıkarken** ne tuttuğunu sayar. İlk tür en
yaygın varsayılandır: nesne deposu (object storage). Ucuz olduğu doğrudur ve bu bir karar taşımaz;
karar taşıyan şey, nesne deposunun bir dosya sistemi **olmamasıdır**.

#### Kova, Nesne ve Anahtar

Üç kavram vardır. **Kova** (bucket) bir ad alanıdır; içinde **nesne** (object) durur; her nesneye
bir **anahtar** (key) ile erişilir. Anahtar bir yoldur ama yol değildir: `sayac/2026/03/14/A118.json`
düz bir dizedir, içindeki eğik çizgilerin depo için bir anlamı yoktur. Depo bu dizeyi bir sözlükte
arar. Eğik çizgiler yalnız **önek** (prefix) sorgusunda işe yarar: verilen dizeyle başlayan
anahtarlar listelenebilir. Dizin diye bir nesne yoktur, dolayısıyla boş dizin de yoktur, dizin
silme de yoktur, dizinin boyutu diye okunacak bir alan da yoktur.

Bu tek farkın dört sonucu vardır ve dördü de sayılabilir: dizin yerine önek, yeniden adlandırma
yerine kopyalama, kısmi güncelleme yerine tam yeniden yazma ve ücretsiz sanılan listelemenin
ücretli bir işlem olması. Aşağıdaki model bunları kurgu ölçüm ağının nesne kümesi üzerinde sayar.

- **DT1** — Bölgesel ölçüm ağı kurgudur: 4.000 sayaç, 310 günlük geçmiş, dört nesne ailesi. Adetler
  ve ortalama boyutlar modelde yazılıdır.
- **DT2** — Ücretler kurgu **birim** cinsindendir, gerçek bir sağlayıcının fiyatı değildir; saklama,
  istek ve çıkış oranları modelde açık yazılıdır.
- **DT3** — Modelde bir listeleme isteği en çok 1.000 anahtar döndürür; sayfa boyu sağlayıcıdan
  sağlayıcıya değişir. Bir isteğin gidiş dönüş süresi 45 ms'dir ve istekler tek akışta sıralıdır.
- **DT4** — Kopyalama sunucu tarafındadır: çıkış ücreti doğmaz, istek ücreti doğar.

```js
// nesne/olcum-agi.mjs — bolgesel olcum agi KURGUDUR: nesne kumesi de ucret de modeldir.
// Butun ucretler kurgu "birim" cinsindendir; gercek bir saglayicinin fiyati degildir.
export const SAYAC = 4000, GUN = 310;             // kurgu ag: 4000 sayac, 310 gunluk gecmis
export const AILE = [
  { ad: "sayac-okumalari", adet: SAYAC * GUN, ort: 2400, yazim: "gunluk" },
  { ad: "fatura-belgeleri", adet: 86_000, ort: 380 * 1024, yazim: "aylik" },
  { ad: "saha-fotograflari", adet: 42_000, ort: Math.round(3.6 * 1024 * 1024), yazim: "bir kez" },
  { ad: "is-emri-kayitlari", adet: 310_000, ort: 11 * 1024, yazim: "gunluk" },
];
export const UCRET = {                            // kurgu birim: B
  saklama: 0.023,                                 // B / GiB / ay
  yazmaIstek: 0.0050 / 1000,                      // B / istek (koyma, kopyalama, listeleme)
  okumaIstek: 0.0004 / 1000,                      // B / istek (getirme, basliga bakma)
  cikisInternet: 0.085,                           // B / GiB
  cikisBolgelerArasi: 0.020,                      // B / GiB
};
export const SAYFA = 1000;                        // bir listeleme istegi en cok 1000 anahtar doner
export const TUR_MS = 45;                         // modelde bir istegin gidis donus suresi

export const GIB = (bayt) => bayt / 1024 ** 3;
export const toplamBayt = AILE.reduce((a, f) => a + f.adet * f.ort, 0);
export const toplamAdet = AILE.reduce((a, f) => a + f.adet, 0);
export const listeIstegi = (anahtar) => Math.ceil(anahtar / SAYFA);
```

#### Dosya Sistemiyle Kalem Kalem Fark

- **DT5** — Fatura belgelerinde ayda 4.300 düzeltme yapılır; her düzeltme belgeye 2 KiB ekler.
- **DT6** — Aralık isteği desteklenir: bir nesnenin yalnız istenen bayt aralığı okunabilir.

```js
// nesne/model-farki.mjs — dosya sistemi islemleri ile nesne deposu karsiliklari kalem kalem
import { AILE, UCRET, SAYFA, TUR_MS, GIB, toplamBayt, toplamAdet, listeIstegi } from "./olcum-agi.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
console.log(`kurgu kova: ${toplamAdet.toLocaleString("tr")} nesne, ${g(GIB(toplamBayt), 0, 1)} GiB, ` +
  `sayfa basina ${SAYFA} anahtar, modelde tur suresi ${TUR_MS} ms`);
console.log("\naile               |     adet |    GiB | liste istegi | liste suresi (sn)");
console.log("-------------------|----------|--------|--------------|------------------");
for (const f of AILE) {
  const li = listeIstegi(f.adet);
  console.log(`${f.ad.padEnd(18)} | ${s(f.adet, 8)} | ${g(GIB(f.adet * f.ort), 6, 1)} | ` +
    `${s(li, 12)} | ${g(li * TUR_MS / 1000, 17, 1)}`);
}

// Dort islem: dosya sisteminde tek cagri olan is, nesne deposunda kaca cikiyor.
const fatura = AILE[1], foto = AILE[2], sayac = AILE[0];
const DUZELTME = 4300, EK = 2 * 1024, ARALIK = 64 * 1024;
const ISLEM = [
  { ad: "dizin boyutunu ogren", fsCagri: 1, fsBayt: 0,
    noIstek: listeIstegi(sayac.adet), noBayt: 0 },
  { ad: "dizini yeniden adlandir", fsCagri: 1, fsBayt: 0,
    noIstek: listeIstegi(sayac.adet) + 2 * sayac.adet, noBayt: sayac.adet * sayac.ort },
  { ad: "dosyaya 2 KiB ekle", fsCagri: 1, fsBayt: EK,
    noIstek: 1, noBayt: fatura.ort },
  { ad: "aylik duzeltmeler", fsCagri: DUZELTME, fsBayt: DUZELTME * EK,
    noIstek: DUZELTME, noBayt: DUZELTME * fatura.ort },
  { ad: "64 KiB araligi oku", fsCagri: 1, fsBayt: ARALIK, noIstek: 1, noBayt: ARALIK },
  { ad: "tum fotografi oku", fsCagri: 1, fsBayt: foto.ort, noIstek: 1, noBayt: foto.ort },
];
console.log("\nislem                   | dosya sisteminde |    nesne deposunda | bayt buyutmesi");
console.log("                        | cagri /     bayt |   istek /      bayt |");
console.log("------------------------|------------------|--------------------|---------------");
for (const i of ISLEM) {
  const kat = i.fsBayt === 0 ? (i.noBayt === 0 ? "1x" : "olcusuz") : (i.noBayt / i.fsBayt).toFixed(1) + "x";
  console.log(`${i.ad.padEnd(23)} | ${s(i.fsCagri, 5)} / ${s(i.fsBayt, 8)} | ` +
    `${s(i.noIstek, 7)} / ${s(i.noBayt, 10)} | ${kat.padStart(14)}`);
}

const ad = ISLEM[1];
const istekUcret = ad.noIstek * UCRET.yazmaIstek;
console.log(`\nyeniden adlandirma: ${ad.noIstek.toLocaleString("tr")} istek = ${g(istekUcret, 0, 2)} birim ` +
  `(kurgu), tasinan ${g(GIB(ad.noBayt), 0, 2)} GiB; dosya sisteminde 1 cagri, 0 bayt.`);
const duz = ISLEM[3];
console.log(`aylik duzeltmeler: degisen ${g(duz.fsBayt / 1024 ** 2, 0, 1)} MiB, yazilan ` +
  `${g(GIB(duz.noBayt), 0, 2)} GiB; kismi guncelleme olmadigi icin fark ${(duz.noBayt / duz.fsBayt).toFixed(0)} kat.`);
console.log(`aralik okuma calisir: ${ARALIK / 1024} KiB istenince ${ARALIK / 1024} KiB cikiyor — ` +
  `kismi okuma var, kismi yazma yok.`);
```

```
kurgu kova: 1.678.000 nesne, 184.8 GiB, sayfa basina 1000 anahtar, modelde tur suresi 45 ms

aile               |     adet |    GiB | liste istegi | liste suresi (sn)
-------------------|----------|--------|--------------|------------------
sayac-okumalari    |  1240000 |    2.8 |         1240 |              55.8
fatura-belgeleri   |    86000 |   31.2 |           86 |               3.9
saha-fotograflari  |    42000 |  147.7 |           42 |               1.9
is-emri-kayitlari  |   310000 |    3.3 |          310 |              13.9

islem                   | dosya sisteminde |    nesne deposunda | bayt buyutmesi
                        | cagri /     bayt |   istek /      bayt |
------------------------|------------------|--------------------|---------------
dizin boyutunu ogren    |     1 /        0 |    1240 /          0 |             1x
dizini yeniden adlandir |     1 /        0 | 2481240 / 2976000000 |        olcusuz
dosyaya 2 KiB ekle      |     1 /     2048 |       1 /     389120 |         190.0x
aylik duzeltmeler       |  4300 /  8806400 |    4300 / 1673216000 |         190.0x
64 KiB araligi oku      |     1 /    65536 |       1 /      65536 |           1.0x
tum fotografi oku       |     1 /  3774874 |       1 /    3774874 |           1.0x

yeniden adlandirma: 2.481.240 istek = 12.41 birim (kurgu), tasinan 2.77 GiB; dosya sisteminde 1 cagri, 0 bayt.
aylik duzeltmeler: degisen 8.4 MiB, yazilan 1.56 GiB; kismi guncelleme olmadigi icin fark 190 kat.
aralik okuma calisir: 64 KiB istenince 64 KiB cikiyor — kismi okuma var, kismi yazma yok.
```

Tablo dört farkı birbirinden ayırıyor. Dizin boyutunu öğrenmek dosya sisteminde tek çağrıdır; nesne
deposunda 1.240 listeleme isteğidir ve modelde 55,8 saniye sürer — sıfır bayt aktarılarak. Sayaç
ailesi kovanın **baytının yüzde 1,5'ini** tutar ama listeleme isteklerinin çoğunu üretir: listeleme
bayta değil **anahtar sayısına** bağlıdır. Dizini yeniden adlandırmak dosya sisteminde tek çağrı ve
sıfır bayttır; nesne deposunda 2.481.240 istektir ve 2,77 GiB'i baştan sona taşır. Karşılığı yoktur,
katı yoktur — işlem türü değişmiştir.

Kısmi güncelleme farkı en sinsi olanıdır çünkü hata vermez, yalnız faturayı büyütür: 380 KiB'lik bir
belgeye 2 KiB eklemek belgenin tamamını yeniden yazar, 190 kat. Ayda 4.300 düzeltmede değişen 8,4
MiB, yazılan 1,56 GiB olur. Son iki satır dengeyi kuruyor: kısmi **okuma** vardır. 64 KiB'lik aralık
istendiğinde 64 KiB çıkar. Nesne deposu parça okumaya izin verir, parça yazmaya vermez; bu
asimetri, sık güncellenen küçük kayıtların nesne deposunda tutulmamasının tek cümlelik gerekçesidir.

#### Anahtar Düzeni Geri Alınamayan Kalemdir

Dizin olmadığı için erişim örüntüsünü belirleyen tek şey anahtarın **kendisidir**. Aynı veri iki
düzende tutulabilir ve ikisi de doğrudur; fark, hangi sorgunun önekle daralabildiğidir.

```js
// nesne/anahtar-duzeni.mjs — ayni veri, iki anahtar duzeni: sorgular kac listeleme istegi istiyor
import { SAYAC, GUN, AILE, UCRET, TUR_MS, GIB, listeIstegi } from "./olcum-agi.mjs";

const OKUMA = AILE[0], TOPLAM = OKUMA.adet;
// Onek agaci: bir sorgu ancak onekle daralabiliyorsa az anahtar okur, daralamiyorsa tam tarar.
const DUZEN = {
  "tarih-onde": { kalip: "sayac/<yil>/<ay>/<gun>/<sayac>.json", gun: SAYAC, sayac: TOPLAM },
  "sayac-onde": { kalip: "sayac/<sayac>/<yil>/<ay>/<gun>.json", gun: TOPLAM, sayac: GUN },
};
const SORGU = [
  { ad: "bir gunun tum okumalari", alan: "gun", aylik: 30 },
  { ad: "bir sayacin tum gecmisi", alan: "sayac", aylik: 900 },
];
const g = (x, n, d = 2) => x.toFixed(d).padStart(d === 0 ? n : n);
const s = (x, n) => String(x).padStart(n);

console.log(`${TOPLAM.toLocaleString("tr")} okuma nesnesi = ${SAYAC} sayac x ${GUN} gun. ` +
  `Veri ayni, degisen yalniz anahtarin ilk alani.`);
for (const [ad, d] of Object.entries(DUZEN)) console.log(`  ${ad.padEnd(11)} ${d.kalip}`);

console.log("\nsorgu                    | duzen       | okunan anahtar | liste istegi | sure (sn)");
console.log("-------------------------|-------------|----------------|--------------|----------");
const maliyet = {};
for (const q of SORGU)
  for (const [ad, d] of Object.entries(DUZEN)) {
    const anahtar = d[q.alan], li = listeIstegi(anahtar);
    maliyet[ad] = (maliyet[ad] ?? 0) + q.aylik * li;
    console.log(`${q.ad.padEnd(24)} | ${ad.padEnd(11)} | ${s(anahtar, 14)} | ` +
      `${s(li, 12)} | ${g(li * TUR_MS / 1000, 8, 1)}`);
  }

console.log("\naylik toplam (30 gun sorgusu + 900 sayac sorgusu):");
for (const [ad, istek] of Object.entries(maliyet))
  console.log(`  ${ad.padEnd(11)} ${s(istek.toLocaleString("tr"), 11)} liste istegi = ` +
    `${(istek * UCRET.yazmaIstek).toFixed(2).padStart(7)} birim (kurgu)`);
const [a, b] = Object.values(maliyet);
console.log(`  fark ${(Math.max(a, b) / Math.min(a, b)).toFixed(0)} kat; ikisi de dogru, ikisi de ayni veriyi tutuyor.`);

// Duzeni sonradan degistirmek: dizin yeniden adlandirma yok, her nesne kopyalanip silinir.
const gecis = listeIstegi(TOPLAM) + 2 * TOPLAM, bayt = TOPLAM * OKUMA.ort;
console.log(`\nduzeni degistirmenin bedeli: ${listeIstegi(TOPLAM)} listeleme + ${TOPLAM.toLocaleString("tr")} kopyalama + ` +
  `${TOPLAM.toLocaleString("tr")} silme = ${gecis.toLocaleString("tr")} istek`);
console.log(`  istek ucreti ${(gecis * UCRET.yazmaIstek).toFixed(2)} birim, tasinan ${GIB(bayt).toFixed(2)} GiB, ` +
  `modelde tek akista ${(gecis * TUR_MS / 3600000).toFixed(1)} saat`);
console.log(`  ayni bayt bolge disina cikarilsaydi: bolgeler arasi ${(GIB(bayt) * UCRET.cikisBolgelerArasi).toFixed(3)} birim, ` +
  `internete ${(GIB(bayt) * UCRET.cikisInternet).toFixed(3)} birim`);
console.log(`  gecis ucreti ${(gecis * UCRET.yazmaIstek / (GIB(bayt) * UCRET.saklama)).toFixed(0)} aylik saklama ucretine esit.`);
```

```
1.240.000 okuma nesnesi = 4000 sayac x 310 gun. Veri ayni, degisen yalniz anahtarin ilk alani.
  tarih-onde  sayac/<yil>/<ay>/<gun>/<sayac>.json
  sayac-onde  sayac/<sayac>/<yil>/<ay>/<gun>.json

sorgu                    | duzen       | okunan anahtar | liste istegi | sure (sn)
-------------------------|-------------|----------------|--------------|----------
bir gunun tum okumalari  | tarih-onde  |           4000 |            4 |      0.2
bir gunun tum okumalari  | sayac-onde  |        1240000 |         1240 |     55.8
bir sayacin tum gecmisi  | tarih-onde  |        1240000 |         1240 |     55.8
bir sayacin tum gecmisi  | sayac-onde  |            310 |            1 |      0.0

aylik toplam (30 gun sorgusu + 900 sayac sorgusu):
  tarih-onde    1.116.120 liste istegi =    5.58 birim (kurgu)
  sayac-onde       38.100 liste istegi =    0.19 birim (kurgu)
  fark 29 kat; ikisi de dogru, ikisi de ayni veriyi tutuyor.

duzeni degistirmenin bedeli: 1240 listeleme + 1.240.000 kopyalama + 1.240.000 silme = 2.481.240 istek
  istek ucreti 12.41 birim, tasinan 2.77 GiB, modelde tek akista 31.0 saat
  ayni bayt bolge disina cikarilsaydi: bolgeler arasi 0.055 birim, internete 0.236 birim
  gecis ucreti 195 aylik saklama ucretine esit.
```

İki düzen aynı baytı tutuyor, aynı nesneleri barındırıyor, aynı saklama ücretini ödüyor. Fark
sorgudadır: tarih önde olduğunda bir günün okumaları 4 istekle gelir, bir sayacın geçmişi 1.240
istekle taranır; sayaç önde olduğunda tam tersi olur. Bu iş yükünde ayda 900 sayaç sorgusu ve 30
günlük sorgu vardır, dolayısıyla yanlış düzen aylık listeleme isteğini 29 katına çıkarır.

Asıl kalem son bloktadır. Düzeni değiştirmek bir yapılandırma işi değildir: 2.481.240 istek, 2,77
GiB'in yeniden yazılması ve modelde tek akışta 31 saattir. Geçişin istek ücreti, aynı verinin **195
aylık saklama ücretine** eşittir — on altı yıllık saklama parası bir kerelik yeniden adlandırmaya
gider. **Anahtar düzeni bu kursun ilk geri alınamayan kalemidir:** teknik olarak dönülebilir,
pratikte veri taşımadan dönülemez. Çıkış tarafı ayrıca durur: geçiş bölge içinde kalırsa çıkış
ücreti doğmaz, aynı baytı bölge dışına taşımak 0,055 birim, internete indirmek 0,236 birim tutar.
Verinin girmesi ucuz, çıkması pahalıdır.

#### Devredilen Karar ve Elde Kalan

Nesne deposu kiralandığında disk yerleşimi, çoğaltma sayısı, bozulmuş bloğun onarımı, disk
değişimi ve dayanıklılık hedefi sağlayıcıya geçer. Bunlar geri alınmaz kararlar değildir, çünkü
zaten karar değildir: görünürlükleri yoktur, bir kadranı yoktur.

Elde kalanlar dörttür ve hepsi bu kursun ilerleyen derslerinde ölçülür: **anahtar düzeni** (bu
derste), **depolama sınıfı**, **sürümleme** ve **erişim kapsamı**. Dördünün ortak yanı, seçildikten
sonra veriyi taşımadan değiştirilememeleridir. Kova adı beşincisidir ve en serttir: ad alanı
paylaşımlıdır, ad sonradan değiştirilemez, değiştirmek yeni kova açıp her nesneyi kopyalamak
demektir — yukarıdaki 2.481.240 isteğin aynısı.

#### Özet

- Nesne deposu bir sözlüktür: kova bir ad alanı, anahtar düz bir dize, eğik çizgi yalnız önek
  sorgusunda anlamlıdır. Dizin, boş dizin ve dizin boyutu diye bir kavram yoktur.
- Dört fark sayıyla ayrılır: dizin boyutu 1 çağrı yerine 1.240 istek, yeniden adlandırma 1 çağrı
  yerine 2.481.240 istek, 2 KiB ekleme 190 kat yazma, aralık okuma ise birebir.
- Listeleme bayta değil anahtar sayısına bağlıdır: kovanın baytının yüzde 1,5'ini tutan sayaç
  ailesi, listeleme isteklerinin çoğunu üretir ve modelde tek tarama 55,8 saniye sürer.
- Anahtar düzeni erişim örüntüsünü sabitler: aynı veri iki düzende tutulduğunda aylık listeleme
  isteği 29 kat değişir, düzeni sonradan değiştirmek 195 aylık saklama ücreti tutar.
- Devredilen karar görünmez olanlardır (yerleşim, çoğaltma, onarım); elde kalanlar anahtar düzeni,
  depolama sınıfı, sürümleme ve erişim kapsamıdır — dördü de veri taşımadan geri alınamaz.

#### Sonraki Adım

Bu dersin bütün sayıları tek bir saklama ücretiyle çıktı: her nesne aynı orandan faturalandı. Oysa
kurgu kovanın içindeki dört aile birbirine hiç benzemiyor — sayaç okumaları günlük yazılıp günlük
okunuyor, fatura belgeleri ayda bir yazılıp yılda birkaç kez açılıyor, saha fotoğrafları bir kez
yazılıp neredeyse hiç okunmuyor. Sonraki ders bu farkı fiyat tarafına geçirir: erişim sıklığına göre
depolama sınıfları vardır, saklama ücreti düştükçe erişim ücreti yükselir. Ölçülecek üç şey var —
her sınıfın başabaş erişim sıklığı, seyrek erişilen veriyi sık sınıfta tutmanın bedeli ve sık
erişilen veriyi seyrek sınıfa atmanın bedeli.

### Depolama Sınıfları

Source: https://academia.sh/tr/kurslar/bulut-depolama/depolama-siniflari

Erişim sıklığına göre katmanların ölçülmesi: saklama ücretiyle erişim ücretinin ters yönde çalışması, başabaş erişim sıklığının nesne boyutuna göre taranması, erişim geçmişi üzerinde nesnelerin sınıflara dağıtılması ve yanlış sınıfın iki yönde de sayılması — seyrek veriyi sık sınıfta, sık veriyi arşivde tutmanın yıllık bedeli.

Önceki ders kurgu kovadaki dört aileyi tek bir saklama oranıyla faturalandırdı. Oysa aileler
birbirine benzemiyor: sayaç okumaları küçük ve çok sayıda, fatura belgeleri büyük ve seyrek okunan,
saha fotoğrafları bir kez yazılıp neredeyse hiç açılmayan kayıtlar. Nesne deposu bu farkı **depolama
sınıfı** (storage class) ile fiyat tarafına geçirir: aynı kovadaki nesneler farklı sınıflarda
tutulabilir ve sınıf nesne başına seçilir.

Sınıf bir kalite kadranı değildir. Dayanıklılık dört sınıfta da aynıdır; değişen tek şey ücretin
saklama ile erişim arasında nasıl bölündüğüdür. Bu yüzden "seyrek erişilen sınıf daha ucuzdur"
cümlesi karar taşımaz; karar taşıyan sayı **başabaş erişim sıklığıdır**.

- **DT7** — Dört sınıf ve ücretleri kurgudur; sınıflar yalnız erişim sıklığıyla anılır, ücretler
  kurgu **birim** cinsindendir.
- **DT8** — Erişim geçmişi karışım modelidir: sıcak pay ile sıcak ve soğuk yıllık ortalamalar
  modelde yazılıdır, üreteç modelin içindedir, tohum 40127'dir.
- **DT9** — Sınıf nesne başına seçilir; yıllık okuma sayısı yıl boyunca sabittir.

```js
// sinif/sinif-modeli.mjs — depolama siniflari ve erisim gecmisi MODELDIR. Ucretler kurgu birimdir,
// siniflar erisim sikligiyla anilir; hicbir ticari ad kullanilmaz.
export const SINIF = [                 // saklama: B/GiB/ay, istek ve gecis: B/istek, getirme: B/GiB
  { ad: "sik erisilen", saklama: 0.0230, istek: 0.00040 / 1000, getirme: 0.000, enAz: 0, gecis: 0.0050 / 1000 },
  { ad: "seyrek erisilen", saklama: 0.0125, istek: 0.00100 / 1000, getirme: 0.010, enAz: 30, gecis: 0.0100 / 1000 },
  { ad: "cok seyrek erisilen", saklama: 0.0040, istek: 0.00250 / 1000, getirme: 0.020, enAz: 90, gecis: 0.0250 / 1000 },
  { ad: "arsiv", saklama: 0.0010, istek: 0.00500 / 1000, getirme: 0.030, enAz: 180, gecis: 0.0500 / 1000 },
];
export const CIKIS_INTERNET = 0.085;   // B/GiB, kurgu

// Erisim gecmisi karisim modelidir: her ailenin bir sicak payi var, gerisi soguk.
export const AILE = [       // adet, ortalama boyut, sicak pay, sicak ve soguk yillik okuma ortalamasi
  { ad: "sayac-okumalari", adet: 1_240_000, ort: 2400, sicak: 0.06, sOrt: 60, cOrt: 0.4 },
  { ad: "fatura-belgeleri", adet: 86_000, ort: 380 * 1024, sicak: 0.15, sOrt: 26, cOrt: 0.8 },
  { ad: "saha-fotograflari", adet: 42_000, ort: Math.round(3.6 * 1024 * 1024), sicak: 0.03, sOrt: 40, cOrt: 0.15 },
  { ad: "is-emri-kayitlari", adet: 310_000, ort: 11 * 1024, sicak: 0.20, sOrt: 34, cOrt: 1.2 },
];
export const GIB = (bayt) => bayt / 1024 ** 3;
// Yillik ucret: saklama + okuma istekleri + geri getirilen bayt. Sinif degistirmek ayri ucrettir.
export const yillik = (s, bayt, okumaYil) =>
  12 * s.saklama * GIB(bayt) + okumaYil * (s.istek + GIB(bayt) * s.getirme);

export const TOHUM = 40127;            // ureteci kendimiz yaziyoruz, tohum gorunur: kurgudur
export function* erisim(aile) {        // her nesne icin yillik okuma sayisi (tam sayi)
  let x = (TOHUM ^ aile.adet) >>> 0;
  const s = () => (x = (Math.imul(x, 1664525) + 1013904223) >>> 0) / 4294967296;
  for (let i = 0; i < aile.adet; i++) {
    const ort = s() < aile.sicak ? aile.sOrt : aile.cOrt;
    yield Math.floor(-ort * Math.log(1 - s()));
  }
}
```

#### Başabaş Erişim Sıklığı

```js
// sinif/basabas.mjs — saklama ile erisim ucretleri ters yonde: basabas erisim sikligi taranir
import { SINIF, AILE, GIB, yillik } from "./sinif-modeli.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
console.log("sinif                | saklama | istek (1000'de) | getirme B/GiB | en az saklama");
console.log("---------------------|---------|-----------------|---------------|--------------");
for (const s of SINIF)
  console.log(`${s.ad.padEnd(20)} | ${g(s.saklama, 7, 4)} | ${g(s.istek * 1000, 15, 5)} | ` +
    `${g(s.getirme, 13, 3)} | ${String(s.enAz + " gun").padStart(13)}`);
console.log("Saklama asagi inerken istek ve getirme yukari cikiyor: cevrilecek tek yonlu kadran yok.");

// Basabas taramasi: yilda 0,1 okuma adimiyla, ucuz saklamali sinif nerede pahaliya donuyor.
const basabas = (ucuz, pahali, bayt) => {
  for (let k = 0; k <= 2000; k++) {
    const r = k / 10;
    if (yillik(ucuz, bayt, r) > yillik(pahali, bayt, r)) return r;
  }
  return null;
};
console.log("\nbasabas erisim sikligi (yilda okuma); ustunde ucuz saklamali sinif pahaliya doner:");
console.log("aile               | ort. boyut | seyrek>sik | cok seyrek>seyrek | arsiv>cok seyrek");
console.log("-------------------|------------|------------|-------------------|-----------------");
for (const f of AILE) {
  const c = [basabas(SINIF[1], SINIF[0], f.ort), basabas(SINIF[2], SINIF[1], f.ort),
    basabas(SINIF[3], SINIF[2], f.ort)];
  const boyut = f.ort < 1024 ** 2 ? (f.ort / 1024).toFixed(1) + " KiB" : (f.ort / 1024 ** 2).toFixed(1) + " MiB";
  console.log(`${f.ad.padEnd(18)} | ${boyut.padStart(10)} | ` +
    c.map((x, i) => x.toFixed(1).padStart([10, 17, 16][i])).join(" | "));
}
console.log("Kucuk nesnede basabas asagi iniyor: istek ucreti bayt ucretini bastiriyor ve");
console.log("ucuz saklama yalnizca cok dar bir siklik araliginda kazandiriyor.");

// Ayni aile, ayni bayt, iki farkli siklik: siralamanin tersine dondugu nokta.
const f = AILE[1], y = (r) => SINIF.map((s) => yillik(s, f.ort, r) * f.adet);
const [t0, t12] = [y(0), y(12)];
console.log(`\n${f.ad} (${GIB(f.adet * f.ort).toFixed(1)} GiB) yillik toplam, kurgu birim:`);
console.log(`  sifir okuma  : sik ${g(t0[0], 6)} | arsiv ${g(t0[3], 6)} -> arsiv ${(t0[0] / t0[3]).toFixed(0)} kat ucuz`);
console.log(`  yilda 12 okuma: sik ${g(t12[0], 6)} | arsiv ${g(t12[3], 6)} -> siralama tersine dondu`);
```

```
sinif                | saklama | istek (1000'de) | getirme B/GiB | en az saklama
---------------------|---------|-----------------|---------------|--------------
sik erisilen         |  0.0230 |         0.00040 |         0.000 |         0 gun
seyrek erisilen      |  0.0125 |         0.00100 |         0.010 |        30 gun
cok seyrek erisilen  |  0.0040 |         0.00250 |         0.020 |        90 gun
arsiv                |  0.0010 |         0.00500 |         0.030 |       180 gun
Saklama asagi inerken istek ve getirme yukari cikiyor: cevrilecek tek yonlu kadran yok.

basabas erisim sikligi (yilda okuma); ustunde ucuz saklamali sinif pahaliya doner:
aile               | ort. boyut | seyrek>sik | cok seyrek>seyrek | arsiv>cok seyrek
-------------------|------------|------------|-------------------|-----------------
sayac-okumalari    |    2.3 KiB |        0.5 |               0.2 |              0.1
fatura-belgeleri   |  380.0 KiB |       10.9 |               7.3 |              2.2
saha-fotograflari  |    3.6 MiB |       12.4 |               9.8 |              3.4
is-emri-kayitlari  |   11.0 KiB |        1.9 |               0.7 |              0.2
Kucuk nesnede basabas asagi iniyor: istek ucreti bayt ucretini bastiriyor ve
ucuz saklama yalnizca cok dar bir siklik araliginda kazandiriyor.

fatura-belgeleri (31.2 GiB) yillik toplam, kurgu birim:
  sifir okuma  : sik   8.60 | arsiv   0.37 -> arsiv 23 kat ucuz
  yilda 12 okuma: sik   9.01 | arsiv  16.75 -> siralama tersine dondu
```

Başabaş tablosu sınıf seçiminin **nesne boyutuna** bağlı olduğunu gösteriyor. 380 KiB'lik fatura
belgesi yılda 10,9 okumanın altında kalıyorsa seyrek sınıf kazandırır; 2,3 KiB'lik sayaç okuması
için aynı eşik 0,5'tir — yılda bir kez okunan bir kaydı ucuz saklamalı sınıfa koymak zarardır.
Nedeni sabit istek ücretidir: küçük nesnede erişimin bedeli baytla değil **istek sayısıyla**
ölçülür. Son iki satır aynı şeyi bir aile üzerinde gösteriyor.

#### Erişim Geçmişi Üzerinde Dağıtım

- **DT10** — Sınıf değiştirmek bir geçiş isteğidir, ayrı ücretlidir ve en az saklama süresi geçişte
  başlar.
- **DT11** — Getirme ücreti çıkış ücretinden ayrıdır; ikisi aynı bayt için birlikte ödenir.
- **DT12** — Yılda 24'ten çok okunan nesne modelde "sıcak" sayılır.

```js
// sinif/dagitim.mjs — erisim gecmisi uzerinde siniflar dagitilir; yanlis sinif iki yonde sayilir
import { SINIF, AILE, CIKIS_INTERNET, GIB, yillik, TOHUM, erisim } from "./sinif-modeli.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const enUcuz = (bayt, r) => {
  const t = SINIF.map((s) => yillik(s, bayt, r));
  return t.indexOf(Math.min(...t));
};
// Tek gecis: her ailenin erisim gecmisi taranir, ozetler ve strateji toplamlari birlikte cikar.
const OZET = [], STRATEJI = { "hepsi sik": 0, "hepsi seyrek": 0, "hepsi arsiv": 0, "aileye gore": 0, "nesne basina": 0 };
let hicOkunmayan = 0, hicOkunmayanBayt = 0, hicOkunmayanFazla = 0;
let sicakArsiv = 0, sicakArsivOkuma = 0, sicakArsivBayt = 0, sicakArsivFazla = 0, getirilenBayt = 0;

for (const f of AILE) {
  let okumaTop = 0, sifir = 0, dagilim = [0, 0, 0, 0], nesneBasina = 0;
  const aileTop = SINIF.map(() => 0), esik = 24;   // yilda 24'ten cok okunan nesne sicak sayilir
  for (const r of erisim(f)) {
    okumaTop += r;
    if (r === 0) sifir++;
    const i = enUcuz(f.ort, r);
    dagilim[i]++;
    nesneBasina += yillik(SINIF[i], f.ort, r);
    for (let k = 0; k < SINIF.length; k++) aileTop[k] += yillik(SINIF[k], f.ort, r);
    if (r === 0) {                        // hic okunmayan nesne sik sinifta tutulursa
      hicOkunmayan++; hicOkunmayanBayt += f.ort;
      hicOkunmayanFazla += yillik(SINIF[0], f.ort, 0) - yillik(SINIF[3], f.ort, 0);
    } else if (r > esik) {                // sicak nesne arsive atilirsa
      sicakArsiv++; sicakArsivOkuma += r; sicakArsivBayt += f.ort; getirilenBayt += r * f.ort;
      sicakArsivFazla += yillik(SINIF[3], f.ort, r) - yillik(SINIF[0], f.ort, r);
    }
  }
  const en = aileTop.indexOf(Math.min(...aileTop));
  STRATEJI["hepsi sik"] += aileTop[0]; STRATEJI["hepsi seyrek"] += aileTop[1];
  STRATEJI["hepsi arsiv"] += aileTop[3]; STRATEJI["aileye gore"] += aileTop[en];
  STRATEJI["nesne basina"] += nesneBasina;
  OZET.push({ f, okumaTop, sifir, dagilim });
}

console.log(`erisim gecmisi modeldir; uretec bu dosyada, tohum ${TOHUM}. Yillik okuma sayilari:`);
console.log("\naile               | hic okunmayan | ort. okuma/yil | nesne basina en ucuz sinif dagilimi");
console.log("                   |               |                |     sik | seyrek | cok seyrek |  arsiv");
console.log("-------------------|---------------|----------------|---------|--------|------------|-------");
for (const o of OZET)
  console.log(`${o.f.ad.padEnd(18)} | %${g(100 * o.sifir / o.f.adet, 12, 1)} | ${g(o.okumaTop / o.f.adet, 14, 2)} | ` +
    o.dagilim.map((x, i) => String(x).padStart([7, 6, 10, 6][i])).join(" | "));

console.log("\nstrateji     | yillik toplam | en iyiye gore fazla | fazlanin orani");
console.log("-------------|---------------|---------------------|---------------");
const enIyi = STRATEJI["nesne basina"];
for (const [ad, t] of Object.entries(STRATEJI))
  console.log(`${ad.padEnd(12)} | ${g(t, 13)} | ${g(t - enIyi, 19)} | %${g(100 * (t - enIyi) / enIyi, 13, 1)}`);

console.log("\nyanlis sinifin iki yonu:");
console.log(`  seyrek veri sik sinifta: ${hicOkunmayan.toLocaleString("tr")} nesne, ` +
  `${g(GIB(hicOkunmayanBayt), 0, 1)} GiB hic okunmuyor; arsiv yerine sik sinifta tutmak ` +
  `yilda ${g(hicOkunmayanFazla, 0, 2)} birim fazla.`);
console.log(`  sik veri arsiv sinifinda: ${sicakArsiv.toLocaleString("tr")} nesne, ` +
  `${g(GIB(sicakArsivBayt), 0, 1)} GiB, yilda ${sicakArsivOkuma.toLocaleString("tr")} okuma; ` +
  `arsivde tutmak yilda ${g(sicakArsivFazla, 0, 2)} birim fazla.`);
console.log(`  bu okumalarda getirilen ${g(GIB(getirilenBayt), 0, 1)} GiB internete de cikiyorsa cikis ucreti ` +
  `ayrica ${g(GIB(getirilenBayt) * CIKIS_INTERNET, 0, 2)} birim: getirme ucreti cikisin yerine gecmez, ustune biner.`);

// Sinif degistirmek geri alinabilir, bedava degil: en az saklama suresi tasiyor.
const f = AILE[1], N = 12_000, GUN = 8, seyrek = SINIF[1];
const gecisUcret = 2 * N * seyrek.gecis;
const enAzBorc = N * seyrek.saklama * GIB(f.ort) * (seyrek.enAz / 30);
const getirmeUcret = N * GIB(f.ort) * seyrek.getirme;
const kazanc = N * (SINIF[0].saklama - seyrek.saklama) * GIB(f.ort) * (GUN / 30);
console.log(`\n${N.toLocaleString("tr")} fatura belgesi seyrek sinifa tasindi, ${GUN}. gun sicak oldugu anlasildi, geri alindi:`);
console.log(`  iki yonlu gecis istegi ${g(gecisUcret, 0, 3)} | en az ${seyrek.enAz} gun saklama borcu ${g(enAzBorc, 0, 3)} | ` +
  `geri getirme ${g(getirmeUcret, 0, 3)}`);
console.log(`  toplam ${g(gecisUcret + enAzBorc + getirmeUcret, 0, 3)} birim; ${GUN} gunde kazanilan ${g(kazanc, 0, 3)} birim; ` +
  `net ${g(gecisUcret + enAzBorc + getirmeUcret - kazanc, 0, 3)} birim zarar.`);
console.log(`  karar geri alindi, ucreti geri alinmadi: en az saklama borcu nesne silinse de duruyor.`);
```

```
erisim gecmisi modeldir; uretec bu dosyada, tohum 40127. Yillik okuma sayilari:

aile               | hic okunmayan | ort. okuma/yil | nesne basina en ucuz sinif dagilimi
                   |               |                |     sik | seyrek | cok seyrek |  arsiv
-------------------|---------------|----------------|---------|--------|------------|-------
sayac-okumalari    | %        86.4 |           3.66 |  168911 |      0 |          0 | 1071089
fatura-belgeleri   | %        61.4 |           4.16 |    8311 |   1095 |       3774 |  72820
saha-fotograflari  | %        97.0 |           1.22 |     920 |     64 |        142 |  40874
is-emri-kayitlari  | %        45.7 |           7.34 |  105257 |  63012 |          0 | 141731

strateji     | yillik toplam | en iyiye gore fazla | fazlanin orani
-------------|---------------|---------------------|---------------
hepsi sik    |         53.91 |               45.78 | %        563.0
hepsi seyrek |         38.39 |               30.26 | %        372.2
hepsi arsiv  |         48.65 |               40.52 | %        498.4
aileye gore  |         16.80 |                8.67 | %        106.6
nesne basina |          8.13 |                0.00 | %          0.0

yanlis sinifin iki yonu:
  seyrek veri sik sinifta: 1.306.318 nesne, 166.2 GiB hic okunmuyor; arsiv yerine sik sinifta tutmak yilda 43.87 birim fazla.
  sik veri arsiv sinifinda: 84.485 nesne, 4.6 GiB, yilda 6.192.838 okuma; arsivde tutmak yilda 35.56 birim fazla.
  bu okumalarda getirilen 276.3 GiB internete de cikiyorsa cikis ucreti ayrica 23.48 birim: getirme ucreti cikisin yerine gecmez, ustune biner.

12.000 fatura belgesi seyrek sinifa tasindi, 8. gun sicak oldugu anlasildi, geri alindi:
  iki yonlu gecis istegi 0.240 | en az 30 gun saklama borcu 0.054 | geri getirme 0.043
  toplam 0.338 birim; 8 gunde kazanilan 0.012 birim; net 0.326 birim zarar.
  karar geri alindi, ucreti geri alinmadi: en az saklama borcu nesne silinse de duruyor.
```

#### Yanlış Sınıfın İki Yönü

Dağılım sütunu başabaş tablosunu doğruluyor: sayaç okumalarında ara sınıflar sıfır nesne alıyor,
1.240.000 kayıt sık erişilen ile arşiv arasında ikiye bölünüyor. Nesne büyüdükçe ara sınıfların
aralığı açılıyor ve fatura belgelerinde dördü de kullanılıyor.

Strateji tablosu tek sınıflı üç yaklaşımın da kaybettiğini gösteriyor. Hepsini sık sınıfta tutmak
en iyi dağıtımın 6,6 katıdır. Hepsini arşive atmak, sezgiye aykırı biçimde, hepsini seyrek sınıfta
tutmaktan pahalıdır — 48,65'e karşı 38,39 — çünkü sıcak nesnelerin getirme ücreti kazanılanı yutar.
Aile düzeyinde tek sınıf toplamı 16,80'e indirir ama hâlâ yüzde 106 fazladır; kazancın yarısı
**aile içindeki** sıcak-soğuk ayrımındadır.

İki yön ayrı sayılıyor. Hiç okunmayan 1.306.318 nesne — 166,2 GiB — sık sınıfta tutulduğunda yılda
43,87 birim fazla ödetir; bu yön sessizdir, hiçbir hata üretmez. Ters yön daha az veri, daha çok
para tutar: yılda 24'ten çok okunan 84.485 nesne yalnız 4,6 GiB'dir ama arşivde yılda 35,56 birim
fazla ödetir. Getirilen 276,3 GiB internete de çıkıyorsa 23,48 birimlik çıkış ücreti bunun
**üstüne** biner.

#### Geri Alınan Karar, Geri Alınmayan Ücret

Depolama sınıfı, anahtar düzeninin aksine geri alınabilir görünür: bir istek nesneyi başka sınıfa
taşır. Son blok bedelini sayıyor. 12.000 fatura belgesi seyrek sınıfa taşınıyor, sekizinci gün geri
alınıyor: 0,240 geçiş isteği, 0,054 en az saklama borcu, 0,043 geri getirme, toplam 0,338 birim.
Sekiz günde kazanılan 0,012 birimdir; net zarar kazancın yirmi yedi katıdır.

**Geri alınamayan kalem en az saklama borcudur.** Nesne sınıfa girdiği anda o sınıfın süresi taahhüt
edilir; nesne taşınsa da silinse de borç durur. Devredilen taraf sabittir: dayanıklılık, çoğaltma ve
yerleşim dört sınıfta da sağlayıcıdadır.

#### Özet

- Sınıf bir kalite kadranı değil takastır: saklama düştükçe istek ve getirme yükselir, dayanıklılık
  değişmez.
- Başabaş sıklık nesne boyutuna bağlıdır: 380 KiB'lik belgede yılda 10,9 okuma, 2,3 KiB'lik kayıtta
  0,5 okuma. Küçük nesnelerde ara sınıflar hiç kazanmaz.
- Nesne başına seçim 8,13 birim tutar; hepsini sık sınıfta tutmak 53,91, hepsini arşive atmak 48,65
  birimdir — arşiv otomatik olarak ucuz değildir.
- Yanlış sınıf iki yönde ödetir: hiç okunmayan 166,2 GiB sık sınıfta yılda 43,87 birim, çok okunan
  4,6 GiB arşivde 35,56 birim fazla. Getirme ücreti çıkışın üstüne biner.
- Sınıf kararı geri alınabilir, ücreti alınamaz: sekiz günde dönülen geçiş kazancın yirmi yedi katı
  zarar bırakır; en az saklama borcu nesne silinse de durur.

#### Sonraki Adım

Bu dersin sınıf dağıtımı elle yapıldı: her nesnenin yıllık okuma sayısı bilindi ve en ucuz sınıf
seçildi. Gerçek bir kovada bu bilgi önceden yoktur; her nesneyi tek tek taşıyan bir betik, taşıdığı
isteklerin ücretiyle kazancı götürür. Sonraki ders kararı depoya bırakır: yaşam döngüsü kuralı
nesneleri yaşlarına göre sınıf değiştirir ve siler. Ölçülecek üç şey var — kural olmadan biriken
bayt, kuralla geçen ve silinen nesne sayısı, erken geçişin geri getirme bedeli. Sürümleme de aynı
derste açılır: açıldığında silme işleminin gerçekten silmediği sayıyla gösterilir.

### Sürümleme ve Yaşam Döngüsü Kuralları

Source: https://academia.sh/tr/kurslar/bulut-depolama/surumleme-ve-yasam-dongusu-kurallari

Otomatik geçişin ve silmenin 36 aylık bir nesne yaşamı üzerinde koşturulması: kural olmadan biriken bayt, kuralla geçen ve silinen nesne sayısı, geçiş ücretinin küçük nesnede kazancı yutması, erken geçişin geri getirme bedeli ve sürümleme açıldığında silinen nesnenin gerçekten silinmemesi.

Önceki dersin sınıf dağıtımı bir varsayıma dayanıyordu: her nesnenin yıllık okuma sayısı bilinir ve
doğru sınıfa elle konur. Milyonlarca nesnede bu ne bilinir ne de elle yapılır. Nesne deposu bunun
için **yaşam döngüsü kuralı** (lifecycle rule) sunar: bir önek altındaki nesneler belirli bir yaşa
geldiğinde sınıf değiştirir ya da silinir. Kural erişime değil **yaşa** bakar ve bu ayrım ölçülebilir
bir bedel taşır.

Aynı ders sürümlemeyi de açar. Sürümleme (versioning) bu modelde kova düzeyinde bir anahtardır
ve açıldıktan sonra geriye dönüşü yoktur; gerçek sağlayıcılarda anahtarın düzeyi ve
kapatılabilirliği değişir, biriken eski sürümler ise her yerde kalır. İkisi birlikte ölçülür:
sürümleme baytı büyütür, yaşam döngüsü kuralı küçültür.

- **DT13** — 36 aylık nesne yaşamı modeldir: aylık üretim, ortalama boyut ve okumanın yaşla
  yarılanma süresi modelde yazılıdır. Rastgelelik yoktur, her sayı kohorttan çıkar.
- **DT14** — Geçiş bir istektir, nesne başına ücretlidir; en az saklama süresi sınıfa girişte başlar.
- **DT15** — Kural yalnız yaşa bakar; bir nesnenin gerçekte okunup okunmadığını görmez.

```js
// yasam/model.mjs — 36 aylik nesne yasami MODELDIR: rastgelelik yok, her sayi kohorttan cikar.
// Ucretler kurgu birimdir; siniflar yalnizca erisim sikligiyla anilir.
export const AY = 36;
export const SINIF = {                 // saklama B/GiB/ay, istek ve gecis B/istek, getirme B/GiB
  sik: { saklama: 0.0230, istek: 0.00040 / 1000, getirme: 0.000, enAz: 0, gecis: 0.0050 / 1000 },
  seyrek: { saklama: 0.0125, istek: 0.00100 / 1000, getirme: 0.010, enAz: 1, gecis: 0.0100 / 1000 },
  arsiv: { saklama: 0.0010, istek: 0.00500 / 1000, getirme: 0.030, enAz: 6, gecis: 0.0500 / 1000 },
};
// aylikUretim: her ay yaratilan nesne; taban: yasi sifirken aylik okuma; yariOmur: okumanin yarilanma ayi
export const AILE = [
  { ad: "sayac-okumalari", uretim: 120_000, ort: 2400, taban: 3.0, yari: 1.5 },
  { ad: "fatura-belgeleri", uretim: 7_200, ort: 380 * 1024, taban: 2.2, yari: 4 },
  { ad: "saha-fotograflari", uretim: 3_500, ort: Math.round(3.6 * 1024 * 1024), taban: 0.9, yari: 2 },
  { ad: "is-emri-kayitlari", uretim: 26_000, ort: 11 * 1024, taban: 4.0, yari: 3 },
];
export const GIB = (bayt) => bayt / 1024 ** 3;
export const okuma = (f, yas) => f.taban * Math.pow(0.5, yas / f.yari);
// Kural: yas (ay) esiginde sinif degistir; sil esiginde nesneyi kaldir.
export const KURAL = {
  "kural yok": { gecis: [], sil: null },
  ilimli: { gecis: [[3, "seyrek"], [12, "arsiv"]], sil: 30 },
  agresif: { gecis: [[1, "seyrek"], [3, "arsiv"]], sil: 7 },
  "erken-arsiv": { gecis: [[1, "arsiv"]], sil: null },
};
export const sinifi = (k, yas) => {    // yasa gore icinde bulunulan sinif ve o sinifa girilen yas
  let ad = "sik", giris = 0;
  for (const [esik, s] of k.gecis) if (yas >= esik) { ad = s; giris = esik; }
  return { s: SINIF[ad], ad, giris };
};
```

#### Kural Yaşa Bakar, Erişime Değil

```js
// yasam/kural.mjs — yasam dongusu kurallari 36 ay boyunca kohortlar uzerinde kosturulur
import { AY, SINIF, AILE, KURAL, GIB, okuma, sinifi } from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
const bos = () => ({ saklama: 0, istek: 0, getirme: 0, gecisUcret: 0, gecisAdet: 0, borc: 0, silinen: 0, kalanB: 0 });
const kosu = (k, aile) => {                           // tek ailenin 36 aylik yasami
  const r = bos();
  for (let dogum = 0; dogum < AY; dogum++)            // her ay dogan kohort, ay ay yasatilir
    for (let ay = dogum; ay < AY; ay++) {
      const yas = ay - dogum;
      if (k.sil !== null && yas >= k.sil) {           // silme aninda en az saklama borcu cikar
        if (yas === k.sil) {
          const c = sinifi(k, yas - 1);
          r.borc += aile.uretim * Math.max(0, c.s.enAz - (yas - c.giris)) * c.s.saklama * GIB(aile.ort);
          r.silinen += aile.uretim;
        }
        continue;
      }
      const c = sinifi(k, yas), oku = okuma(aile, yas);
      if (k.gecis.some(([e]) => e === yas)) { r.gecisAdet += aile.uretim; r.gecisUcret += aile.uretim * c.s.gecis; }
      r.saklama += aile.uretim * GIB(aile.ort) * c.s.saklama;
      r.istek += aile.uretim * oku * c.s.istek;
      r.getirme += aile.uretim * oku * GIB(aile.ort) * c.s.getirme;
      if (ay === AY - 1) r.kalanB += aile.uretim * aile.ort;
    }
  r.toplam = r.saklama + r.istek + r.getirme + r.gecisUcret + r.borc;
  return r;
};

const T = {};                                          // T[kural][aile] ve T[kural].hepsi
for (const [ad, k] of Object.entries(KURAL)) {
  T[ad] = { hepsi: bos() };
  for (const f of AILE) {
    const r = T[ad][f.ad] = kosu(k, f);
    for (const a of ["saklama", "istek", "getirme", "gecisUcret", "gecisAdet", "borc", "silinen", "kalanB", "toplam"])
      T[ad].hepsi[a] = (T[ad].hepsi[a] ?? 0) + r[a];
  }
}
console.log(`${AILE.reduce((a, f) => a + f.uretim, 0).toLocaleString("tr")} nesne/ay, ${AY} ay; ` +
  `okuma yasla yariliyor, rastgelelik yok. Ucretler kurgu birim.`);
console.log("\nkural       |    GiB | gecis istegi | saklama | getirme | gecis ucreti | toplam");
console.log("------------|--------|--------------|---------|---------|--------------|-------");
for (const [ad, r] of Object.entries(T).map(([a, x]) => [a, x.hepsi]))
  console.log(`${ad.padEnd(11)} | ${g(GIB(r.kalanB), 6, 1)} | ${s(r.gecisAdet.toLocaleString("tr"), 12)} | ` +
    `${g(r.saklama, 7)} | ${g(r.getirme, 7)} | ${g(r.gecisUcret, 12)} | ${g(r.toplam, 6)}`);

console.log("\n36 aylik toplam, aile aile (kurgu birim):");
console.log("aile               |" + Object.keys(KURAL).map((a) => a.padStart(12)).join(" |") + " | en ucuz kural");
console.log("-------------------|" + Object.keys(KURAL).map(() => "-".repeat(13)).join("|") + "|--------------");
for (const f of AILE) {
  const v = Object.keys(KURAL).map((a) => T[a][f.ad].toplam);
  console.log(`${f.ad.padEnd(18)} |` + v.map((x) => g(x, 12)).join(" |") +
    ` | ${Object.keys(KURAL)[v.indexOf(Math.min(...v))]}`);
}

const [yok, ili, agr, erk] = ["kural yok", "ilimli", "agresif", "erken-arsiv"].map((a) => T[a]);
console.log(`\nkural yokken 36. ayda ${GIB(yok.hepsi.kalanB).toFixed(1)} GiB birikiyor, hicbir nesne silinmiyor. Ilimli kural ` +
  `${ili.hepsi.silinen.toLocaleString("tr")} nesne silip saklamayi ` +
  `${(100 * (1 - ili.hepsi.saklama / yok.hepsi.saklama)).toFixed(1)} puan indiriyor, ama gecis ucreti toplami ` +
  `${(ili.hepsi.toplam / yok.hepsi.toplam).toFixed(2)} katina cikariyor.`);
const karma = AILE.reduce((a, f) => a + Math.min(...Object.keys(KURAL).map((k) => T[k][f.ad].toplam)), 0);
console.log(`aileye gore secilen karma kural ${karma.toFixed(2)} birim: tek kuralin en iyisinin ` +
  `(${Math.min(...Object.values(T).map((x) => x.hepsi.toplam)).toFixed(2)}) altinda. Kural nesne turune gore yazilir.`);
console.log(`erken gecisin bedeli getirme sutununda: ilimli ${ili.hepsi.getirme.toFixed(2)}, erken-arsiv ` +
  `${erk.hepsi.getirme.toFixed(2)} birim (${(erk.hepsi.getirme / ili.hepsi.getirme).toFixed(1)} kat); erken-arsiv saklamada ` +
  `${(ili.hepsi.saklama - erk.hepsi.saklama).toFixed(2)} kazanip getirme ve istekte ` +
  `${(erk.hepsi.getirme + erk.hepsi.istek - ili.hepsi.getirme - ili.hepsi.istek).toFixed(2)} birim kaybediyor.`);
console.log(`agresif kural 7. ayda siliyor, arsivin en az ${SINIF.arsiv.enAz} aylik borcu var: ` +
  `${agr.hepsi.borc.toFixed(2)} birim artik var olmayan nesneler icin odeniyor.`);
```

```
156.700 nesne/ay, 36 ay; okuma yasla yariliyor, rastgelelik yok. Ucretler kurgu birim.

kural       |    GiB | gecis istegi | saklama | getirme | gecis ucreti | toplam
------------|--------|--------------|---------|---------|--------------|-------
kural yok   |  556.4 |            0 |  236.74 |    0.00 |         0.00 | 257.94
ilimli      |  463.6 |    8.931.900 |   92.06 |   13.05 |       239.75 | 379.90
agresif     |  108.2 |   10.655.600 |   28.07 |   30.28 |       313.40 | 460.64
erken-arsiv |  556.4 |    5.484.500 |   22.53 |   58.48 |       274.22 | 540.24

36 aylik toplam, aile aile (kurgu birim):
aile               |   kural yok |      ilimli |     agresif | erken-arsiv | en ucuz kural
-------------------|-------------|-------------|-------------|-------------|--------------
sayac-okumalari    |       17.46 |      203.62 |      292.04 |      318.98 | kural yok
fatura-belgeleri   |       41.19 |       37.32 |       38.33 |       56.13 | ilimli
saha-fotograflari  |      188.63 |       83.22 |       44.92 |       51.49 | agresif
is-emri-kayitlari  |       10.66 |       55.74 |       85.34 |      113.64 | kural yok

kural yokken 36. ayda 556.4 GiB birikiyor, hicbir nesne silinmiyor. Ilimli kural 940.200 nesne silip saklamayi 61.1 puan indiriyor, ama gecis ucreti toplami 1.47 katina cikariyor.
aileye gore secilen karma kural 110.36 birim: tek kuralin en iyisinin (257.94) altinda. Kural nesne turune gore yazilir.
erken gecisin bedeli getirme sutununda: ilimli 13.05, erken-arsiv 58.48 birim (4.5 kat); erken-arsiv saklamada 69.52 kazanip getirme ve istekte 195.39 birim kaybediyor.
agresif kural 7. ayda siliyor, arsivin en az 6 aylik borcu var: 0.90 birim artik var olmayan nesneler icin odeniyor.
```

Kural olmadan otuz altı ayda 556,4 GiB birikiyor ve hiçbir nesne silinmiyor; saklama kalemi
toplamın neredeyse tamamıdır. Ilımlı kural bu kalemi yüzde 61,1 indirir, 940.200 nesne siler, baytı
463,6 GiB'e çeker — ve toplamı **artırır**. Nedeni geçiş ücreti sütunundadır: 8.931.900 geçiş isteği
239,75 birim tutar, saklamada kazanılanın üstündedir.

Aile tablosu kuralın nerede kazandığını gösteriyor. Saha fotoğraflarında agresif kural toplamı
188,63'ten 44,92 birime iner: nesne büyüktür, geçiş isteğinin taşıdığı bayt çoktur. Sayaç
okumalarında aynı kural 17,46'dan 292,04 birime çıkar; 2,3 KiB'lik bir nesne için geçiş isteği o
nesnenin yıllarca saklanmasından pahalıdır. Kural bu yüzden **önek düzeyinde** yazılır: karma kural
110,36 birimle tek kuralın en iyisinin yarısından azdır.

Erken geçiş üçüncü kalemi açıyor. Erken-arşiv kuralı saklamada 69,52 birim kazanır, getirme ve
istekte 195,39 birim kaybeder: birinci ayında hâlâ okunan bir nesne arşive gönderildiğinde her okuma
geri getirme ücreti doğurur. Agresif kuralın yedinci ayda sildiği nesneler ise arşivin altı aylık
süresini doldurmaz; 0,90 birim artık var olmayan nesneler için ödenir.

#### Sürümleme: Silmenin Silmediği Yer

- **DT16** — Güncelleme oranı modeldir: nesne yaşlandıkça üzerine yazma seyrekleşir ve her üzerine
  yazma bir eski sürüm bırakır.
- **DT17** — Sürümleme kova düzeyindedir; açıkken silme bir silme işareti koyar ve geçerli sürümü
  eski sürüme çevirir.
- **DT18** — Eski sürümler ancak ayrı bir yaşam döngüsü kuralıyla temizlenir.

```js
// yasam/surumleme.mjs — surumleme acikken silmenin ve kapatmanin ne yaptigi sayilir (MODEL)
import { AY, SINIF, AILE, GIB } from "./model.mjs";

// Guncelleme MODELI: nesne yaslandikca uzerine yazma seyreliyor. Her uzerine yazma bir eski surum birakir.
const GUNCELLEME = { "is-emri-kayitlari": { taban: 0.85, yari: 2 }, "fatura-belgeleri": { taban: 0.30, yari: 3 } };
const SIL_AYI = 30, SURUM_OMRU = 3, KAPATMA_AYI = 24;    // eski surum kurali: 3 ay sonra temizle
const secili = AILE.filter((f) => GUNCELLEME[f.ad]);
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);

// Her ay: gecerli nesne bayti, uretilen eski surum bayti (uretildigi aya gore) toplanir.
const kosu = ({ surumleme, surumKurali, kapatma }) => {
  const r = { gecerli: 0, gecerliB: 0, surum: 0, surumB: 0, saklama: 0, silinen: 0, bosalan: 0 };
  for (const f of secili) {
    const u = GUNCELLEME[f.ad], uretilen = [];           // uretilen[m] = o ay dogan eski surum sayisi
    for (let m = 0; m < AY; m++) uretilen.push(0);
    for (let m = 0; m < AY; m++) {
      let gecerli = 0;
      for (let dogum = 0; dogum <= m; dogum++) {
        const yas = m - dogum;
        if (yas >= SIL_AYI) {                            // silme: surumleme kapaliysa bayt gider
          if (yas === SIL_AYI) {
            r.silinen += f.uretim;
            if (surumleme && !(kapatma && m >= KAPATMA_AYI)) uretilen[m] += f.uretim;
            else r.bosalan += f.uretim * f.ort;
          }
          continue;
        }
        gecerli += f.uretim;
        const yazma = f.uretim * u.taban * Math.pow(0.5, yas / u.yari);
        if (surumleme && !(kapatma && m >= KAPATMA_AYI)) uretilen[m] += yazma;
      }
      let surum = 0;                                     // o ay ayakta olan eski surumler
      for (let k = 0; k <= m; k++) if (!surumKurali || m - k < SURUM_OMRU) surum += uretilen[k];
      r.saklama += GIB(f.ort) * (gecerli + surum) * SINIF.sik.saklama;
      if (m === AY - 1) {
        r.gecerli += gecerli; r.gecerliB += gecerli * f.ort;
        r.surum += surum; r.surumB += surum * f.ort;
      }
    }
  }
  return r;
};

const D = {
  "surumleme kapali": kosu({ surumleme: false }),
  "surumleme acik": kosu({ surumleme: true }),
  "acik + surum kurali": kosu({ surumleme: true, surumKurali: true }),
  "24. ayda kapatildi": kosu({ surumleme: true, kapatma: true }),
};
console.log(`${secili.map((f) => f.ad).join(" + ")}; ${AY} ay, ${SIL_AYI}. ayda silme, ` +
  `eski surum kurali ${SURUM_OMRU} ay. Guncelleme orani modelde.`);
console.log("\ndurum               | gecerli nesne | eski surum | eski surum GiB | 36 aylik saklama");
console.log("--------------------|---------------|------------|----------------|-----------------");
for (const [ad, r] of Object.entries(D))
  console.log(`${ad.padEnd(19)} | ${s(Math.round(r.gecerli).toLocaleString("tr"), 13)} | ` +
    `${s(Math.round(r.surum).toLocaleString("tr"), 10)} | ${g(GIB(r.surumB), 14, 1)} | ${g(r.saklama, 16)}`);

const [kap, acik, kural, kapatma] = Object.values(D);
console.log(`\nsilme deneyi: ${Math.round(kap.silinen).toLocaleString("tr")} nesne silindi. Bosalan bayt — ` +
  `surumleme kapali ${GIB(kap.bosalan).toFixed(1)} GiB, acik ${GIB(acik.bosalan).toFixed(1)} GiB.`);
console.log(`  eski surum / gecerli veri orani ${(acik.surumB / acik.gecerliB).toFixed(2)}; surum kurali ` +
  `${GIB(acik.surumB - kural.surumB).toFixed(1)} GiB geri getiriyor.`);
console.log(`kapatma deneyi: ${KAPATMA_AYI}. ayda kapatildi. Yeni surum uretilmiyor, birikmis ` +
  `${GIB(kapatma.surumB).toFixed(1)} GiB duruyor ve ${AY - KAPATMA_AYI} ay daha ucretlendiriliyor;`);
console.log(`  kapatmadan sonraki silmeler ${GIB(kapatma.bosalan).toFixed(1)} GiB bosaltiyor, oncekiler icin ` +
  `yapilabilecek tek sey ayri bir surum kurali yazmaktir.`);
```

```
fatura-belgeleri + is-emri-kayitlari; 36 ay, 30. ayda silme, eski surum kurali 3 ay. Guncelleme orani modelde.

durum               | gecerli nesne | eski surum | eski surum GiB | 36 aylik saklama
--------------------|---------------|------------|----------------|-----------------
surumleme kapali    |       996.000 |          0 |            0.0 |            42.75
surumleme acik      |       996.000 |  3.070.001 |          165.9 |           102.12
acik + surum kurali |       996.000 |    357.335 |           22.4 |            53.68
24. ayda kapatildi  |       996.000 |  1.839.941 |           93.6 |            92.51

silme deneyi: 199.200 nesne silindi. Bosalan bayt — surumleme kapali 17.3 GiB, acik 0.0 GiB.
  eski surum / gecerli veri orani 1.92; surum kurali 143.5 GiB geri getiriyor.
kapatma deneyi: 24. ayda kapatildi. Yeni surum uretilmiyor, birikmis 93.6 GiB duruyor ve 12 ay daha ucretlendiriliyor;
  kapatmadan sonraki silmeler 17.3 GiB bosaltiyor, oncekiler icin yapilabilecek tek sey ayri bir surum kurali yazmaktir.
```

Geçerli nesne sayısı dört satırda da aynı: 996.000. Uygulamanın gördüğü veri değişmez, değişen
faturadır. Sürümleme açıldığında 3.070.001 eski sürüm birikir, 165,9 GiB tutar — geçerli verinin
1,92 katı, üzerine yazmanın kendi ürettiği bayt.

Silme deneyi kavramı yerine oturtuyor. 199.200 nesne siliniyor: sürümleme kapalıyken 17,3 GiB
boşalır, açıkken **0,0 GiB**. Silme başarılıdır, nesne listede görünmez — ve bayt yerinde durur,
çünkü silinen nesne bir eski sürüme dönüşmüştür. Eski sürümler için ayrı bir kural yazıldığında
143,5 GiB geri gelir, saklama 102,12'den 53,68 birime iner; o kural yazılmadıkça sürümleme açmak
silmeyi sessizce anlamsızlaştırır.

Kapatma deneyi geri alınamazlığı gösteriyor. Yirmi dördüncü ayda sürümleme kapatılır: yeni sürüm
üretilmez, sonraki silmeler yeniden bayt boşaltır, ama birikmiş 93,6 GiB durur ve on iki ay daha
ücretlendirilir. **Sürümleme bu kursun ikinci geri alınamayan kalemidir:** açmak bir anahtardır,
kapatmak aynı anahtar değildir. Sağlayıcı yalnız kuralı **işletir**; eşikler, silme ve eski sürüm
ömrü elde kalır.

#### Özet

- Kural yaşa bakar, erişime bakmaz: erken-arşiv saklamada 69,52 birim kazanıp getirme ve istekte
  195,39 birim kaybeder, geri getirme kalemi 4,5 katına çıkar.
- Geçiş ücreti nesne başınadır: ılımlı kural saklamayı yüzde 61,1 indirse de toplamı 1,47 katına
  çıkarır. Kural kova düzeyinde değil önek düzeyinde yazılır.
- Karma kural 110,36 birimdir, tek kuralın en iyisi 257,94: saha fotoğraflarında agresif kural
  kazandırır, sayaç okumalarında aynı kural on yedi kat zarar ettirir.
- Erken silme en az saklama borcu doğurur: yedinci ayda silinen nesneler için 0,90 birim ödenir,
  nesne artık yoktur.
- Sürümleme açıkken 199.200 nesne silindiğinde boşalan 0,0 GiB'dir, 165,9 GiB eski sürüm birikir.
  Kapatmak birikmiş sürümleri temizlemez, yalnız yenisini üretmez.

#### Sonraki Adım

Bu üç ders tek bir varsayımı paylaşıyor: veri bütün hâlinde yazılıp bütün hâlinde okunuyor. Kurgu
ölçüm ağının bir bölümü böyle çalışmaz — toplayıcı süreç bir veritabanı dosyasına saniyede yüzlerce
küçük yazma yapar ve her yazma dosyanın ortasındaki birkaç kilobaytı değiştirir. Birinci derste
ölçülen 190 kat yazma büyütmesi bu iş yükünü nesne deposunda tek başına imkânsız kılar. Sonraki
ders veriyi bayt bloğu olarak sunan türe geçer. Ölçülecek üç şey var — birim türü ve boyutunun
verdiği giriş çıkış bütçesi, iş yükü profillerinin bu bütçeyi doyurduğu nokta ve boyutla başarımın
birbirine bağlı olmasının açtığı tasarım tuzağı.

### Blok Depolama

Source: https://academia.sh/tr/kurslar/bulut-depolama/blok-depolama

Birim türü ve boyutunun bir giriş çıkış bütçesi vermesi: iş yükü profillerinin bu bütçeye uygulanması, doyma noktasının ve atıl bütçenin sayılması, boyutla başarımın birbirine bağlı olmasının açtığı tasarım tuzağı, birimin küçültülememesi ve tek örneğe bağlı olması.

Önceki üç ders veriyi bütün hâlinde yazılıp okunan bir nesne olarak ele aldı. Kurgu ölçüm ağının
toplayıcı süreci böyle çalışmaz: bir veritabanı dosyasının ortasındaki birkaç kilobaytı saniyede
binlerce kez değiştirir. Birinci derste ölçülen 190 kat yazma büyütmesi bu iş yükünü nesne deposunda
imkânsız kılar. Gereken şey, veriyi adreslenebilir **bloklar** hâlinde sunan ve üzerine bir dosya
sistemi kurulabilen bir katmandır.

Bu türde kiralanan şey bir **birim**dir (volume). Birim bu modelde tek bir örneğe takılır,
işletim sistemi onu disk olarak görür. Kimi sağlayıcı belirli birim türlerini birden çok örneğe
bağlamaya izin verir, ama o düzen küme farkında bir dosya sistemi ister. Devredilen taraf
geniştir: fiziksel diskler, çoğaltma, bozuk sektör onarımı ve disk
değişimi sağlayıcıdadır. Elde kalan taraf iki sayıya iner — **tür** ve **boyut**. Bu ikisinin bir
üçüncüyü, giriş çıkış bütçesini belirlemesi dersin bütün ölçümlerinin kaynağıdır.

- **DT19** — Birim türü kataloğu ve ücretler kurgudur; türler yetenekleriyle anılır.
- **DT20** — Bir giriş çıkış işlemi, birimin saydığı **taneye** yuvarlanır: 16 KiB tane sayan türde
  1 MiB'lik okuma 64 tane, 1 MiB tane sayan türde 1 tane tüketir.
- **DT21** — İş yükü profilleri modeldir: işlem boyutu, işlem sayısı ve veri boyutu modelde
  yazılıdır.

```js
// blok/model.mjs — blok birimi katalogu ve is yuku profilleri MODELDIR. Ucretler kurgu birimdir;
// hicbir urun ya da birim ailesi adi kullanilmaz, turler yetenekleriyle anilir.
export const TUR = {   // birimKib: bu turun giris cikis islemini saydigi tane; ayar: is/s basina ucret
  "genel amacli": { birimKib: 16, gibBasi: 3, taban: 100, ustIs: 16000, mibGib: 0.25, ustMib: 250, ucret: 0.080, ayar: 0 },
  "basarim ayarli": { birimKib: 16, gibBasi: 500, taban: 100, ustIs: 64000, mibGib: 1.00, ustMib: 1000, ucret: 0.125, ayar: 0.006 },
  "verim ayarli": { birimKib: 1024, gibBasi: 0.5, taban: 12, ustIs: 500, mibGib: 0.40, ustMib: 1000, ucret: 0.045, ayar: 0 },
  soguk: { birimKib: 1024, gibBasi: 0.2, taban: 12, ustIs: 250, mibGib: 0.12, ustMib: 250, ucret: 0.015, ayar: 0 },
};
// Is yuku profilleri: islem boyutu, saniyedeki islem, uzerinde durdugu veri.
export const YUK = [
  { ad: "sayac yazma", kib: 16, islem: 4200, veriGib: 200, cins: "rastgele kucuk yazma" },
  { ad: "is emri sorgusu", kib: 8, islem: 900, veriGib: 60, cins: "rastgele kucuk okuma" },
  { ad: "fatura uretimi", kib: 1024, islem: 180, veriGib: 400, cins: "sirali buyuk okuma" },
  { ad: "foto yukleme", kib: 4096, islem: 25, veriGib: 1200, cins: "sirali buyuk yazma" },
];
// Bir islem, turun saydigi taneye yuvarlanir: 16 KiB'lik yazma 1024 KiB'lik tanede de 1 tane yer.
export const tane = (y, t) => Math.ceil(y.kib / t.birimKib);
export const tuketilenIs = (y, t) => y.islem * tane(y, t);
export const tuketilenMib = (y, t) => tuketilenIs(y, t) * t.birimKib / 1024;
export const butce = (t, gib) => ({
  is: Math.min(t.ustIs, Math.max(t.taban, Math.round(t.gibBasi * gib))),
  mib: Math.min(t.ustMib, t.mibGib * gib),
});
export const ucret = (t, gib, ayarliIs = 0) => t.ucret * gib + t.ayar * ayarliIs;
```

#### Tür ve Boyut Bir Bütçe Verir

```js
// blok/butce.mjs — birim turu ve boyutu bir butce verir; is yukleri bu butceye uygulanir
import { TUR, YUK, tane, tuketilenIs, tuketilenMib, butce, ucret } from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
console.log("is yuku          | cins                 | islem boyutu | islem/s | ham MiB/s | veri GiB");
console.log("-----------------|----------------------|--------------|---------|-----------|---------");
for (const y of YUK)
  console.log(`${y.ad.padEnd(16)} | ${y.cins.padEnd(20)} | ${s(y.kib + " KiB", 12)} | ${s(y.islem, 7)} | ` +
    `${g(y.islem * y.kib / 1024, 9, 1)} | ${s(y.veriGib, 8)}`);

const gen = TUR["genel amacli"];
console.log("\nveri boyutu kadar genel amacli birim alinirsa (dogal secim), tane 16 KiB:");
console.log("is yuku          | butce is/s | tuketilen | doluluk | butce MiB/s | tuketilen | doluluk | doyan eksen");
console.log("-----------------|------------|-----------|---------|-------------|-----------|---------|------------");
for (const y of YUK) {
  const b = butce(gen, y.veriGib), dIs = tuketilenIs(y, gen) / b.is, dMib = tuketilenMib(y, gen) / b.mib;
  console.log(`${y.ad.padEnd(16)} | ${s(b.is, 10)} | ${s(tuketilenIs(y, gen), 9)} | %${g(100 * dIs, 6, 1)} | ` +
    `${g(b.mib, 11, 1)} | ${g(tuketilenMib(y, gen), 9, 1)} | %${g(100 * dMib, 6, 1)} | ` +
    `${(dIs >= dMib ? "is/s" : "MiB/s").padStart(11)}`);
}
const foto = YUK[3], bf = butce(gen, foto.veriGib);
console.log(`atil butce: ${foto.ad} is/s ekseninde doyarken MiB/s butcesinin ` +
  `%${(100 * (1 - tuketilenMib(foto, gen) / bf.mib)).toFixed(1)}'i kullanilmiyor. Ayrica 8 KiB'lik okuma 16 KiB tane`);
console.log(`tuketiyor: is emri sorgusunun ham ${(YUK[1].islem * YUK[1].kib / 1024).toFixed(1)} MiB/s'i butcede ` +
  `${tuketilenMib(YUK[1], gen).toFixed(1)} MiB/s yaziliyor.`);

console.log("\nis yukunu karsilamak icin gereken en kucuk boyut ve aylik ucret (kurgu birim):");
console.log("is yuku          | tur             | tane/islem | gereken GiB | atil GiB | aylik ucret");
console.log("-----------------|-----------------|------------|-------------|----------|------------");
const enUcuz = {};
for (const y of YUK)
  for (const [ad, t] of Object.entries(TUR)) {
    let boyut = null;
    for (let gib = y.veriGib; gib <= 65536; gib += 4) {          // butce yetene kadar boyut buyutulur
      const b = butce(t, gib);
      if (b.is >= tuketilenIs(y, t) && b.mib >= tuketilenMib(y, t)) { boyut = gib; break; }
    }
    if (ad === "basarim ayarli" && tuketilenMib(y, t) <= t.ustMib && tuketilenIs(y, t) <= t.ustIs) boyut = y.veriGib;
    if (boyut === null) {
      console.log(`${y.ad.padEnd(16)} | ${ad.padEnd(15)} | ${s(tane(y, t), 10)} | ${"karsilanamaz".padStart(11)} | ` +
        `${"-".padStart(8)} | ${"-".padStart(11)}`);
      continue;
    }
    const u = ucret(t, boyut, ad === "basarim ayarli" ? tuketilenIs(y, t) : 0);
    if (!enUcuz[y.ad] || u < enUcuz[y.ad].u) enUcuz[y.ad] = { ad, u, boyut };
    console.log(`${y.ad.padEnd(16)} | ${ad.padEnd(15)} | ${s(tane(y, t), 10)} | ${s(boyut, 11)} | ` +
      `${s(boyut - y.veriGib, 8)} | ${g(u, 11)}`);
  }
console.log("\nen ucuz secim: " + YUK.map((y) => `${y.ad} -> ${enUcuz[y.ad].ad} ${enUcuz[y.ad].boyut} GiB ` +
  `(${enUcuz[y.ad].u.toFixed(2)})`).join("; "));
```

```
is yuku          | cins                 | islem boyutu | islem/s | ham MiB/s | veri GiB
-----------------|----------------------|--------------|---------|-----------|---------
sayac yazma      | rastgele kucuk yazma |       16 KiB |    4200 |      65.6 |      200
is emri sorgusu  | rastgele kucuk okuma |        8 KiB |     900 |       7.0 |       60
fatura uretimi   | sirali buyuk okuma   |     1024 KiB |     180 |     180.0 |      400
foto yukleme     | sirali buyuk yazma   |     4096 KiB |      25 |     100.0 |     1200

veri boyutu kadar genel amacli birim alinirsa (dogal secim), tane 16 KiB:
is yuku          | butce is/s | tuketilen | doluluk | butce MiB/s | tuketilen | doluluk | doyan eksen
-----------------|------------|-----------|---------|-------------|-----------|---------|------------
sayac yazma      |        600 |      4200 | % 700.0 |        50.0 |      65.6 | % 131.3 |        is/s
is emri sorgusu  |        180 |       900 | % 500.0 |        15.0 |      14.1 | %  93.8 |        is/s
fatura uretimi   |       1200 |     11520 | % 960.0 |       100.0 |     180.0 | % 180.0 |        is/s
foto yukleme     |       3600 |      6400 | % 177.8 |       250.0 |     100.0 | %  40.0 |        is/s
atil butce: foto yukleme is/s ekseninde doyarken MiB/s butcesinin %60.0'i kullanilmiyor. Ayrica 8 KiB'lik okuma 16 KiB tane
tuketiyor: is emri sorgusunun ham 7.0 MiB/s'i butcede 14.1 MiB/s yaziliyor.

is yukunu karsilamak icin gereken en kucuk boyut ve aylik ucret (kurgu birim):
is yuku          | tur             | tane/islem | gereken GiB | atil GiB | aylik ucret
-----------------|-----------------|------------|-------------|----------|------------
sayac yazma      | genel amacli    |          1 |        1400 |     1200 |      112.00
sayac yazma      | basarim ayarli  |          1 |         200 |        0 |       50.20
sayac yazma      | verim ayarli    |          1 | karsilanamaz |        - |           -
sayac yazma      | soguk           |          1 | karsilanamaz |        - |           -
is emri sorgusu  | genel amacli    |          1 |         300 |      240 |       24.00
is emri sorgusu  | basarim ayarli  |          1 |          60 |        0 |       12.90
is emri sorgusu  | verim ayarli    |          1 | karsilanamaz |        - |           -
is emri sorgusu  | soguk           |          1 | karsilanamaz |        - |           -
fatura uretimi   | genel amacli    |         64 |        3840 |     3440 |      307.20
fatura uretimi   | basarim ayarli  |         64 |         400 |        0 |      119.12
fatura uretimi   | verim ayarli    |          1 |         452 |       52 |       20.34
fatura uretimi   | soguk           |          1 |        1500 |     1100 |       22.50
foto yukleme     | genel amacli    |        256 |        2136 |      936 |      170.88
foto yukleme     | basarim ayarli  |        256 |        1200 |        0 |      188.40
foto yukleme     | verim ayarli    |          4 |        1200 |        0 |       54.00
foto yukleme     | soguk           |          4 |        1200 |        0 |       18.00

en ucuz secim: sayac yazma -> basarim ayarli 200 GiB (50.20); is emri sorgusu -> basarim ayarli 60 GiB (12.90); fatura uretimi -> verim ayarli 452 GiB (20.34); foto yukleme -> soguk 1200 GiB (18.00)
```

İkinci tablo doyma noktalarını veriyor. Veri boyutu kadar birim almak — en doğal seçim — dört iş
yükünün dördünde de yetmiyor: doluluk yüzde 177,8 ile yüzde 960 arasında. Doyan eksen dördünde de
iş/s'dir, ama nedenleri farklıdır. Sayaç yazma gerçekten çok işlem yapar; fatura üretimi saniyede
yalnız 180 işlem yapar, her işlemi 64 tane tükettiği için bütçede 11.520 iş/s yazılır. **Tane boyutu,
iş yükünün bütçedeki görüntüsünü değiştirir.**

Atıl bütçe aynı tablonun diğer yüzüdür. Foto yükleme iş/s ekseninde doyarken MiB/s bütçesinin yüzde
60'ı hiç harcanmaz. Ters yönde de kayıp vardır: 8 KiB'lik iş emri okuması 16 KiB'lik taneyi tümüyle
tüketir, ham 7,0 MiB/s bütçede 14,1 MiB/s yazılır — işlem boyutunun tane boyutundan küçük olmasının
doğrudan sonucu.

Üçüncü tablo tür seçimini bir hesaba indiriyor. Sıralı büyük okuma 1 MiB tane sayan türlerde 15 kat
ucuza gelir: fatura üretimi genel amaçlı birimde 307,20, verim ayarlı birimde 20,34 birim tutar. Aynı
türler rastgele küçük yazmayı ise **karşılayamaz** — 16 KiB'lik yazma 1 MiB'lik taneyi harcar, 4.200
işlem/s 4.200 MiB/s tüketim yazar. Yanlış tür burada pahalı değil, imkânsızdır.

#### Boyutla Başarımın Bağlı Olması

- **DT22** — Başarım ayarlı türde iş/s ayrıca ücretlendirilir; diğer türlerde bütçe yalnız boyuta
  bağlıdır.
- **DT23** — Birim büyütülebilir, küçültülemez; kopyalama hızı modelde 250 MiB/s'dir.
- **DT24** — Birim tek örneğe ve tek bölgeye bağlıdır; anlık görüntü sıkışma oranı 0,55'tir.

```js
// blok/tuzak.mjs — boyut ile basarimin bagli olmasi, kucultememe ve tek ornege baglilik sayilir
import { TUR, YUK, tuketilenIs, butce, ucret } from "./model.mjs";

const gen = TUR["genel amacli"], sayac = YUK[0];
const CIKIS = { bolgelerArasi: 0.020, internet: 0.085 };
const SIKISMA = 0.55, HIZ_MIB = 250, BAGLAMA_SN = 40, TOPLAYICI = 12, YAZAR = 1;
const g = (x, d = 2) => x.toFixed(d);
const gerekenBoyut = (isS) => {                       // butce yetene kadar boyut buyutulur
  for (let gib = 4; gib <= 65536; gib += 4) if (butce(gen, gib).is >= isS) return gib;
};
const ILK = gerekenBoyut(tuketilenIs(sayac, gen)), DUSEN = 900, YENI = gerekenBoyut(DUSEN);
console.log(`${sayac.ad}: veri ${sayac.veriGib} GiB, gereken ${tuketilenIs(sayac, gen)} is/s.`);
console.log(`  genel amacli birimde is/s boyuta bagli oldugu icin ${ILK} GiB alinmali: ` +
  `${ILK - sayac.veriGib} GiB veri icin degil, butce icin duruyor (aylik ${g(ucret(gen, ILK))} birim).`);
console.log(`  ayni butce basarim ayarli turde ${sayac.veriGib} GiB ile aliniyor: aylik ` +
  `${g(ucret(TUR["basarim ayarli"], sayac.veriGib, tuketilenIs(sayac, gen)))} birim.`);

console.log(`\nis yuku ${tuketilenIs(sayac, gen)} is/s'den ${DUSEN} is/s'ye dustu; artik ${YENI} GiB yeterli.`);
console.log(`  buyutme serbest: ${ILK} GiB birim veri tasimadan buyutulebilir.`);
console.log(`  kuculme yok: ${YENI} GiB'lik yeni birim acilir, ${sayac.veriGib} GiB kopyalanir, baglanti degistirilir.`);
const kopyaSn = sayac.veriGib * 1024 / HIZ_MIB;
console.log(`  kopyalama ${g(kopyaSn / 60, 1)} dk (${HIZ_MIB} MiB/s), gecis boyunca iki birim birden faturalanir: ` +
  `${g(ucret(gen, ILK) + ucret(gen, YENI))} birim/ay.`);
console.log(`  kucultulemedigi icin odenen fark: aylik ${g(ucret(gen, ILK) - ucret(gen, YENI))}, ` +
  `yillik ${g(12 * (ucret(gen, ILK) - ucret(gen, YENI)))} birim.`);

const anlik = sayac.veriGib * SIKISMA;
console.log(`\nbirim tek ornege ve tek bolgeye baglidir: ${TOPLAYICI} toplayici ornekten ayni anda ${YAZAR} tanesi yazabilir.`);
console.log(`  baska ornege vermek sokup takmaktir; modelde baglama ${BAGLAMA_SN} sn, bu sure boyunca yazar yok.`);
console.log(`  baska bolgeye tasimak anlik goruntu ister: ${g(anlik, 1)} GiB (sikisma ${SIKISMA}); ` +
  `bolgeler arasi ${g(anlik * CIKIS.bolgelerArasi, 2)}, internete ${g(anlik * CIKIS.internet, 2)} birim cikis.`);
console.log(`  bolge ici anlik goruntu cikis ucreti dogurmaz; birimi bolgeden cikarmak dogurur.`);
```

```
sayac yazma: veri 200 GiB, gereken 4200 is/s.
  genel amacli birimde is/s boyuta bagli oldugu icin 1400 GiB alinmali: 1200 GiB veri icin degil, butce icin duruyor (aylik 112.00 birim).
  ayni butce basarim ayarli turde 200 GiB ile aliniyor: aylik 50.20 birim.

is yuku 4200 is/s'den 900 is/s'ye dustu; artik 300 GiB yeterli.
  buyutme serbest: 1400 GiB birim veri tasimadan buyutulebilir.
  kuculme yok: 300 GiB'lik yeni birim acilir, 200 GiB kopyalanir, baglanti degistirilir.
  kopyalama 13.7 dk (250 MiB/s), gecis boyunca iki birim birden faturalanir: 136.00 birim/ay.
  kucultulemedigi icin odenen fark: aylik 88.00, yillik 1056.00 birim.

birim tek ornege ve tek bolgeye baglidir: 12 toplayici ornekten ayni anda 1 tanesi yazabilir.
  baska ornege vermek sokup takmaktir; modelde baglama 40 sn, bu sure boyunca yazar yok.
  baska bolgeye tasimak anlik goruntu ister: 110.0 GiB (sikisma 0.55); bolgeler arasi 2.20, internete 9.35 birim cikis.
  bolge ici anlik goruntu cikis ucreti dogurmaz; birimi bolgeden cikarmak dogurur.
```

Tuzak ilk satırlarda duruyor. Genel amaçlı türde iş/s boyuta bağlı olduğu için 200 GiB'lik veri
1.400 GiB'lik birim ister: 1.200 GiB, veri için değil **bütçe için** durur. Aynı bütçe, iş/s'yi
ayrıca satan türde 200 GiB ile 50,20 birime alınır — kapasiteyi başarım için satın almak, boş baytı
her ay yeniden ödemektir.

İkinci blok geri alınamayan kalemi veriyor. İş yükü 4.200 iş/s'den 900'e düştüğünde 300 GiB
yeterlidir, ama **birim küçültülemez**. Büyütmek veri taşımadan yapılır; küçültmek yeni birim açmak,
200 GiB kopyalamak, bağlantıyı değiştirmektir — modelde 13,7 dakika, geçiş boyunca çift
faturalandırma ve yılda 1.056 birim fazla ödeme. Boyut tek yönlü bir kadrandır.

Üçüncü blok türün kendi sınırını yazıyor. Birim tek örneğe bağlıdır: on iki toplayıcı örnekten aynı
anda yalnız biri yazabilir; başka bir örneğe vermek sökme ve takma işidir ve modelde kırk saniye
boyunca hiçbir yazar yoktur. Birim tek bölgeye de bağlıdır, taşınması anlık görüntü ister — 110 GiB,
bölgeler arası 2,20, internete 9,35 birim. Bölge içinde kalan anlık görüntü çıkış ücreti doğurmaz.

#### Özet

- Tür ve boyut birlikte bir giriş çıkış bütçesi verir; bütçe iş/s ve MiB/s eksenlerinde tükenir ve
  iş yükü hangisini önce doldurursa orada doyar.
- İşlem, birimin saydığı taneye yuvarlanır: 1 MiB'lik okuma 16 KiB tanede 64 tane tüketir; 8 KiB'lik
  okumanın ham 7,0 MiB/s'i bütçede 14,1 MiB/s görünür.
- Atıl bütçe ölçülür: foto yükleme iş/s ekseninde doyarken MiB/s bütçesinin yüzde 60'ı kullanılmaz.
  Yanlış tür kimi zaman pahalı değil imkânsızdır.
- Boyutla başarımın bağlı olması tuzaktır: 200 GiB veri için 1.400 GiB birim alınır, 1.200 GiB bütçe
  için durur. Aynı bütçe iş/s'yi ayrıca satan türde 112,00 yerine 50,20 birimdir.
- Geri alınamayan kalem boyuttur: birim büyütülebilir, küçültülemez. Küçültme yeni birim, 13,7
  dakikalık kopyalama ve çift faturalandırma demektir.

#### Sonraki Adım

Son blok bir kapı bıraktı: on iki toplayıcı örnekten aynı anda yalnız biri yazabiliyor. Kurgu ölçüm
ağında bu doğrudan bir engeldir — saha ekipleri iş emri eklerini aynı dizine bırakır, fatura üretimi
aynı dizinden okur ve hepsi ayrı örneklerde koşar. Blok birimi bunu karşılayamaz, nesne deposu ise
dizin ve kilit sunmaz. Sonraki ders üçüncü türü ölçer: aynı veriyi birden çok örneğin aynı anda
bağladığı paylaşımlı dosya sistemi. Ölçülecek üç şey var — çok yazarlı erişimin üç türde nasıl
değiştiği, kilidin ne kadar beklettiği ve paylaşımlı dosya sisteminin hangi iş yükünde hiçbir şey
kazandırmadığı.

### Dosya Depolama

Source: https://academia.sh/tr/kurslar/bulut-depolama/dosya-depolama

Paylaşımlı dosya sisteminin çok yazarlı erişimde ölçülmesi: aynı verinin nesne, blok ve paylaşımlı dosya olarak tutulup kaç örneğin aynı anda yazabildiğinin, kilidin nasıl çalıştığının, gecikmenin ve aylık ücretin sayılması; paylaşımlı dosya sisteminin kazandırmadığı durumun adıyla yazılması ve erişim protokolünün geri alınamayan kalem olarak çıkarılması.

Önceki ders bir kapıyla bitti: blok birimi tek örneğe bağlıdır ve on iki toplayıcı örnekten aynı
anda yalnız biri yazabilir. Kurgu ölçüm ağında bu bir ayrıntı değil doğrudan engeldir — saha ekipleri
iş emri eklerini aynı dosyalara bırakır, fatura üretimi aynı dizinden okur ve bunların hepsi ayrı
örneklerde koşar. Nesne deposu birden çok yazarı kabul eder ama kilit ve kısmi güncelleme sunmaz;
blok birimi ikisini de sunar ama tek yazara izin verir.

Üçüncü tür bu boşluğu doldurur: **paylaşımlı dosya sistemi**. Ağ üzerinden bağlanır, birden çok
örnek aynı anda takar, tam bir dosya sistemi arayüzü sunar — dizin, yeniden adlandırma, kısmi yazma
ve bayt aralığı kilidi. Ölçülecek şey bunun ne kadarının gerçekten kazanç olduğudur: aynı veri üç
türde de tutulabilir ve üçünün farkı yalnız çok yazarlı erişimde görünür.

- **DT25** — Kurgu iş yükü: on iki saha örneği, saniyede 340 ek, her ek 2 KiB, 4.800 etkin iş emri
  dosyası. Yazmaların hangi dosyaya düştüğü modeldeki üreteçle belirlenir, tohum 71549'dur.
- **DT26** — Gecikmeler modeldir: nesne deposu isteği 25 ms, blok birimi 0,6 ms, paylaşımlı dosya
  sistemi 2,5 ms; uzak örnekten tek yazara ağ turu 0,4 ms.
- **DT27** — Nesne deposunda oku-değiştir-yaz penceresi 50 ms'dir; aynı dosyaya bu pencere içinde
  gelen ikinci yazma birincisini ezer.

```js
// dosya/model.mjs — uc depolama turu, cok yazarli is yuku ve ucretler MODELDIR. Ucretler kurgu
// birimdir; turler urun adiyla degil erisim bicimiyle anilir.
export const ORNEK = 12, YAZMA_S = 340, EK_KIB = 2, DOSYA_KIB = 11, AKTIF = 4800;
export const AY_SN = 2_592_000;                    // 30 gunluk ay, saniye
export const TUR = {
  "nesne deposu": { yazar: ORNEK, kilit: "yok", gecikmeMs: 25, saklama: 0.023, istek: 0.0050 / 1000, verim: 0 },
  "blok birimi": { yazar: 1, kilit: "tek yazar", gecikmeMs: 0.6, saklama: 0.080, istek: 0, verim: 0 },
  "paylasimli dosya": { yazar: ORNEK, kilit: "bayt araligi", gecikmeMs: 2.5, saklama: 0.300, istek: 0, verim: 0.60 },
};
export const AG_TURU_MS = 0.4;                     // uzak ornekten tek yazara giden tur
export const CAKISMA_MS = 50;                      // nesne deposunda oku-degistir-yaz penceresi
export const GIB = (bayt) => bayt / 1024 ** 3;

// Yazmalarin hangi dosyaya dustugu MODELDIR: uretec burada, tohum gorunur. Dagilim carpiktir.
export const TOHUM = 71549;
export function* yazmalar(adet) {
  let x = TOHUM >>> 0;
  const u = () => (x = (Math.imul(x, 1664525) + 1013904223) >>> 0) / 4294967296;
  for (let i = 0; i < adet; i++)
    yield { t: (i / YAZMA_S) * 1000, dosya: Math.floor(AKTIF * Math.pow(u(), 3)) };
}
// Tek sunucuda kuyruk: sabit hizmet suresiyle ortalama bekleme (yogunluk p, hizmet S).
export const bekleme = (p, S) => (p >= 1 ? Infinity : (p / (2 * (1 - p))) * S);
```

#### Aynı Veri, Üç Tür, Çok Yazar

```js
// dosya/cok-yazar.mjs — ayni veri uc turde: kac yazar, kilit nasil, gecikme ve ucret ne
import { ORNEK, YAZMA_S, EK_KIB, DOSYA_KIB, AKTIF, AY_SN, TUR, AG_TURU_MS, CAKISMA_MS, GIB, TOHUM, yazmalar, bekleme }
  from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
const SURE_SN = 60, ADET = YAZMA_S * SURE_SN;

// 1) Nesne deposu: kilit yok. Ayni dosyaya CAKISMA_MS icinde gelen ikinci yazma oncekini eziyor.
const sonYazma = new Map();
let kayip = 0, enSicak = 0;
const sayac = new Map();
for (const y of yazmalar(ADET)) {
  const onceki = sonYazma.get(y.dosya);
  if (onceki !== undefined && y.t - onceki < CAKISMA_MS) kayip++;
  sonYazma.set(y.dosya, y.t);
  sayac.set(y.dosya, (sayac.get(y.dosya) ?? 0) + 1);
}
for (const n of sayac.values()) enSicak = Math.max(enSicak, n);
const sicakHiz = enSicak / SURE_SN;

// 2) Blok birimi: tek yazar. Digerleri ag uzerinden o ornege gonderiyor, kuyruk orada olusuyor.
const S_BLOK = TUR["blok birimi"].gecikmeMs, pBlok = YAZMA_S * S_BLOK / 1000;
const blokGecikme = AG_TURU_MS + S_BLOK + bekleme(pBlok, S_BLOK);
// 3) Paylasimli dosya sistemi: dosya basina bayt araligi kilidi; kuyruk yalniz ayni dosyada.
const S_PAY = TUR["paylasimli dosya"].gecikmeMs, pSicak = sicakHiz * S_PAY / 1000;
const payGecikme = S_PAY + bekleme(pSicak, S_PAY);

const veriGib = GIB(AKTIF * DOSYA_KIB * 1024);
const aylikYazma = YAZMA_S * AY_SN;
const UCRET = {
  "nesne deposu": TUR["nesne deposu"].saklama * veriGib + aylikYazma * TUR["nesne deposu"].istek,
  "blok birimi": TUR["blok birimi"].saklama * Math.ceil(YAZMA_S / 3 / 4) * 4,   // is/s butcesi boyut ister
  "paylasimli dosya": TUR["paylasimli dosya"].saklama * veriGib +
    TUR["paylasimli dosya"].verim * (YAZMA_S * EK_KIB / 1024),
};
console.log(`${ORNEK} saha ornegi, saniyede ${YAZMA_S} ek (${EK_KIB} KiB), ${AKTIF} etkin is emri dosyasi ` +
  `(${DOSYA_KIB} KiB). Dagilim carpik, uretec modelde, tohum ${TOHUM}. ${SURE_SN} sn kosuldu.`);
console.log(`en sicak dosya ${SURE_SN} sn'de ${enSicak} yazma aldi: ${g(sicakHiz, 0, 1)} yazma/s.`);
console.log("\ntur              | ayni anda yazar | kilit        | gecikme (ms) | kayip guncelleme | aylik ucret");
console.log("-----------------|-----------------|--------------|--------------|------------------|------------");
const GECIKME = { "nesne deposu": TUR["nesne deposu"].gecikmeMs, "blok birimi": blokGecikme, "paylasimli dosya": payGecikme };
const KAYIP = { "nesne deposu": kayip, "blok birimi": 0, "paylasimli dosya": 0 };
for (const [ad, t] of Object.entries(TUR))
  console.log(`${ad.padEnd(16)} | ${s(t.yazar, 15)} | ${t.kilit.padEnd(12)} | ${g(GECIKME[ad], 12, 2)} | ` +
    `${s(KAYIP[ad], 16)} | ${g(UCRET[ad], 11)}`);
console.log(`nesne deposunda ${ADET} yazmanin ${kayip} tanesi (%${g(100 * kayip / ADET, 0, 2)}) sessizce kayboldu: ` +
  `kilit yok, son yazan kazandi.`);
console.log(`blok biriminde 11 ornek dogrudan yazamiyor; tek yazarin yogunlugu %${g(100 * pBlok, 0, 1)}, ` +
  `bekleme ${g(bekleme(pBlok, S_BLOK), 0, 3)} ms. O ornek dusunce ${ORNEK}/${ORNEK} yazar duruyor.`);
console.log(`paylasimli dosya sisteminde en sicak dosyanin yogunlugu %${g(100 * pSicak, 0, 2)}, ` +
  `kilit beklemesi ${g(bekleme(pSicak, S_PAY), 0, 4)} ms; kilit dosya basina, kova basina degil.`);

// Kazandirmadigi durum: tek yazar, buyuk sirali okuma. Ayni veri, ayni is, uc turde ucret.
const FATURA = { veriGib: 400, mibS: 180 };
const F = {
  "nesne deposu": TUR["nesne deposu"].saklama * FATURA.veriGib,
  "blok birimi": 0.045 * 452,                        // verim ayarli birim, onceki derste hesaplandi
  "paylasimli dosya": TUR["paylasimli dosya"].saklama * FATURA.veriGib + TUR["paylasimli dosya"].verim * FATURA.mibS,
};
console.log(`\nkazandirmadigi durum — fatura uretimi: tek yazar, ${FATURA.mibS} MiB/s sirali okuma, ${FATURA.veriGib} GiB:`);
for (const [ad, u] of Object.entries(F))
  console.log(`  ${ad.padEnd(16)} ${g(u, 8)} birim/ay${ad === "paylasimli dosya" ?
    ` — en ucuzun ${g(u / Math.min(...Object.values(F)), 0, 1)} kati, kazandirdigi tek sey kullanilmayan kilit` : ""}`);
```

```
12 saha ornegi, saniyede 340 ek (2 KiB), 4800 etkin is emri dosyasi (11 KiB). Dagilim carpik, uretec modelde, tohum 71549. 60 sn kosuldu.
en sicak dosya 60 sn'de 1168 yazma aldi: 19.5 yazma/s.

tur              | ayni anda yazar | kilit        | gecikme (ms) | kayip guncelleme | aylik ucret
-----------------|-----------------|--------------|--------------|------------------|------------
nesne deposu     |              12 | yok          |        25.00 |             1057 |     4406.40
blok birimi      |               1 | tek yazar    |         1.08 |                0 |        9.28
paylasimli dosya |              12 | bayt araligi |         2.56 |                0 |        0.41
nesne deposunda 20400 yazmanin 1057 tanesi (%5.18) sessizce kayboldu: kilit yok, son yazan kazandi.
blok biriminde 11 ornek dogrudan yazamiyor; tek yazarin yogunlugu %20.4, bekleme 0.077 ms. O ornek dusunce 12/12 yazar duruyor.
paylasimli dosya sisteminde en sicak dosyanin yogunlugu %4.87, kilit beklemesi 0.0639 ms; kilit dosya basina, kova basina degil.

kazandirmadigi durum — fatura uretimi: tek yazar, 180 MiB/s sirali okuma, 400 GiB:
  nesne deposu         9.20 birim/ay
  blok birimi         20.34 birim/ay
  paylasimli dosya   228.00 birim/ay — en ucuzun 24.8 kati, kazandirdigi tek sey kullanilmayan kilit
```

Tablo üç türü tek ekranda ayırıyor. Nesne deposu on iki yazarı kabul eder ama kilidi yoktur:
altmış saniyede 20.400 yazmanın 1.057'si, yüzde 5,18'i, sessizce kaybolur. Hata dönmez, günlükte iz
kalmaz, saha ekibinin eklediği not yalnızca yoktur. Aylık ücreti de en yüksektir — 4.406,40 birim,
neredeyse tamamı yazma isteklerinden gelir: küçük ve sık yazma, nesne deposunun en pahalı kullanım
biçimidir.

Blok birimi kilidi ve kısmi yazmayı verir, gecikmesi en düşüktür (1,08 ms), ücreti 9,28 birimdir —
ama yazar sayısı birdir. On bir örnek doğrudan yazamaz, yazmalarını tek örneğe gönderir. Bu örneğin
yoğunluğu yüzde 20,4'tür, yani bugün rahattır; asıl kalem başarımda değil yapıdadır: o örnek
düştüğünde on iki yazarın on ikisi birden durur. Tek yazarlı huni bir başarım kısıtı değil, bir
kullanılabilirlik kalemidir.

Paylaşımlı dosya sistemi ikisini birden verir: on iki yazar, bayt aralığı kilidi, kayıp güncelleme
sıfır. Kilit dosya başınadır, kova başına değil — en sıcak dosya bile saniyede 19,5 yazma alır,
yoğunluğu yüzde 4,87'dir ve ortalama kilit beklemesi 0,064 ms'dir. Gecikmesi blok biriminin iki
katından fazladır (2,56 ms'e karşı 1,08 ms), çünkü her işlem ağdan geçer.

Son blok türün sınırını adıyla yazıyor. Fatura üretimi tek yazarlıdır ve büyük sıralı okuma yapar;
kilide ihtiyacı yoktur, dizin ağacına ihtiyacı yoktur. Paylaşımlı dosya sisteminde aylık 228,00
birim tutar — en ucuz seçeneğin 24,8 katı. **Paylaşımlı dosya sistemi çok yazarlı erişim için
alınır; tek yazarlı büyük sıralı okumada kazandırdığı tek şey kullanılmayan bir kilittir.**

#### Erişim Protokolü Geri Alınamayan Kalemdir

- **DT28** — Kurgu uygulamanın dosya erişim noktaları ve her birinin kaç yerde geçtiği modelde
  yazılıdır.
- **DT29** — Paylaşımlı dosya sistemi bölgeye bağlıdır; veriyi başka bir yere kopyalamak çıkış
  ücreti doğurur.
- **DT30** — Ücretler kurgu birimdir; paylaşımlı dosya sistemi kullanılan boyutu ve verimi
  faturalandırır, blok birimi ayrılan boyutu.

```js
// dosya/protokol.mjs — erisim protokolu geri alinamayan kalemdir: cagri noktalari sayilir (MODEL)
import { AKTIF, DOSYA_KIB, GIB } from "./model.mjs";

// Kurgu uygulamanin dosya erisim noktalari: cagri, kac yerde gectigi, nesne modelinde karsiligi.
const NOKTA = [
  ["dosyayi bastan sona oku", 9, "var", "tam nesne getirme"],
  ["dosyanin bir araligini oku", 6, "var", "aralik istegi"],
  ["dosyayi bastan sona yaz", 5, "var", "tam nesne koyma"],
  ["dosyanin ortasina yaz", 7, "yok", "kismi guncelleme yok, nesne bastan yazilir"],
  ["dosyaya ekle", 8, "yok", "ekleme yok, nesne bastan yazilir"],
  ["dosyayi kirp", 2, "yok", "karsiligi yok"],
  ["dizin listele", 4, "kismen", "onek listeleme, sayfali ve ucretli"],
  ["dizin boyutunu oku", 2, "yok", "tum anahtarlar taranir"],
  ["yeniden adlandir", 3, "yok", "kopyala ve sil"],
  ["bayt araligi kilidi al", 5, "yok", "kilit yok"],
  ["degisikligi diske zorla", 3, "yok", "yazma zaten butun ya da hic"],
];
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
const toplam = NOKTA.reduce((a, n) => a + n[1], 0);
const tasinabilir = NOKTA.filter((n) => n[2] === "var").reduce((a, n) => a + n[1], 0);
const kismen = NOKTA.filter((n) => n[2] === "kismen").reduce((a, n) => a + n[1], 0);

console.log("cagri                      | yer | nesne modelinde | karsilik");
console.log("---------------------------|-----|-----------------|--------------------------------------");
for (const [ad, yer, durum, not] of NOKTA)
  console.log(`${ad.padEnd(26)} | ${s(yer, 3)} | ${durum.padEnd(15)} | ${not}`);
console.log(`\ntoplam ${toplam} cagri noktasi: ${tasinabilir} tanesi dogrudan tasinir, ${kismen} tanesi ` +
  `davranis degistirerek tasinir, ${toplam - tasinabilir - kismen} tanesi yeniden yazilir.`);
console.log(`yeniden yazilacak oran %${g(100 * (toplam - tasinabilir - kismen) / toplam, 0, 1)}; bu sayi ` +
  `veri boyutundan bagimsizdir — ${GIB(AKTIF * DOSYA_KIB * 1024).toFixed(3)} GiB de olsa ayni ${toplam - tasinabilir - kismen} nokta yazilir.`);

// Cikis ve aktarim: paylasimli dosya sistemi bolgeye baglidir.
const CIKIS = { "bolge ici": 0, "bolgeler arasi": 0.020, "internete": 0.085 };
const veriGib = GIB(AKTIF * DOSYA_KIB * 1024), YEDEK_GIB = 640;
console.log(`\ncikis: ${YEDEK_GIB} GiB'lik saha arsivi paylasimli dosya sisteminden okunup baska bir yere kopyalanirsa`);
for (const [nere, oran] of Object.entries(CIKIS))
  console.log(`  ${nere.padEnd(14)} ${g(YEDEK_GIB * oran, 7)} birim`);
console.log(`etkin is emri verisi ${veriGib.toFixed(3)} GiB; cikis ucreti verinin boyutuyla degil, ` +
  `nereye tasindigiyla olculur.`);
```

```
cagri                      | yer | nesne modelinde | karsilik
---------------------------|-----|-----------------|--------------------------------------
dosyayi bastan sona oku    |   9 | var             | tam nesne getirme
dosyanin bir araligini oku |   6 | var             | aralik istegi
dosyayi bastan sona yaz    |   5 | var             | tam nesne koyma
dosyanin ortasina yaz      |   7 | yok             | kismi guncelleme yok, nesne bastan yazilir
dosyaya ekle               |   8 | yok             | ekleme yok, nesne bastan yazilir
dosyayi kirp               |   2 | yok             | karsiligi yok
dizin listele              |   4 | kismen          | onek listeleme, sayfali ve ucretli
dizin boyutunu oku         |   2 | yok             | tum anahtarlar taranir
yeniden adlandir           |   3 | yok             | kopyala ve sil
bayt araligi kilidi al     |   5 | yok             | kilit yok
degisikligi diske zorla    |   3 | yok             | yazma zaten butun ya da hic

toplam 54 cagri noktasi: 20 tanesi dogrudan tasinir, 4 tanesi davranis degistirerek tasinir, 30 tanesi yeniden yazilir.
yeniden yazilacak oran %55.6; bu sayi veri boyutundan bagimsizdir — 0.050 GiB de olsa ayni 30 nokta yazilir.

cikis: 640 GiB'lik saha arsivi paylasimli dosya sisteminden okunup baska bir yere kopyalanirsa
  bolge ici         0.00 birim
  bolgeler arasi   12.80 birim
  internete        54.40 birim
etkin is emri verisi 0.050 GiB; cikis ucreti verinin boyutuyla degil, nereye tasindigiyla olculur.
```

Paylaşımlı dosya sistemi seçildiğinde devredilen karar listesi kısadır: sağlayıcı üst veri
sunucusunu, çoğaltmayı ve büyümeyi devralır. Elde kalan taraf ise bir şey daha içerir ve fatura
sütununda görünmez — **erişim protokolü**. Uygulama dosya yollarına, dizin ağacına ve kilitlere göre
yazılır. Bu bir yapılandırma değil, kod biçimidir.

Tablo bunun ölçüsünü veriyor. Elli dört erişim noktasının yirmisi nesne modeline doğrudan taşınır,
dördü davranış değiştirerek taşınır, otuzu yeniden yazılır: yüzde 55,6. Bu sayı **veri boyutundan
bağımsızdır** — 0,050 GiB'lik iş emri verisi de olsa aynı otuz nokta yeniden yazılır. Anahtar düzeni
geri alınamayan kalemdi çünkü veriyi taşımak gerekiyordu; erişim protokolü geri alınamayan kalemdir
çünkü **uygulamayı** taşımak gerekir ve o taşımanın bedeli veriyle küçülmez.

Çıkış tarafı üçüncü kalemi kapatıyor. Paylaşımlı dosya sistemi tek bölgeye bağlıdır; 640 GiB'lik
saha arşivini bölge içinde okumak çıkış ücreti doğurmaz, bölgeler arasına taşımak 12,80 birim,
internete indirmek 54,40 birim tutar. Bu kursun ilk dersinden beri aynı kural işliyor: veri girerken
ücretsizdir, çıkarken ücretlidir ve ücreti nereye gittiğiyle ölçülür.

#### Özet

- Üç tür çok yazarlı erişimde ayrışır: nesne deposu on iki yazar alır ama kilidi yoktur, blok birimi
  kilidi verir ama tek yazar alır, paylaşımlı dosya sistemi ikisini birden verir.
- Kilitsiz erişimin bedeli sessizdir: altmış saniyede 20.400 yazmanın 1.057'si, yüzde 5,18'i, hata
  dönmeden kaybolur. Aynı iş yükünde nesne deposu 4.406,40 birimle en pahalı seçenektir.
- Tek yazarlı huni bir başarım kısıtı değil kullanılabilirlik kalemidir: yoğunluk yüzde 20,4 ile
  rahattır, ama o örnek düştüğünde on iki yazarın on ikisi durur.
- Kilit dosya başınadır: en sıcak dosya saniyede 19,5 yazma alır, yoğunluğu yüzde 4,87, kilit
  beklemesi 0,064 ms. Gecikme blok biriminin iki katından fazladır (2,56 ms'e karşı 1,08 ms),
  çünkü her işlem ağdan geçer.
- Kazandırmadığı durum adıyla yazılır: tek yazarlı büyük sıralı okumada 228,00 birim tutar, en ucuz
  seçeneğin 24,8 katı. Geri alınamayan kalem erişim protokolüdür — elli dört çağrı noktasının otuzu
  veri boyutundan bağımsız olarak yeniden yazılır.

#### Sonraki Adım

Beş ders bir eksik bırakıyor. Kurgu ölçüm ağının saha fotoğrafları bir kez yazılıp neredeyse hiç
okunmuyor; ikinci derste ölçülen dağılımda bu ailenin yüzde 97'si yıl boyunca hiç açılmadı. Böyle
veri için sık erişilen sınıf açık bir israftır, ama arşiv katmanının ne olduğu henüz ölçülmedi:
saklama ücreti neredeyse yok gibidir, karşılığında veri **hemen okunamaz**. Sonraki ders bu takası
sayar — geri getirme hızı seçenekleri taranır, her birinde süre ile ücret birlikte çıkarılır, bir
denetim isteğinde kaç saat beklendiği hesaplanır ve en az saklama süresinin erken silinen nesneye ne
ödettiği gösterilir.

### Arşiv Depolama

Source: https://academia.sh/tr/kurslar/bulut-depolama/arsiv-depolama

Arşiv katmanında saklama ücretinin düşmesine karşılık geri getirmenin hem ücretli hem gecikmeli olması: üç geri getirme hızının süre ve ücretle birlikte taranması, bir denetim isteğinde kaç saat beklendiğinin çıkarılması, çıkış ücretinin getirmenin üstüne binmesi ve en az saklama süresinin erken silinen nesneye tam süreyi ödetmesi.

İkinci derste erişim geçmişi taranınca bir aile ayrıldı: saha fotoğraflarının yüzde 97'si yıl
boyunca hiç açılmadı. Böyle veri için sık erişilen sınıf açık bir israftır ve üçüncü dersin yaşam
döngüsü kuralı onu otomatik olarak arşive gönderebilir. Arşive gönderilen verinin ne olduğu ise
henüz ölçülmedi.

Arşiv katmanı bir depolama sınıfıdır ama diğerlerinden bir noktada ayrılır: veri **hemen okunamaz**.
Bir nesneyi almak için önce bir geri getirme isteği verilir, istek işlenir, nesne okunabilir hâle
gelir. Bu bekleme dakikalardan saatlere uzanır ve hızlandırılabilir — ücreti ödendiği sürece.
Bekleme her arşiv sınıfının kuralı değildir: kimi sağlayıcının en ucuz sınıfı da milisaniyelerde
okunur ve yalnız ücretle en az saklama süresinde ayrışır; bu ders beklemeli olanı ölçer. Bu
dersin ölçüsü budur: saklamada kazanılanın nerede, hangi kalemle geri ödendiği.

- **DT31** — Arşiv katmanı, geri getirme hızları ve ücretler kurgudur; katmanlar erişim sıklığıyla
  anılır.
- **DT32** — Üç geri getirme hızı vardır; her birinin ilk yanıt gecikmesi, akış hızı, bayt ücreti ve
  istek ücreti modelde yazılıdır.
- **DT33** — Bir geri getirme isteği en çok 10.000 nesne alır ve aynı anda dört parti işlenir.

```js
// arsiv/model.mjs — arsiv katmani, geri getirme hizlari ve denetim istegi MODELDIR. Ucretler kurgu
// birimdir; katmanlar erisim sikligiyla anilir, hicbir ticari ad kullanilmaz.
export const SINIF = {                  // saklama B/GiB/ay, gecis B/istek, enAzGun: en az saklama
  "sik erisilen": { saklama: 0.0230, gecis: 0.0050 / 1000, enAzGun: 0 },
  arsiv: { saklama: 0.0010, gecis: 0.0500 / 1000, enAzGun: 180 },
};
// Geri getirme hizlari: ilk yanit gecikmesi, akis hizi, bayt ve istek ucreti.
export const HIZ = {
  yavas: { ilkSaat: 12, gibSaat: 250, gib: 0.0025, istek: 0.030 / 1000 },
  orta: { ilkSaat: 4, gibSaat: 600, gib: 0.0100, istek: 0.060 / 1000 },
  hizli: { ilkSaat: 5 / 60, gibSaat: 1500, gib: 0.0300, istek: 0.120 / 1000 },
};
export const PARTI = 10_000, ES_ZAMANLI = 4;        // bir istekte 10.000 nesne, ayni anda 4 parti
export const CIKIS = { "bolge ici": 0, "bolgeler arasi": 0.020, internete: 0.085 };
// Kurgu denetim istegi: bir ilin uc yillik fatura belgeleri ve saha fotograflari.
export const DENETIM = { fatura: { adet: 46_000, kib: 380 }, foto: { adet: 80_000, kib: 3686 } };
export const GIB = (bayt) => bayt / 1024 ** 3;
export const denetimBayt = Object.values(DENETIM).reduce((a, k) => a + k.adet * k.kib * 1024, 0);
export const denetimAdet = Object.values(DENETIM).reduce((a, k) => a + k.adet, 0);
```

#### Süre ile Ücret Aynı Kadranın İki Ucu

- **DT34** — Kurgu denetim isteği bir ilin üç yıllık fatura belgelerini ve saha fotoğraflarını
  kapsar; adetler ve boyutlar modelde yazılıdır.

```js
// arsiv/getirme.mjs — geri getirme hizlari taranir: sure ile ucret birlikte sayilir
import { HIZ, PARTI, ES_ZAMANLI, CIKIS, GIB, denetimBayt, denetimAdet, DENETIM } from "./model.mjs";

const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
const gib = GIB(denetimBayt), parti = Math.ceil(denetimAdet / PARTI), tur = Math.ceil(parti / ES_ZAMANLI);
console.log(`kurgu denetim istegi: ${Object.entries(DENETIM).map(([a, k]) => `${k.adet} ${a}`).join(" + ")} = ` +
  `${denetimAdet.toLocaleString("tr")} nesne, ${g(gib, 0, 1)} GiB.`);
console.log(`istek ${PARTI} nesnelik partilere boluniyor: ${parti} parti, ayni anda ${ES_ZAMANLI} parti, ${tur} tur.`);
console.log("\nhiz    | ilk yanit | akis GiB/saat | tek parti (saat) | toplam bekleme (saat) | getirme ucreti");
console.log("-------|-----------|---------------|------------------|-----------------------|---------------");
const U = {}, T = {};
for (const [ad, h] of Object.entries(HIZ)) {
  const partiGib = gib / parti, turSaat = h.ilkSaat + (partiGib * ES_ZAMANLI) / h.gibSaat;
  const ucret = U[ad] = gib * h.gib + denetimAdet * h.istek;
  T[ad] = tur * turSaat;
  console.log(`${ad.padEnd(6)} | ${g(h.ilkSaat, 9, 2)} | ${s(h.gibSaat, 13)} | ${g(h.ilkSaat + partiGib / h.gibSaat, 16, 2)} | ` +
    `${g(T[ad], 21, 1)} | ${g(ucret, 14, 2)}`);
}
console.log(`ayni istek: bekleme ${(T.yavas / T.hizli).toFixed(0)} kat kisaliyor, ucret ` +
  `${(U.hizli / U.yavas).toFixed(1)} kat artiyor. Sure ile ucret ayni kadranin iki ucu.`);
console.log(`istek ucreti baskin: ${denetimAdet.toLocaleString("tr")} nesne yavas hizda ` +
  `${g(denetimAdet * HIZ.yavas.istek, 0, 2)} birim, ayni bayt icin bayt ucreti ${g(gib * HIZ.yavas.gib, 0, 2)} birim.`);
console.log("\ngetirme bittikten sonra cikis ayrica odenir (ayni bayt):");
for (const [nere, oran] of Object.entries(CIKIS))
  console.log(`  ${nere.padEnd(15)} ${g(gib * oran, 7)} birim`);
console.log(`internete indirilirse cikis ucreti, en ucuz getirmenin ${g(gib * CIKIS.internete / U.yavas, 0, 1)} kati: ` +
  `arsivin ucuzlugu veriyi disari cikarmaya kadardir.`);

// Karar: verilen yanit suresi taahhudune uyan en ucuz hiz hangisi. Istek daraltilirsa ne degisir.
const cozum = (adet, bayt, sinirSaat) => {
  const G = GIB(bayt), p = Math.ceil(adet / PARTI), t = Math.ceil(p / ES_ZAMANLI);
  let en = null;
  for (const [ad, h] of Object.entries(HIZ)) {
    const sure = t * (h.ilkSaat + (G / p * ES_ZAMANLI) / h.gibSaat), uc = G * h.gib + adet * h.istek;
    if (sure <= sinirSaat && (en === null || uc < en.uc)) en = { ad, sure, uc };
  }
  return en;
};
console.log("\nyanit suresi taahhudune uyan en ucuz hiz:");
console.log("taahhut | tam istek (126.000 nesne)        | yalniz fatura (46.000 nesne)");
console.log("--------|----------------------------------|------------------------------");
for (const sinir of [1, 6, 24, 72]) {
  const a = cozum(denetimAdet, denetimBayt, sinir);
  const f = cozum(DENETIM.fatura.adet, DENETIM.fatura.adet * DENETIM.fatura.kib * 1024, sinir);
  const yaz = (x) => x ? `${x.ad.padEnd(5)} ${g(x.sure, 5, 1)} saat ${g(x.uc, 7)} birim` : "karsilanamaz";
  console.log(`${s(sinir + " saat", 7)} | ${yaz(a).padEnd(32)} | ${yaz(f)}`);
}
```

```
kurgu denetim istegi: 46000 fatura + 80000 foto = 126.000 nesne, 297.9 GiB.
istek 10000 nesnelik partilere boluniyor: 13 parti, ayni anda 4 parti, 4 tur.

hiz    | ilk yanit | akis GiB/saat | tek parti (saat) | toplam bekleme (saat) | getirme ucreti
-------|-----------|---------------|------------------|-----------------------|---------------
yavas  |     12.00 |           250 |            12.09 |                  49.5 |           4.52
orta   |      4.00 |           600 |             4.04 |                  16.6 |          10.54
hizli  |      0.08 |          1500 |             0.10 |                   0.6 |          24.06
ayni istek: bekleme 86 kat kisaliyor, ucret 5.3 kat artiyor. Sure ile ucret ayni kadranin iki ucu.
istek ucreti baskin: 126.000 nesne yavas hizda 3.78 birim, ayni bayt icin bayt ucreti 0.74 birim.

getirme bittikten sonra cikis ayrica odenir (ayni bayt):
  bolge ici          0.00 birim
  bolgeler arasi     5.96 birim
  internete         25.32 birim
internete indirilirse cikis ucreti, en ucuz getirmenin 5.6 kati: arsivin ucuzlugu veriyi disari cikarmaya kadardir.

yanit suresi taahhudune uyan en ucuz hiz:
taahhut | tam istek (126.000 nesne)        | yalniz fatura (46.000 nesne)
--------|----------------------------------|------------------------------
 1 saat | hizli   0.6 saat   24.06 birim   | hizli   0.2 saat    6.02 birim
 6 saat | hizli   0.6 saat   24.06 birim   | hizli   0.2 saat    6.02 birim
24 saat | orta   16.6 saat   10.54 birim   | orta    8.0 saat    2.93 birim
72 saat | yavas  49.5 saat    4.52 birim   | yavas  24.1 saat    1.42 birim
```

Denetim isteği 126.000 nesne ve 297,9 GiB'dir. Üç hızın hiçbiri yanlış değildir; farkları iki
sütunda toplanır. Yavaş hızda toplam bekleme 49,5 saattir — iki günden fazla — ve getirme ücreti
4,52 birimdir. Hızlı hızda bekleme 0,6 saate iner, ücret 24,06 birime çıkar. Bekleme 86 kat kısalır,
ücret 5,3 kat artar. Bir denetim isteğinde asıl karar hangi hızın "iyi" olduğu değil, **kaç saat
beklemenin kabul edilebilir olduğudur**; o cevap bilinmeden hız seçilemez.

Toplam beklemenin ilk yanıt gecikmesinden büyük olmasının nedeni parti hesabıdır. İstek 10.000
nesnelik partilere bölünür: 126.000 nesne 13 parti eder, aynı anda dört parti işlenir, dolayısıyla
dört tur gerekir. Yavaş hızda tek parti 12,09 saat sürer ama toplam 49,5 saattir. **İlk yanıt
gecikmesi her turda yeniden ödenir** ve nesne sayısı arttıkça bekleme baytla değil turla büyür.

Alt satır aynı yapının fiyat tarafını gösteriyor: 126.000 nesnenin istek ücreti yavaş hızda 3,78
birimdir, aynı baytın bayt ücreti ise 0,74 birim. Getirme faturasının beşte dördü **nesne
sayısındandır**. Bu, birinci ve ikinci dersteki kuralın arşivdeki karşılığıdır — küçük ve çok sayıda
nesne her katmanda istek ücretiyle ödetir.

Çıkış ayrı bir kalemdir. Geri getirme, veriyi okunabilir hâle getirir; veriyi bir yere **taşımaz**.
Aynı 297,9 GiB bölge içinde kalırsa çıkış ücreti doğmaz, bölgeler arasına taşınırsa 5,96 birim,
internete indirilirse 25,32 birim tutar. İnternete indirme, en ucuz getirmenin 5,6 katıdır: arşivin
ucuzluğu veriyi dışarı çıkarmaya kadardır.

Son tablo kararı yanıt süresi taahhüdüne bağlıyor ve seçimi tek satıra indiriyor. Bir saatlik
taahhütte yalnız hızlı hız yeter ve 24,06 birim tutar; yirmi dört saatlik taahhütte orta hız 10,54
birime düşer; yetmiş iki saatlik taahhütte yavaş hız 4,52 birimle yeter. Sağ sütun ikinci bir kolu
açıyor: denetim isteği daraltılıp yalnız fatura belgeleri istendiğinde her taahhütte hem süre hem
ücret düşer — yirmi dört saatlik taahhütte 10,54 birim yerine 2,93 birim. **İsteği daraltmak, hızı
yükseltmekten ucuzdur;** arşivde ölçülmesi gereken ilk şey neyin gerçekten geri getirilmesi
gerektiğidir.

#### En Az Saklama Süresi

- **DT35** — Arşiv katmanının en az saklama süresi 180 gündür ve nesne sınıfa girdiği anda başlar.
- **DT36** — Yaşam döngüsü kuralı nesneyi 30. günde arşive geçirir, ömrü bitince siler.

```js
// arsiv/enaz.mjs — en az saklama suresi: erken silinen nesne yine de tam sure ucretlendirilir
import { SINIF, GIB } from "./model.mjs";

const AY_GUN = 30, arsiv = SINIF.arsiv, sik = SINIF["sik erisilen"];
const enAzAy = arsiv.enAzGun / AY_GUN;
// Iki aile, iki omur: kucuk ve kisa omurlu belge, buyuk ve uzun omurlu fotograf.
const AILE = [
  { ad: "fatura-belgeleri", adet: 86_000, kib: 380, omurAy: 3 },
  { ad: "saha-fotograflari", adet: 42_000, kib: 3686, omurAy: 60 },
];
const GECIS_AY = 1;                                  // 30. gunde arsive gecen kural
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
console.log(`arsiv katmaninin en az saklama suresi ${arsiv.enAzGun} gun = ${enAzAy} ay. ` +
  `Kural ${GECIS_AY}. ayda arsive geciriyor, omur bitince siliyor.`);
console.log("\naile              |  omur | arsivde gecen | faturalanan | gecis ucreti | arsivsiz | arsivli | oran");
console.log("------------------|-------|---------------|-------------|--------------|----------|---------|------");
for (const f of AILE) {
  const gib = GIB(f.adet * f.kib * 1024), arsivde = f.omurAy - GECIS_AY;
  const faturalanan = Math.max(arsivde, enAzAy);
  const gecisUcret = f.adet * arsiv.gecis;
  const arsivsiz = gib * sik.saklama * f.omurAy;
  const arsivli = gib * sik.saklama * GECIS_AY + gecisUcret + gib * arsiv.saklama * faturalanan;
  console.log(`${f.ad.padEnd(17)} | ${s(f.omurAy + " ay", 5)} | ${s(arsivde + " ay", 13)} | ${s(faturalanan + " ay", 11)} | ` +
    `${g(gecisUcret, 12)} | ${g(arsivsiz, 8)} | ${g(arsivli, 7)} | ${g(arsivli / arsivsiz, 5, 2)}`);
}

// Erken silme: nesne 45. gunde silinse de 180 gunluk borc duruyor.
const foto = AILE[1], gib = GIB(foto.adet * foto.kib * 1024), SILME_GUN = 45;
const kullanilan = SILME_GUN / AY_GUN, borclu = enAzAy - kullanilan;
console.log(`\nerken silme: ${foto.adet.toLocaleString("tr")} fotograf arsive konup ${SILME_GUN}. gunde silindi.`);
console.log(`  kullanilan ${g(kullanilan, 0, 1)} ay, faturalanan ${enAzAy} ay, odenen bos sure ${g(borclu, 0, 1)} ay.`);
console.log(`  ${SILME_GUN}. gunde silmenin faturasi ${g(gib * arsiv.saklama * enAzAy, 0, 3)} birim; ` +
  `hic silmeyip ${enAzAy} ay tutmanin faturasi da ${g(gib * arsiv.saklama * enAzAy, 0, 3)} birim.`);
console.log(`  aradaki ${g(borclu, 0, 1)} ay icin ${g(gib * arsiv.saklama * borclu, 0, 3)} birim, artik var olmayan ` +
  `nesneler icin odeniyor: erken silmek hicbir sey kazandirmiyor.`);
console.log(`arsiv, ${enAzAy} aydan kisa yasayacak veri icin bir depolama sinifi degil, pesin odenmis bir borctur.`);
```

```
arsiv katmaninin en az saklama suresi 180 gun = 6 ay. Kural 1. ayda arsive geciriyor, omur bitince siliyor.

aile              |  omur | arsivde gecen | faturalanan | gecis ucreti | arsivsiz | arsivli | oran
------------------|-------|---------------|-------------|--------------|----------|---------|------
fatura-belgeleri  |  3 ay |          2 ay |        6 ay |         4.30 |     2.15 |    5.20 |  2.42
saha-fotograflari | 60 ay |         59 ay |       59 ay |         2.10 |   203.74 |   14.21 |  0.07

erken silme: 42.000 fotograf arsive konup 45. gunde silindi.
  kullanilan 1.5 ay, faturalanan 6 ay, odenen bos sure 4.5 ay.
  45. gunde silmenin faturasi 0.886 birim; hic silmeyip 6 ay tutmanin faturasi da 0.886 birim.
  aradaki 4.5 ay icin 0.664 birim, artik var olmayan nesneler icin odeniyor: erken silmek hicbir sey kazandirmiyor.
arsiv, 6 aydan kisa yasayacak veri icin bir depolama sinifi degil, pesin odenmis bir borctur.
```

Tablo tek bir kuralı iki aileye uyguluyor ve zıt sonuç veriyor. Saha fotoğrafları altmış ay yaşar;
arşivde geçen elli dokuz ay en az saklama süresinin çok üstündedir, dolayısıyla faturalanan süre de
elli dokuz aydır. Arşivsiz 203,74 birim tutan aile arşivle 14,21 birime iner — oran 0,07, on dört
kat kazanç. Fatura belgeleri üç ay yaşar; arşivde iki ay geçirir ama **altı ay faturalanır**. Arşivsiz
2,15 birim tutan aile arşivle 5,20 birime çıkar: 2,42 kat zarar. Aynı kural, aynı katman, ters
sonuç. Farkı yaratan iki şey vardır — nesnenin ömrü ve nesnenin boyutu. 86.000 küçük belgenin geçiş
ücreti tek başına 4,30 birimdir, arşivsiz toplamın iki katı.

Erken silme bloğu kalemi adıyla yazıyor. Kırk iki bin fotoğraf arşive konup kırk beşinci günde
siliniyor: kullanılan 1,5 ay, faturalanan 6 ay. Silmenin faturası 0,886 birimdir ve hiç silmeyip
altı ay tutmanın faturası da 0,886 birimdir — birebir aynı. Aradaki 4,5 ay için ödenen 0,664 birim,
artık var olmayan nesneler içindir. **En az saklama süresi bu dersin geri alınamayan kalemidir:**
nesne sınıfa girdiği anda borç doğar ve o borcu silme de, sınıf değiştirme de kapatmaz.

Devredilen karar tarafı burada en geniştir. Arşiv katmanında dayanıklılık, yerleşim, saklama ortamı,
onarım ve okunabilirliğin sürdürülmesi tümüyle sağlayıcıdadır; hiçbiri görünmez, hiçbirinin kadranı
yoktur. Elde kalan üç sayı vardır: hangi nesnenin ne zaman arşive gireceği, ne kadar yaşayacağı ve
gerektiğinde hangi hızla geri getirileceği. Üçü de veriyi yazmadan önce kararlaştırılır, çünkü
üçünün de bedeli sonradan ödenir.

#### Özet

- Arşiv katmanında saklama ucuzdur ama veri hemen okunamaz: aynı denetim isteği yavaş hızda 49,5
  saat bekletip 4,52 birim, hızlı hızda 0,6 saat bekletip 24,06 birim tutar.
- Bekleme baytla değil turla büyür: 126.000 nesne 10.000'lik partilere bölünür, dört tur eder ve ilk
  yanıt gecikmesi her turda yeniden ödenir.
- Getirme faturasının beşte dördü nesne sayısındandır: 126.000 nesnenin istek ücreti 3,78, aynı
  baytın bayt ücreti 0,74 birimdir.
- Geri getirme veriyi okunabilir yapar, taşımaz: aynı 297,9 GiB internete indirilirse 25,32 birim
  çıkış ücreti getirmenin üstüne biner, en ucuz getirmenin 5,6 katı.
- En az saklama süresi geri alınamayan kalemdir: altmış ay yaşayan fotoğraflarda arşiv on dört kat
  kazandırır, üç ay yaşayan belgelerde 2,42 kat zarar ettirir; kırk beşinci günde silinen nesne yine
  de altı ay öder.

#### Sonraki Adım

Altı ders verinin **nereye** konacağını ölçtü: nesne, blok, paylaşımlı dosya ve arşiv. Hiçbiri tek
bir soruyu sormadı — bu veriyi kim okuyabilir. Kurgu ölçüm ağında saha ekipleri fotoğrafları
telefondan açar, denetçiler fatura belgelerini dışarıdan ister ve iki grubun da kova erişimi yoktur.
Kimlik vermek kalıcı bir kapı açar; oysa istenen şey genellikle **süreli ve dar** bir kapıdır.
Sonraki ders bunu ölçer: imzalı bağlantı üretilir, süresi ve kapsamı gerçekten doğrulanır. Ölçülecek
üç şey var — bağlantının ömrü kısaldıkça artan yeniden üretme yükü, uzadıkça büyüyen sızıntı
penceresi ve kapsam genişledikçe tek bir bağlantının açtığı nesne sayısı.

### Erişim Denetimi ve İmzalı Bağlantılar

Source: https://academia.sh/tr/kurslar/bulut-depolama/erisim-denetimi-ve-imzali-baglantilar

Süreli ve dar erişim vermenin ölçülmesi: kurgu anahtarla imzalı bağlantı üretilip süre, yöntem ve kapsam denetimlerinin gerçekten doğrulanması; bağlantı ömrünün taranarak yeniden üretme yüküyle sızıntı penceresinin karşılaştırılması, kapsam genişliğinin açtığı yüzeyin sayılması ve imzalı bağlantının geri alınamazlığının iptal patlamasıyla gösterilmesi.

Altı ders verinin nereye konacağını ölçtü. Hiçbiri tek bir soruyu sormadı: bu veriyi kim okuyabilir.
Kurgu ölçüm ağında saha ekipleri fotoğrafları telefondan açar, denetçiler fatura belgelerini
dışarıdan ister ve iki grubun da kova erişimi yoktur. Kimlik vermek kalıcı bir kapı açar; oysa
istenen şey genellikle **süreli ve dar** bir kapıdır — bu nesne, bu kadar süre, yalnız okuma.

**İmzalı bağlantı** (presigned URL) bunu sunar. Bir anahtarla imzalanmış bağlantı, taşıdığı alanların
değiştirilmediğini kanıtlar; depo bağlantıyı doğrular ve nesneyi verir. Bağlantıyı taşıyan kişinin
hesabı, kimliği, yetkisi yoktur — bağlantının kendisi yetkidir. Bu, hem gücünü hem tehlikesini aynı
cümleye koyar: bağlantı kime giderse yetki de oraya gider.

- **DT37** — İmza anahtarı kurgudur, gerçek bir sır değildir; saat sabittir ki çıktı koşumdan koşuma
  aynı kalsın.
- **DT38** — Kanonik dize yöntem, kapsam, kaynak ve son geçerlilik alanlarından oluşur; imza bu
  dizenin anahtarlı özetidir.
- **DT39** — Doğrulama dört denetim yapar: imza, saat, yöntem ve kapsam.

```js
// imza/imzala.mjs — imzali baglanti uretilir ve sure ile kapsam GERCEKTEN dogrulanir.
// Anahtar kurgudur, gercek bir sir degildir; saat sabittir ki cikti kosumdan kosuma ayni kalsin.
import { createHmac, timingSafeEqual } from "node:crypto";

const ANAHTAR = Buffer.from("kurgu-imza-anahtari-ornek-gecersiz");   // gercek sir yazilmaz
const SIMDI = 1_774_000_000;                        // sabit saat (saniye); Date.now() kullanilmaz
const kanonik = (y, kapsam, kaynak, son) => [y, kapsam, kaynak, son].join("\n");
const imzala = (y, kapsam, kaynak, omurSn) => {
  const son = SIMDI + omurSn;
  const imza = createHmac("sha256", ANAHTAR).update(kanonik(y, kapsam, kaynak, son)).digest("hex");
  return { y, kapsam, kaynak, son, imza };
};
// Dogrulama: imza tutuyor mu, sure gecmis mi, istenen anahtar kapsamin icinde mi, yontem ayni mi.
const dogrula = (b, istenenYontem, istenenAnahtar, saat) => {
  const beklenen = createHmac("sha256", ANAHTAR).update(kanonik(b.y, b.kapsam, b.kaynak, b.son)).digest("hex");
  const a = Buffer.from(beklenen, "hex"), c = Buffer.from(b.imza, "hex");
  if (a.length !== c.length || !timingSafeEqual(a, c)) return "imza tutmuyor";
  if (saat > b.son) return `suresi ${saat - b.son} sn once doldu`;
  if (b.y !== istenenYontem) return "yontem disi";
  if (!istenenAnahtar.startsWith(b.kapsam)) return "kapsam disi";
  return "gecerli";
};

const ONEK = "saha/2026/03/14/";
const TEK = ONEK + "foto-00412.jpg";
const baglanti = imzala("oku", TEK, TEK, 900);      // tek nesneye, 15 dakikalik
const onekli = imzala("oku", ONEK, TEK, 900);       // bir gunun tum fotograflarina
const DENEME = [
  ["dogru anahtar, sure icinde", baglanti, "oku", TEK, SIMDI + 300],
  ["sure dolduktan sonra", baglanti, "oku", TEK, SIMDI + 1200],
  ["baska nesne istenirse", baglanti, "oku", ONEK + "foto-00413.jpg", SIMDI + 300],
  ["okuma baglantisiyla yazma", baglanti, "yaz", TEK, SIMDI + 300],
  ["imzanin son harfi degisirse", { ...baglanti, imza: baglanti.imza.slice(0, -1) + (baglanti.imza.endsWith("a") ? "b" : "a") },
    "oku", TEK, SIMDI + 300],
  ["onek kapsami, kapsam icinde", onekli, "oku", ONEK + "foto-09999.jpg", SIMDI + 300],
  ["onek kapsami, kapsam disinda", onekli, "oku", "saha/2026/03/15/foto-00001.jpg", SIMDI + 300],
];
console.log(`kurgu anahtarla imzalandi; sabit saat ${SIMDI}. Imza uzunlugu ${baglanti.imza.length} onaltilik basamak.`);
console.log(`tek nesne baglantisi: kapsam ${baglanti.kapsam}, son ${baglanti.son} (${baglanti.son - SIMDI} sn omur)`);
console.log(`onek baglantisi     : kapsam ${onekli.kapsam}`);
console.log("\ndeneme                        | istenen anahtar                | sonuc");
console.log("------------------------------|--------------------------------|---------------------");
for (const [ad, b, y, anahtar, saat] of DENEME)
  console.log(`${ad.padEnd(29)} | ${anahtar.padEnd(30)} | ${dogrula(b, y, anahtar, saat)}`);
console.log("\nRed gerekceleri ayri: biri imzadan, biri saatten, ikisi kanonik dizeye yazilan alanlardan geliyor.");
console.log("Imza yalnizca baglantinin degistirilmedigini soyluyor; ne kadar yasadigini ve neyi actigini");
console.log("kapsam ve son alanlari soyluyor — ikisi de imzanin icinde, disaridan degistirilemiyor.");
```

```
kurgu anahtarla imzalandi; sabit saat 1774000000. Imza uzunlugu 64 onaltilik basamak.
tek nesne baglantisi: kapsam saha/2026/03/14/foto-00412.jpg, son 1774000900 (900 sn omur)
onek baglantisi     : kapsam saha/2026/03/14/

deneme                        | istenen anahtar                | sonuc
------------------------------|--------------------------------|---------------------
dogru anahtar, sure icinde    | saha/2026/03/14/foto-00412.jpg | gecerli
sure dolduktan sonra          | saha/2026/03/14/foto-00412.jpg | suresi 300 sn once doldu
baska nesne istenirse         | saha/2026/03/14/foto-00413.jpg | kapsam disi
okuma baglantisiyla yazma     | saha/2026/03/14/foto-00412.jpg | yontem disi
imzanin son harfi degisirse   | saha/2026/03/14/foto-00412.jpg | imza tutmuyor
onek kapsami, kapsam icinde   | saha/2026/03/14/foto-09999.jpg | gecerli
onek kapsami, kapsam disinda  | saha/2026/03/15/foto-00001.jpg | kapsam disi

Red gerekceleri ayri: biri imzadan, biri saatten, ikisi kanonik dizeye yazilan alanlardan geliyor.
Imza yalnizca baglantinin degistirilmedigini soyluyor; ne kadar yasadigini ve neyi actigini
kapsam ve son alanlari soyluyor — ikisi de imzanin icinde, disaridan degistirilemiyor.
```

Yedi deneme dört denetimi ayrı ayrı gösteriyor. On beş dakikalık bağlantı üç yüzüncü saniyede
geçerlidir, bin ikiyüzüncü saniyede "süresi 300 sn önce doldu" der — süre bir öneri değil,
doğrulamanın parçasıdır. Aynı bağlantıyla komşu nesne istendiğinde kapsam denetimi devreye girer;
okuma bağlantısıyla yazma denendiğinde yöntem denetimi. İmzanın son basamağı değiştirildiğinde
dördü de çalışmaz, imza denetiminde durur.

Ayrım önemlidir. İmza yalnız bir şey söyler: bağlantı üretildikten sonra **değiştirilmemiştir**.
Bağlantının ne kadar yaşadığını ve neyi açtığını söyleyen şey imza değil, kanonik dizeye yazılan
kapsam ve son geçerlilik alanlarıdır. Bu alanlar imzanın içinde olduğu için dışarıdan
değiştirilemez; ama içeriklerini üretim anında **kim yazıyorsa** erişimin sınırını da o çiziyor.
Bağlantı üretmek bir yetki devretme işlemidir ve iki sayıya iner: ömür ve kapsam.

#### Ömür ve Kapsam

- **DT40** — Saha uygulamasının iş yükü modeldir: günde 12.000 oturum, oturum 1.500 saniye, ekran on
  sekiz kez yenileniyor, ekranda kırk fotoğraf.
- **DT41** — Sızma oranı kurgudur: üretilen bağlantıların 200.000'de biri günlüğe, adres çubuğuna ya
  da paylaşıma sızar. Bir imza üretimi modelde 0,012 ms işlemci süresi harcar.

```js
// imza/omur.mjs — baglantinin omru ve kapsami taranir: yeniden uretme yuku, sizinti penceresi,
// iptal patlamasi. Is yuku ve oranlar MODELDIR, rastgelelik yok.
const OTURUM = 12_000, OTURUM_SN = 1500, YENILEME = 18, EKRAN_FOTO = 40;
const SIZMA_ORANI = 1 / 200_000;                    // uretilen baglantilarin sizan payi (kurgu)
const IMZA_MS = 0.012;                              // modelde bir imza uretiminin islemci suresi
const KAPSAM = {                                    // sizan tek baglantinin actigi yuzey
  "tek nesne": { nesne: 1, gib: 0.0035 },
  "bir gunun oneki": { nesne: 3_500, gib: 12.3 },
  "kovanin tamami": { nesne: 1_678_000, gib: 184.8 },
};
const CIKIS_INTERNET = 0.085;                       // B/GiB, kurgu
const OMUR = [60, 300, 1800, 7200, 86_400, 604_800];
const g = (x, n, d = 2) => x.toFixed(d).padStart(n);
const s = (x, n) => String(x).padStart(n);
const uretim = (ttl) => OTURUM * EKRAN_FOTO * Math.min(YENILEME, Math.ceil(OTURUM_SN / ttl));

console.log(`${OTURUM} oturum/gun, oturum ${OTURUM_SN} sn, ekran ${YENILEME} kez yenileniyor, ` +
  `ekranda ${EKRAN_FOTO} fotograf. Sizma orani 1/${(1 / SIZMA_ORANI).toLocaleString("tr")} (kurgu).`);
console.log("\nomur      | uretilen baglanti/gun | islemci sn/gun | sizan/gun | acik nesne-saat | ayni anda gecerli");
console.log("----------|-----------------------|----------------|-----------|-----------------|------------------");
const U = {};
for (const ttl of OMUR) {
  const u = U[ttl] = uretim(ttl), sizan = u * SIZMA_ORANI;
  console.log(`${s(ttl + " sn", 9)} | ${s(u.toLocaleString("tr"), 21)} | ${g(u * IMZA_MS / 1000, 14, 1)} | ` +
    `${g(sizan, 9, 1)} | ${g(sizan * ttl / 3600, 15, 2)} | ${s(Math.round(u / 86400 * ttl).toLocaleString("tr"), 17)}`);
}
const dirsek = OMUR.find((t) => U[t] === U[OMUR[OMUR.length - 1]]);
console.log(`dirsek ${dirsek} sn: bu noktadan sonra uretim ${U[dirsek].toLocaleString("tr")}/gun'de sabitleniyor, ` +
  `ama acik pencere buyumeye devam ediyor —`);
console.log(`  ${dirsek} sn'de ${g(U[dirsek] * SIZMA_ORANI * dirsek / 3600, 0, 2)} nesne-saat, ` +
  `604800 sn'de ${g(U[604800] * SIZMA_ORANI * 604800 / 3600, 0, 2)} nesne-saat: ` +
  `${(U[604800] * 604800 / (U[dirsek] * dirsek)).toFixed(0)} kat. Uzun omur artik hicbir sey kazandirmiyor.`);

console.log("\nkapsam genisligi — tek baglanti sizarsa:");
console.log("kapsam           | acilan nesne | acilan GiB | tamami indirilirse cikis");
console.log("-----------------|--------------|------------|--------------------------");
for (const [ad, k] of Object.entries(KAPSAM))
  console.log(`${ad.padEnd(16)} | ${s(k.nesne.toLocaleString("tr"), 12)} | ${g(k.gib, 10, 3)} | ` +
    `${g(k.gib * CIKIS_INTERNET, 25)} birim`);
console.log(`kapsami tek nesneden kovaya genisletmek, tek bir sizintinin actigi yuzeyi ` +
  `${(KAPSAM["kovanin tamami"].nesne / KAPSAM["tek nesne"].nesne).toLocaleString("tr")} kat buyutuyor.`);

console.log("\niptal edilebilirlik: imzali baglanti geri alinamaz, suresi dolana kadar gecerlidir.");
console.log("Tek yol imza anahtarini dondurmektir; bu, o an gecerli butun baglantilari birden kirar:");
for (const ttl of [1800, 86_400, 604_800])
  console.log(`  omur ${s(ttl + " sn", 9)} -> anahtar dondugunde ${s(Math.round(U[ttl] / 86400 * ttl).toLocaleString("tr"), 9)} ` +
    `baglanti kiriliyor; sizan tek baglanti icin odenen bedel bu.`);

// Iki eksen birlikte: sizan baglantinin actigi yuzey omur ile kapsamin carpimidir.
console.log("\nomur x kapsam — gunluk acilan nesne-saat (sizan baglanti sayisi x omur x kapsamdaki nesne):");
console.log("omur      |" + Object.keys(KAPSAM).map((a) => a.padStart(17)).join(" |"));
console.log("----------|" + Object.keys(KAPSAM).map(() => "-".repeat(18)).join("|"));
for (const ttl of [300, 1800, 86_400, 604_800]) {
  const sizan = U[ttl] * SIZMA_ORANI;
  console.log(`${s(ttl + " sn", 9)} |` + Object.values(KAPSAM)
    .map((k) => g(sizan * ttl / 3600 * k.nesne, 17, 1)).join(" |"));
}
console.log("Kisa omur ile dar kapsam ayni yonde calisiyor: ikisi de carpimin bir carpanini kuculttugu icin");
console.log("etkileri toplanmiyor, carpiliyor — 300 sn ve tek nesne ile 604800 sn ve kova arasindaki fark budur.");
```

```
12000 oturum/gun, oturum 1500 sn, ekran 18 kez yenileniyor, ekranda 40 fotograf. Sizma orani 1/200.000 (kurgu).

omur      | uretilen baglanti/gun | islemci sn/gun | sizan/gun | acik nesne-saat | ayni anda gecerli
----------|-----------------------|----------------|-----------|-----------------|------------------
    60 sn |             8.640.000 |          103.7 |      43.2 |            0.72 |             6.000
   300 sn |             2.400.000 |           28.8 |      12.0 |            1.00 |             8.333
  1800 sn |               480.000 |            5.8 |       2.4 |            1.20 |            10.000
  7200 sn |               480.000 |            5.8 |       2.4 |            4.80 |            40.000
 86400 sn |               480.000 |            5.8 |       2.4 |           57.60 |           480.000
604800 sn |               480.000 |            5.8 |       2.4 |          403.20 |         3.360.000
dirsek 1800 sn: bu noktadan sonra uretim 480.000/gun'de sabitleniyor, ama acik pencere buyumeye devam ediyor —
  1800 sn'de 1.20 nesne-saat, 604800 sn'de 403.20 nesne-saat: 336 kat. Uzun omur artik hicbir sey kazandirmiyor.

kapsam genisligi — tek baglanti sizarsa:
kapsam           | acilan nesne | acilan GiB | tamami indirilirse cikis
-----------------|--------------|------------|--------------------------
tek nesne        |            1 |      0.004 |                      0.00 birim
bir gunun oneki  |        3.500 |     12.300 |                      1.05 birim
kovanin tamami   |    1.678.000 |    184.800 |                     15.71 birim
kapsami tek nesneden kovaya genisletmek, tek bir sizintinin actigi yuzeyi 1.678.000 kat buyutuyor.

iptal edilebilirlik: imzali baglanti geri alinamaz, suresi dolana kadar gecerlidir.
Tek yol imza anahtarini dondurmektir; bu, o an gecerli butun baglantilari birden kirar:
  omur   1800 sn -> anahtar dondugunde    10.000 baglanti kiriliyor; sizan tek baglanti icin odenen bedel bu.
  omur  86400 sn -> anahtar dondugunde   480.000 baglanti kiriliyor; sizan tek baglanti icin odenen bedel bu.
  omur 604800 sn -> anahtar dondugunde 3.360.000 baglanti kiriliyor; sizan tek baglanti icin odenen bedel bu.

omur x kapsam — gunluk acilan nesne-saat (sizan baglanti sayisi x omur x kapsamdaki nesne):
omur      |        tek nesne |  bir gunun oneki |   kovanin tamami
----------|------------------|------------------|------------------
   300 sn |              1.0 |           3500.0 |        1678000.0
  1800 sn |              1.2 |           4200.0 |        2013600.0
 86400 sn |             57.6 |         201600.0 |       96652800.0
604800 sn |            403.2 |        1411200.0 |      676569600.0
Kisa omur ile dar kapsam ayni yonde calisiyor: ikisi de carpimin bir carpanini kuculttugu icin
etkileri toplanmiyor, carpiliyor — 300 sn ve tek nesne ile 604800 sn ve kova arasindaki fark budur.
```

Ömür taraması iki sütun arasında bir denge arıyor. Altmış saniyelik bağlantıda günde 8.640.000 imza
üretilir; işlemci maliyeti 103,7 saniye/gündür ve açık pencere 0,72 nesne-saattir. Ömür uzadıkça
üretim düşer, ama düşüşün bir dibi vardır: 1.800 saniyeden sonra üretim 480.000'de sabitlenir çünkü
bir bağlantı zaten bir oturumun tamamını kapsar. **Dirsek burasıdır.** Bu noktadan sonra ömrü
uzatmak hiçbir yük azaltmaz; açık pencere ise büyümeye devam eder — 1.800 saniyede 1,20 nesne-saat,
604.800 saniyede 403,20 nesne-saat, 336 kat. Yedi günlük bağlantı, otuz dakikalık bağlantının
kazandırmadığı bir şey için üç yüz otuz altı kat risk taşır.

Kapsam ikinci eksendir ve ölçeği farklıdır. Sızan tek bir bağlantı, kapsamı tek nesneyse bir nesne
açar; bir günün öneğiyse 3.500 nesne ve 12,3 GiB; kova tamamıysa 1.678.000 nesne ve 184,8 GiB. Bu
kursun bütün baytı, tek bir dizede. Aradaki fark 1.678.000 kattır ve bağlantıyı üretmenin zorluğu
üçünde de aynıdır. Önek kapsamı çoğu zaman kolaylık olsun diye seçilir — tek istek bütün ekranı
doldurur — ama kolaylığın karşılığı, sızıntı hâlinde açılan yüzeyin binlerce katına çıkmasıdır.

Son tablo iki ekseni tek sayıda birleştiriyor: günlük açılan nesne-saat, sızan bağlantı sayısı ile
ömrün ve kapsamdaki nesne sayısının çarpımıdır. Beş dakikalık ömür ve tek nesne kapsamında bu sayı
1,0'dır; yedi günlük ömür ve kova kapsamında 676.569.600. İki ekseni de gevşetmek riski toplamaz,
**çarpar**; ikisini de sıkmak da aynı biçimde çarparak azaltır. Bu yüzden "bağlantı ömrünü kısa
tuttuk" tek başına bir önlem değildir, kapsam da daraltılmadıkça çarpanın yalnız biri küçülmüştür.

#### İptal Edilemezlik

- **DT42** — Bu modelde imzalı bağlantı iptal edilemez; tek yol imza anahtarını döndürmektir ve
  bu, o an geçerli bütün bağlantıları birden kırar. Kimi sağlayıcı bağlantıyı adlandırılmış bir
  erişim politikasına bağlayarak seçici iptal sunar; bu ders o mekanizmayı kullanmaz.

Son blok bu türün en sert kalemini yazıyor. Bir bağlantının sızdığı fark edildiğinde yapılabilecek
hiçbir şey yoktur: bağlantı, süresi dolana kadar geçerlidir. Kimlik yoktur ki askıya alınsın, oturum
yoktur ki kapatılsın. Tek kaldıraç imza anahtarını döndürmektir ve o kaldıraç seçici değildir. Otuz
dakikalık ömürde anahtar döndürmek 10.000 bağlantıyı kırar; yirmi dört saatlik ömürde 480.000, yedi
günlük ömürde 3.360.000. Tek bir sızıntının bedeli, o anda dolaşımdaki bütün bağlantıların
kırılmasıdır — ve kullanıcı tarafında bu, ekranların boş gelmesi demektir.

Bu, ömür seçiminin neden bir güvenlik ayarı olmadığını açıklıyor: ömür aynı anda **iptal
maliyetidir**. Kısa ömür sızıntı penceresini de, iptal patlamasını da küçültür; iki kolonu birden
aşağı çeker. Dirsek noktasının anlamı da budur — 1.800 saniye, yeniden üretme yükünün dibe vurduğu
ve iki riskin de en küçük kaldığı yerdir.

Devredilen karar tarafı burada dardır. Sağlayıcı yalnız doğrulamayı yapar: imzayı yeniden hesaplar,
saate bakar, kapsamı karşılaştırır. Kimin ne kadar süreyle neye erişeceği baştan sona elde kalır ve
bu kursun ölçüsüne göre üçü de geri alınamaz — üretilmiş bir bağlantının ömrü kısaltılamaz, kapsamı
daraltılamaz, kendisi iptal edilemez. Çıkış tarafı da açıktır: sızan bir kova bağlantısı 184,8
GiB'in tamamının indirilmesine izin verir, karşılığında 15,71 birim çıkış ücreti doğar ve fatura
sızıntıyı bulmadan önce gelir.

#### Özet

- İmzalı bağlantı dört denetimden geçer: imza, süre, yöntem ve kapsam. İmza yalnız bağlantının
  değiştirilmediğini söyler; ne kadar yaşadığını ve neyi açtığını kanonik dizedeki alanlar söyler.
- Ömür taramasının bir dirseği vardır: 1.800 saniyeden sonra üretim 480.000/günde sabitlenir, ömrü
  uzatmak hiçbir yük azaltmaz.
- Açık pencere ömürle doğru orantılı büyür: 1,20 nesne-saatten 403,20 nesne-saate, 336 kat. Yedi
  günlük bağlantı, kazandırmadığı bir şey için bu farkı taşır.
- Kapsam sızıntının ölçeğini belirler: tek nesne 1, bir günün öneği 3.500, kova tamamı 1.678.000
  nesne ve 184,8 GiB açar; tamamı indirilirse 15,71 birim çıkış ücreti doğar.
- Geri alınamayan kalem bağlantının kendisidir: iptal edilemez, süresi dolana kadar geçerlidir. Tek
  kaldıraç anahtar döndürmektir ve otuz dakikalık ömürde 10.000, yedi günlük ömürde 3.360.000
  bağlantıyı birden kırar.

#### Sonraki Adım

Bu konu iki soruyu kapattı: veri nereye konacak ve ona kim erişecek. Kurgu ölçüm ağının sayaç
okumaları, fatura belgeleri, saha fotoğrafları ve iş emri kayıtları artık türüne göre yerleşmiş,
sınıfı seçilmiş, yaşam döngüsü yazılmış ve erişimi süreli bağlantılarla verilmiş durumda. Bir kalem
hâlâ dışarıda duruyor ve altı derstir kenardan geçiyor: bu verinin **sorgulanan** kısmı. Tarife
tabloları, iş emri durumları ve fatura satırları bir nesne deposunda değil, bir örneğe elle kurulmuş
bir veritabanında duruyor — yedeğini bir zamanlanmış görev alıyor, sürüm yükseltmesini biri elle
yapıyor, tek kopya çalışıyor. Sonraki konu bu katmanı kiralamayı ölçer: veritabanı bir hizmet olarak
alındığında hangi karar devredilir, hangisi elde kalır ve devredilenlerin hangisi geri alınamaz.

## Yönetilen Veri Servisleri

Veritabanının işletiminin devredilmesi: yönetilen ilişkisel veritabanında yedekleme, yama ve devralma otomasyonunun devraldığı kararlar, okuma kopyalarıyla okuma yükünün dağıtılması ve gecikmenin bedeli, bölüm anahtarı ile kapasite modelinin erişim örüntüsünü belirlemesi, ikincil dizinler ve değişim akışları, yönetilen önbellek servisi, bölge ve internet çıkışının ücretlendirilmesi ile anlık görüntü ve zaman noktasına dönüş.

### Yönetilen İlişkisel Veritabanı

Source: https://academia.sh/tr/kurslar/bulut-depolama/yonetilen-iliskisel-veritabani

Elle işletilen bir ilişkisel veritabanı ile yönetilen hizmetin kalem kalem karşılaştırılması: yirmi sekiz kararın kaçının sağlayıcıya devredildiği, kaçının elde kaldığı ve kaçının hiç erişilemez hâle geldiği sayılır, elde kalan kalemlerin kaç tanesinin tek yönlü olduğu ayrılır, devralma penceresi sağlayıcı payı ile uygulama payına bölünüp düşen istek sayısı beş önbellek ömründe ölçülür ve verinin çıkışı mantıksal dışa aktarım süresi ile çıkış ücreti olarak hesaplanır.

Önceki konu nesnelerin nereye konacağını ve o nesnelere kimin, ne kadar süreyle erişeceğini
sayılarla çözdü. Geriye sorulmamış bir şey kaldı: sayaç okumalarının özetlendiği, iş emirlerinin
durum değiştirdiği ve fatura belgelerinin bağlandığı **sorgulanan** veri hâlâ elle kurulmuş bir
ilişkisel veritabanında duruyor. O veritabanının makinesi kiralanmış olabilir, ama yedeği alan,
yamasını geçen, arıza anında ikinciyi birinci yapan hâlâ bir insan.

Bu dersin sorusu "yönetilen hizmet daha iyi mi" değil. Ölçülecek şey daha dar ve daha somut:
veritabanı kiralandığında **hangi kararlar el değiştiriyor**. Karar üç yere gidebilir —
sağlayıcıya devredilir, elde kalır, ya da hiç kimsede kalmaz: erişilemez hâle gelir. Üçüncü küme
bu dersin asıl konusudur, çünkü kendi işlettiğin veritabanında böyle bir küme yoktur.

#### Karar Üç Kümeye Ayrılır

Elle işletilen bir veritabanında yirmi sekiz kalemin yirmi sekizi de eldedir: donanımın hangi
diskle kurulacağı da, çekirdek ayarının ne olacağı da. Yönetilen hizmet bu listeyi böler.
**Devredilen** kalemler artık sağlayıcının işidir ve sonucundan o sorumludur. **Elde kalan**
kalemler ayar olarak durur; değiştirilebilir. **Erişilemez** kalemler ne devredilmiştir ne
eldedir: ayar yüzeyinden çıkarılmıştır, sağlayıcı bir sayı seçmiştir ve o sayı görülmez.

Bu ayrım soyut değildir. Bir arıza gecesinde erişilemez sütundaki bir kalem, gecenin ne kadar
süreceğini belirler ve o kaleme dokunulamaz.

Kataloğu kurarken tek ölçüt kullanıldı: kalemi değiştirmek için ne yapmak gerekir. Bir istekle
değişiyorsa elde, sağlayıcının bir bildirimiyle değişiyorsa devredilmiş, hiçbir yoldan
değişmiyorsa erişilemez sayıldı. Sınır kimi kalemlerde incedir — yedekleme sıklığı elde ama
yedeğin nasıl alındığı devredilmiş, disk büyütme elde ama küçültme erişilemez. Bu incelik
kataloğun kusuru değil, ölçülen şeyin kendisidir: yönetilen hizmet kararları tek parça hâlinde
almaz, **her kalemi ayrı ayrı böler**.

#### Düzenek

**YV1 — kurgu bölgesel ölçüm ağının iş emri veritabanı 220 GB'dir ve saniyede 1.400 istek
alır.** Bütün sayılar kurgudur. **YV2 — sağlık denetimi 5 saniyede bir koşar, üst üste üç
başarısız denetim devralmayı tetikler ve ilk denetim arızadan 2,4 saniye sonraya düşer.** **YV3 —
kopyanın birincile yükseltilmesi 20 saniye sürer.** **YV4 — uygulama tarafında uç nokta adının
çözümleme önbelleği T saniye yaşar; on altı uygulama örneğinin yenileme anları T aralığına eşit
yayılmıştır.** **YV5 — her örnek 120 bağlantılık bir havuz taşır, bir bağlantı 25 ms'de kurulur
ve sekiz bağlantı koşut kurulabilir.** **YV6 — çıkış ücreti kurgu birimdir: bölge içi 0,
bölgeler arası 2, internet 9 birim/GB.** YV2 ve YV3 sağlayıcının, YV4 ve YV5 uygulamanın
tarafındadır; ölçüm bu sınırı ortaya çıkarmak için kurulmuştur.

```js
// yv/model.mjs — yonetilen iliskisel veritabani MODELI. Kurgu bolgesel olcum aginin is emri
// veritabani uzerinde tanimli karar katalogu ve devralma zaman cizelgesi. Gercek bir urun ya da
// olcum degil; rastgelelik yoktur, her kosumda ayni sayilar cikar.
// Ucuncu sutun: karar yonetilen hizmette KIMDE. Dorduncu sutun: geri alinabilir mi.
export const KARAR = [
  ["donanim secimi ve yerlesimi", "devredildi", true],
  ["isletim sistemi yamasi", "devredildi", true],
  ["kucuk surum yamasi", "devredildi", true],
  ["yedek alma bicimi", "devredildi", true],
  ["anlik goruntu deposu", "devredildi", true],
  ["zaman noktasina donus altyapisi", "devredildi", true],
  ["bellek havuzu boyutu", "devredildi", true],
  ["cogaltma duzeni", "devredildi", true],
  ["ana surum yukseltme karari", "elde", false],
  ["yama penceresi", "elde", true],
  ["yedekleme sikligi", "elde", true],
  ["yedek saklama suresi", "elde", true],
  ["devralmayi elle tetikleme", "elde", true],
  ["baglanti ust siniri", "elde", true],
  ["planlayici maliyet ayarlari", "elde", true],
  ["listedeki uzantinin kurulmasi", "elde", true],
  ["disk buyutme", "elde", false],
  ["yerlesim bolgesi secimi", "elde", false],
  ["karakter kumesi ve harmanlama", "elde", false],
  ["kabuk erisimi", "erisilemez", null],
  ["dosya sistemi duzeni", "erisilemez", null],
  ["veri dizini yolu", "erisilemez", null],
  ["devralma esigi", "erisilemez", null],
  ["yazma onu gunlugu esigi", "erisilemez", null],
  ["listede olmayan uzanti", "erisilemez", null],
  ["disk kucultme", "erisilemez", null],
  ["gunluk dosyalarina dogrudan erisim", "erisilemez", null],
  ["cekirdek ayari", "erisilemez", null],
];

// Devralma zaman cizelgesi. Saglayicinin belirledigi iki adim sabittir; ucuncu adim uygulamanin
// cozumleyici onbellek omrune (T) baglidir ve ORNEK BASINA degisir.
export const SAGLIK_ARALIK = 5, SAGLIK_FAZ = 2.4, ESIK = 3, YUKSELTME = 20;
export const ORNEK = 16, ISTEK = 1400, HAVUZ = 120, BAGLANTI_MS = 25, KOSUT = 8;

export const algilama = () => SAGLIK_FAZ + (ESIK - 1) * SAGLIK_ARALIK;
export const havuzKurma = () => (HAVUZ * BAGLANTI_MS) / KOSUT / 1000;

// Her uygulama ornegi kendi onbellegini farkli anda yeniler; fazlar T araligina esit yayilmistir.
// Ornek, yukseltme bittikten SONRAKI ilk yenilemede yeni ucu ogrenir, sonra havuzunu kurar.
export function devralma(T) {
  const hazirlik = algilama() + YUKSELTME;
  const ornekler = [];
  for (let i = 0; i < ORNEK; i += 1) {
    const faz = (i * T) / ORNEK;
    const ogrenme = faz + T * Math.max(0, Math.ceil((hazirlik - faz) / T));
    ornekler.push(ogrenme + havuzKurma());
  }
  const dusen = ornekler.reduce((t, x) => t + x * (ISTEK / ORNEK), 0);
  return { hazirlik, enKotu: Math.max(...ornekler),
    ortalama: ornekler.reduce((a, b) => a + b, 0) / ORNEK, dusen: Math.round(dusen) };
}
```

```js
// yv/olc.mjs — devredilen karar sayimi ve devralma penceresi
import { KARAR, devralma, algilama, havuzKurma, ORNEK, ISTEK, HAVUZ, YUKSELTME } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const say = (k) => KARAR.filter(([, v]) => v === k).length;
console.log(`karar katalogu: ${KARAR.length} kalem. Kendi islettigin veritabaninda hepsi elde.\n`);
console.log("yonetilen hizmette      | kalem | pay   | ornek");
console.log("------------------------|-------|-------|--------------------------------------------");
for (const k of ["devredildi", "elde", "erisilemez"]) {
  const liste = KARAR.filter(([, v]) => v === k).map(([a]) => a);
  console.log(`${k.padEnd(23)} | ${s(liste.length, 5)} | ` +
    `${s("%" + (100 * liste.length / KARAR.length).toFixed(1), 5)} | ${liste.slice(0, 2).join(", ")}`);
}
const geriAlinamaz = KARAR.filter(([, v, g]) => v === "elde" && g === false);
console.log(`\nelde kalan ${say("elde")} kalemin ${geriAlinamaz.length} tanesi tek yonludur:`);
for (const [a] of geriAlinamaz) console.log(`  - ${a}`);
console.log(`erisilemez ${say("erisilemez")} kalem, kendi islettiginde ayar; burada hic yok.\n`);

console.log(`devralma: saglik denetimi ile algilama ${algilama().toFixed(1)} sn, yukseltme ` +
  `${YUKSELTME} sn -> saglayici payi ${(algilama() + YUKSELTME).toFixed(1)} sn (sabit).`);
console.log(`havuz kurma ${(havuzKurma() * 1000).toFixed(0)} ms, ${ORNEK} ornek x ${HAVUZ} ` +
  `baglanti = ${ORNEK * HAVUZ} yeni baglanti yeni birincile ayni anda gelir.`);
console.log(`istek hizi ${ISTEK}/sn; devralma boyunca hepsi duser.\n`);
console.log("onbellek omru T | saglayici payi | uygulama payi | kesinti (ort) | kesinti (en kotu) | dusen istek");
console.log("----------------|----------------|---------------|---------------|-------------------|------------");
for (const T of [5, 15, 30, 60, 120]) {
  const r = devralma(T);
  console.log(`${s(T + " sn", 15)} | ${s(r.hazirlik.toFixed(1) + " sn", 14)} | ` +
    `${s((r.ortalama - r.hazirlik).toFixed(1) + " sn", 13)} | ${s(r.ortalama.toFixed(1) + " sn", 13)} | ` +
    `${s(r.enKotu.toFixed(1) + " sn", 17)} | ${s(r.dusen, 11)}`);
}
const a = devralma(5), b = devralma(120);
console.log(`\nkosumdan bagimsiz: saglayici payi ${a.hazirlik.toFixed(1)} sn ile sabit; T 5'ten 120'ye ` +
  `cikinca kesinti ${a.ortalama.toFixed(1)} -> ${b.ortalama.toFixed(1)} sn, dusen istek ` +
  `${a.dusen} -> ${b.dusen}.`);
console.log(`devralma esigi erisilemez oldugu icin algilama suresi kisaltilamaz; kisaltilabilen tek ` +
  `sey uygulama tarafindaki T.`);

// Cikis: anlik goruntu bicimi erisilemez oldugu icin veri ancak MANTIKSAL disa aktarimla cikar.
const BOYUT_GB = 220, OKUMA_MBS = 40, YUKLEME_MBS = 26, TARIFE = { "bolge ici": 0, "bolgeler arasi": 2, "internet": 9 };
const saat = (mbs) => (BOYUT_GB * 1024) / mbs / 3600;
console.log(`\ncikis: ${BOYUT_GB} GB is emri verisi, mantiksal disa aktarim ${OKUMA_MBS} MB/sn, ` +
  `geri yukleme ${YUKLEME_MBS} MB/sn (indeksler yeniden kurulur).`);
console.log(`sure: disa aktarim ${saat(OKUMA_MBS).toFixed(2)} sa + yukleme ${saat(YUKLEME_MBS).toFixed(2)} sa = ` +
  `${(saat(OKUMA_MBS) + saat(YUKLEME_MBS)).toFixed(2)} sa. Anlik goruntu tasinamaz: bicim erisilemez sutunundadir.`);
console.log("hedef            | cikis ucreti (kurgu birim/GB) | toplam (kurgu birim)");
console.log("-----------------|-------------------------------|---------------------");
for (const [ad, birim] of Object.entries(TARIFE))
  console.log(`${ad.padEnd(16)} | ${s(birim, 29)} | ${s(birim * BOYUT_GB, 20)}`);
```

```
karar katalogu: 28 kalem. Kendi islettigin veritabaninda hepsi elde.

yonetilen hizmette      | kalem | pay   | ornek
------------------------|-------|-------|--------------------------------------------
devredildi              |     8 | %28.6 | donanim secimi ve yerlesimi, isletim sistemi yamasi
elde                    |    11 | %39.3 | ana surum yukseltme karari, yama penceresi
erisilemez              |     9 | %32.1 | kabuk erisimi, dosya sistemi duzeni

elde kalan 11 kalemin 4 tanesi tek yonludur:
  - ana surum yukseltme karari
  - disk buyutme
  - yerlesim bolgesi secimi
  - karakter kumesi ve harmanlama
erisilemez 9 kalem, kendi islettiginde ayar; burada hic yok.

devralma: saglik denetimi ile algilama 12.4 sn, yukseltme 20 sn -> saglayici payi 32.4 sn (sabit).
havuz kurma 375 ms, 16 ornek x 120 baglanti = 1920 yeni baglanti yeni birincile ayni anda gelir.
istek hizi 1400/sn; devralma boyunca hepsi duser.

onbellek omru T | saglayici payi | uygulama payi | kesinti (ort) | kesinti (en kotu) | dusen istek
----------------|----------------|---------------|---------------|-------------------|------------
           5 sn |        32.4 sn |        2.8 sn |       35.2 sn |           37.6 sn |       49306
          15 sn |        32.4 sn |        7.8 sn |       40.2 sn |           47.3 sn |       56306
          30 sn |        32.4 sn |       15.8 sn |       48.2 sn |           62.3 sn |       67463
          60 sn |        32.4 sn |       29.9 sn |       62.3 sn |           90.4 sn |       87150
         120 sn |        32.4 sn |       61.7 sn |       94.1 sn |          150.4 sn |      131775

kosumdan bagimsiz: saglayici payi 32.4 sn ile sabit; T 5'ten 120'ye cikinca kesinti 35.2 -> 94.1 sn, dusen istek 49306 -> 131775.
devralma esigi erisilemez oldugu icin algilama suresi kisaltilamaz; kisaltilabilen tek sey uygulama tarafindaki T.

cikis: 220 GB is emri verisi, mantiksal disa aktarim 40 MB/sn, geri yukleme 26 MB/sn (indeksler yeniden kurulur).
sure: disa aktarim 1.56 sa + yukleme 2.41 sa = 3.97 sa. Anlik goruntu tasinamaz: bicim erisilemez sutunundadir.
hedef            | cikis ucreti (kurgu birim/GB) | toplam (kurgu birim)
-----------------|-------------------------------|---------------------
bolge ici        |                             0 |                    0
bolgeler arasi   |                             2 |                  440
internet         |                             9 |                 1980
```

#### Erişilemez Sütun En Kalabalık İkinci Kümedir

Devredilen kalem sayısı 8, yani kataloğun yüzde 28,6'sı. Yönetilen hizmete geçmenin sattığı şey
bu sütundur ve içindekiler gerçekten iş yükünü azaltır: işletim sistemi yaması, küçük sürüm
yaması, yedek alma biçimi, çoğaltma düzeni artık başkasının gece nöbetidir.

Beklenmedik olan üçüncü sütundur: **9 kalem, yüzde 32,1**. Bu kalemler devredilmedi; ortadan
kalktı. Kabuk erişimi yok, veri dizini yolu yok, günlük dosyalarına doğrudan bakılamıyor. Bunların
bir kısmı yokluğunda fark edilmez. Bir kısmı, kaybedildiği gün fark edilir: **devralma eşiği**
bu sütundadır. Sağlık denetiminin kaç saniyede bir koştuğu ve kaç başarısızlıktan sonra devralma
tetiklendiği okunamaz, ayarlanamaz. Aynı sütunda **yazma önü günlüğü eşiği** ve **listede olmayan
uzantı** var: uygulamanın ihtiyaç duyduğu bir uzantı sağlayıcının listesinde yoksa, kurulmasının
yolu yoktur — kendi işlettiğin veritabanında bu bir paket kurma işidir.

Elde kalan 11 kalem ise yanıltıcı bir rahatlık verir. Dördü **tek yönlüdür**: ana sürüm
yükseltmesinden geri dönülmez, büyütülen disk küçültülmez, seçilen yerleşim bölgesi veri
taşımadan değişmez ve karakter kümesiyle harmanlama seçimi tabloları yeniden yazmadan
düzeltilmez. Bu dördü kurulum ekranında birer açılır listedir; sonuçları veritabanının ömrü
boyunca sürer.

#### Devralmanın Ölçülen Yanı Kesinti Değil, Kesintinin Kime Ait Olduğudur

Devralma yönetilen hizmetin en çok anlatılan özelliğidir ve genellikle tek bir sayıyla anılır.
Tablo o tek sayının iki parçadan oluştuğunu gösteriyor.

**Sağlayıcı payı beş satırda da 32,4 saniyedir.** Algılama 12,4 saniye (2,4 saniyelik faz artı iki
denetim aralığı), yükseltme 20 saniye. Bu sayı hiçbir ayarla değişmez, çünkü onu üreten kalem
erişilemez sütunundadır.

**Uygulama payı 2,8 saniyeden 61,7 saniyeye çıkıyor.** Fark yalnızca uç nokta adının çözümleme
önbelleğinin ömründen geliyor. T 5 saniyeyken ortalama kesinti 35,2 saniye ve 49.306 istek düşüyor;
T 120 saniyeyken ortalama 94,1 saniye ve 131.775 istek düşüyor. Aynı devralma, aynı sağlayıcı,
2,67 katı kayıp. En kötü örnek sütunu daha da açıktır: T 120'de bir uygulama örneği 150,4 saniye
boyunca ölü bir adrese bağlanmayı deniyor.

Buradan çıkan kural devredilen kararın sınırını çiziyor: **devralma devredildi, devralmanın
uygulamada bittiği an devredilmedi.** Havuz satırı da aynı yere bakıyor — on altı örnek ayağa
kalktığında yeni birincil 1.920 bağlantı isteğini aynı anda karşılar; bağlantı üst sınırı elde
kalan kalemlerdendir ve bu sayının altındaysa devralma, devralmanın kendisiyle biten bir kesintiye
dönüşür.

#### Çıkışın Bedeli Biçimin Kilitli Olmasıdır

Son blok kursun tekrar eden kalemini bu derse uyguluyor. Veriyi başka bir yere taşımak
gerektiğinde anlık görüntü işe yaramaz: anlık görüntü biçimi devredilen sütunda alınıp erişilemez
sütununda okunamaz hâle gelir. Geriye tek yol kalır, **mantıksal dışa aktarım**: 220 GB veri 40
MB/sn ile 1,56 saatte çıkar, hedefte 26 MB/sn ile 2,41 saatte yüklenir — indeksler yeniden
kurulduğu için yükleme okumadan yavaştır. Toplam 3,97 saat, üstüne çıkış ücreti: bölge içinde 0,
bölgeler arasında 440, internet üzerinden 1.980 kurgu birim.

Bu üç sayının oranı kursun sonuna kadar aynı kalacak. Veri girerken hiçbir ücret ödemedi; aynı
verinin dışarı çıkması bölge sınırını geçtiği anda ücretlendi. Sürenin kendisi de bir bedeldir:
3,97 saat boyunca ya iki dizge koşut yazılır ve aradaki fark elle kapatılır, ya da iş emri
kayıtları donar. Yerleşim bölgesinin tek yönlü kalemler arasında sayılmasının sebebi budur —
bölge değiştirmek, bu dört saatlik pencereyi bir kez daha ödemek demektir.

#### Özet

- Yirmi sekiz kararın 8'i sağlayıcıya devredildi, 11'i elde kaldı, **9'u erişilemez hâle geldi**;
  üçüncü küme kendi işlettiğin veritabanında yoktur.
- Elde kalan 11 kalemin 4'ü tek yönlüdür: ana sürüm yükseltmesi, disk büyütme, yerleşim bölgesi ve
  harmanlama seçimi veri yeniden yazılmadan geri alınmaz.
- Devralma kesintisinin 32,4 saniyesi sağlayıcının payıdır ve sabittir; devralma eşiği erişilemez
  olduğu için kısaltılamaz.
- Uygulama payı 2,8 saniyeden 61,7 saniyeye çıkabiliyor: aynı devralmada düşen istek 49.306'dan
  131.775'e, en kötü örnekteki kesinti 37,6 saniyeden 150,4 saniyeye yükseliyor.
- Anlık görüntü biçimi erişilemez olduğu için çıkış mantıksal dışa aktarıma zorlar: 220 GB için
  3,97 saat, artı internet üzerinden 1.980 kurgu birim çıkış ücreti.

#### Sonraki Adım

Bu ders tek bir birincil veritabanı varsayarak ölçüm yaptı: devralma anında yükü karşılayacak
başka bir kopya yoktu, ikinci makine yalnızca beklemedeydi. Oysa iş emri veritabanının istek
karışımının büyük bölümü okumadır — sayaç okuma özetleri, fatura sorguları, saha fotoğrafı
kütükleri. Bekleyen bir kopyayı okumaya açmak yükü dağıtır, ama o kopya birincilin gerisinde
kalır. Sonraki ders bu gecikmeyi tarar ve her değerde kaç okumanın bayat döndüğünü sayar; ardından
"kendi yazdığını oku" gereksinimi olan istekleri ayırıp birincile yönlendirmenin kaç isteği
kurtardığını ve birincilin yükünü ne kadar artırdığını ölçer.

### Okuma Kopyaları

Source: https://academia.sh/tr/kurslar/bulut-depolama/okuma-kopyalari

Kopya gecikmesinin uygulamaya nasıl yansıdığının ölçülmesi: 420.000 istekten oluşan bir akışta gecikme 0,1 saniyeden 5 saniyeye taranıp her değerde bayat okuma ve kendi yazdığını göremeyen istek sayısının çıkarılması, oturum tabanlı yapışkan pencerenin kaç isteği kurtardığı ile birincile kaydırdığı okuma payının karşılaştırılması, kopya sayısı arttıkça hem kopya başına kazancın hem de gecikmenin nasıl değiştiğinin sayılması ve bölge dışı kopyanın aylık aktarım bedelinin hesaplanması.

Önceki ders tek birincil üzerinde durdu: ikinci makine beklemedeydi, devralma anına kadar hiçbir
iş yapmıyordu. İş emri veritabanının istek karışımına bakıldığında bu israf göze batar — akışın
büyük bölümü okumadır. Bekleyen kopyayı okumaya açmak yükü dağıtır ve yönetilen hizmette bu bir
düğmedir.

Düğmenin altındaki şey devredilmiş bir karardır: çoğaltmanın nasıl işlediği artık görünmez. O
mekanik — eşzamanlı mı eşzamansız mı, kaç üye onay veriyor — İleri Veri Ölçekleme kursunda
ölçüldü ve burada tekrarlanmaz. Ölçülecek olan, mekaniğin dışarı sızan tek belirtisidir: **kopya
gecikmesi**. Sayılacak olan da "gecikme kaç saniye" değil, gecikmenin **kaç isteğe dokunduğudur**.

#### İki Tür Bayat Okuma

Bayat okumaların hepsi aynı ağırlıkta değildir. Bir saha ekibi başka bir ekibin yarım saniye önce
kapattığı iş emrini hâlâ açık görürse, bu bir tutarsızlıktır ama fark edilmez. Aynı ekip **kendi
kapattığı** iş emrini listede hâlâ açık görürse, bu bir hatadır: ekran az önce yapılan işlemi yok
saymıştır ve işlem ikinci kez denenir. Bu isteklere **kendi yazdığını oku** gereksinimi olan
istekler denir ve ayrı sayılmaları gerekir, çünkü çözümleri de ayrıdır.

#### Düzenek

**YV7 — akış 300 saniyelik bir penceredir: saniyede 1.400 istek, yüzde 78'i okuma (420.000 istek,
92.400 yazma).** **YV8 — kurgu ölçüm ağında 2.400 oturum ve 50.000 açık iş emri kaydı vardır;
oturum bir saha ekibi ya da otomatik toplayıcıdır.** **YV9 — yazmaların yüzde 31'i, aynı oturum
tarafından 120–900 ms sonra geri okunur; ekran işlemden sonra listeyi tazeler.** **YV10 — kopya
gecikmesi tabanı 0,25 saniyedir ve her ek kopya 0,15 saniye ekler, çünkü çoğaltma akışı
birincilden çekilir.** **YV11 — yük birimi kurgudur: yazma 1,0, okuma 0,4, kopya başına çoğaltma
gönderimi yazmanın 0,08'i.** **YV12 — yönlendirme kuralı oturum tabanlıdır: bir oturum yazdıktan
sonra W saniye boyunca okumaları birincile gider.** YV9 doğrudan belirleyicidir; geri okuma
aralığı büyürse ilk tablonun sağ sütunu aynı yönde küçülür.

```js
// yv/model.mjs — okuma kopyasi MODELI. Kurgu bolgesel olcum aginin is emri istek akisi uretilir;
// cogaltma MEKANIGI modellenmez (o M17/K05 ve M19/K04'te olculdu), yalnizca gecikmenin okumaya
// nasil yansidigi olculur. Uretec kendi yazilmistir, tohum gorunurdur: her kosumda ayni akis.
export const ISTEK = 1400, PENCERE = 300, OKUMA_PAYI = 0.78;
export const OTURUM = 2400, VARLIK = 50000, GERI_OKUMA = 0.31;
export const GERI_MIN = 0.12, GERI_MAX = 0.90;

export function akisUret(tohum = 20260802) {
  let s = tohum % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const toplam = ISTEK * PENCERE, yazmaSayisi = Math.round(toplam * (1 - OKUMA_PAYI));
  const olay = [];
  for (let i = 0; i < yazmaSayisi; i += 1) {                 // is emri durum degisimi
    const t = rast() * PENCERE, o = Math.floor(rast() * OTURUM), e = Math.floor(rast() * VARLIK);
    olay.push([t, o, e, 1]);                                 // 1 = yazma
    if (rast() < GERI_OKUMA)                                 // ayni oturum kendi yazdigini okur
      olay.push([t + GERI_MIN + rast() * (GERI_MAX - GERI_MIN), o, e, 0]);
  }
  const kalan = toplam - olay.length;
  for (let i = 0; i < kalan; i += 1)                         // baskasinin verisini okuyanlar
    olay.push([rast() * PENCERE, Math.floor(rast() * OTURUM), Math.floor(rast() * VARLIK), 0]);
  olay.sort((a, b) => a[0] - b[0]);
  return olay;
}

// Her okuma icin uc sayi cikarilir: dw = o varliga en son yazmadan bu yana gecen sure (kopya bu
// sureden kisa gecikmede geride kalir), kyo = son yazan oturum okuyanin kendisi mi, ds = okuyan
// oturumun KENDI son yazmasindan bu yana gecen sure (yonlendirme kurali yalnizca bunu bilir).
export function okumalariCikar(olay) {
  const sonYazma = new Map(), oturumSon = new Map();
  const dw = [], kyo = [], ds = [];
  let yazma = 0;
  for (const [t, o, e, tur] of olay) {
    if (tur === 1) { sonYazma.set(e, [t, o]); oturumSon.set(o, t); yazma += 1; continue; }
    const y = sonYazma.get(e);
    dw.push(y ? t - y[0] : Infinity);
    kyo.push(y ? y[1] === o : false);
    ds.push(oturumSon.has(o) ? t - oturumSon.get(o) : Infinity);
  }
  return { dw, kyo, ds, yazma, okuma: dw.length };
}

export const bayat = (r, L) => r.dw.reduce((n, d) => n + (d < L ? 1 : 0), 0);
export const kyoBayat = (r, L) => r.dw.reduce((n, d, i) => n + (d < L && r.kyo[i] ? 1 : 0), 0);
export const yonlenen = (r, W) => r.ds.reduce((n, d) => n + (d < W ? 1 : 0), 0);
export const kurtarilan = (r, L, W) =>
  r.dw.reduce((n, d, i) => n + (d < L && r.kyo[i] && r.ds[i] < W ? 1 : 0), 0);

export const GECIKME_TABAN = 0.25, GECIKME_ARTIS = 0.15;
export const YUK_YAZMA = 1.0, YUK_OKUMA = 0.4, YUK_COGALTMA = 0.08;
export const gecikmeR = (R) => GECIKME_TABAN + GECIKME_ARTIS * R;
```

```js
// yv/olc.mjs — kopya gecikmesinin uygulamaya yansimasi, yonlendirme kurali ve azalan getiri
import { akisUret, okumalariCikar, bayat, kyoBayat, yonlenen, kurtarilan, gecikmeR,
  ISTEK, PENCERE, OTURUM, VARLIK, GERI_OKUMA, YUK_YAZMA, YUK_OKUMA, YUK_COGALTMA } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const y = (a, b) => "%" + (100 * a / b).toFixed(2);
const r = okumalariCikar(akisUret());
console.log(`${ISTEK * PENCERE} istek / ${PENCERE} sn: ${r.yazma} yazma, ${r.okuma} okuma. ` +
  `${OTURUM} oturum, ${VARLIK} is emri. Tohum 20260802.`);
console.log(`yazmalarin %${100 * GERI_OKUMA} kadari ayni oturum tarafindan geri okunur.\n`);

console.log("kopya gecikmesi | bayat okuma | bayat pay | kendi yazdigini goremeyen | KYO pay");
console.log("----------------|-------------|-----------|---------------------------|---------");
for (const L of [0.1, 0.25, 0.5, 1, 2, 5]) {
  const b = bayat(r, L), k = kyoBayat(r, L);
  console.log(`${s(L.toFixed(2) + " sn", 15)} | ${s(b, 11)} | ${s(y(b, r.okuma), 9)} | ` +
    `${s(k, 25)} | ${s(y(k, r.okuma), 7)}`);
}

const L = 0.55;
const taban = kyoBayat(r, L);
console.log(`\nyonlendirme kurali, kopya gecikmesi ${L} sn sabit (${taban} istek kendi yazdigini goremiyor):`);
console.log("yapiskan pencere W | birincile giden okuma | kurtarilan | kalan | birincile kayan okuma payi");
console.log("-------------------|-----------------------|------------|-------|---------------------------");
for (const W of [0, 0.25, 0.5, 1, 2, 5, 15]) {
  const g = yonlenen(r, W), k = kurtarilan(r, L, W);
  console.log(`${s(W.toFixed(2) + " sn", 18)} | ${s(g, 21)} | ${s(k, 10)} | ${s(taban - k, 5)} | ` +
    `${s(y(g, r.okuma), 26)}`);
}

console.log(`\nkopya sayisi arttikca cogaltma akisi birincilden daha cok cekilir: gecikme ` +
  `${gecikmeR(1).toFixed(2)} sn (1 kopya) -> ${gecikmeR(8).toFixed(2)} sn (8 kopya).`);
console.log("kopya | gecikme | kopya basina okuma/sn | eklenen kopyanin kazanci | bayat pay | birincil yuk (birim/sn)");
console.log("------|---------|-----------------------|--------------------------|-----------|------------------------");
const W = 1, yon = yonlenen(r, W) / PENCERE, kopyaOkuma = (r.okuma / PENCERE) - yon;
let onceki = null;
for (const R of [1, 2, 3, 4, 5, 6, 7, 8]) {
  const basina = kopyaOkuma / R;
  const marj = onceki === null ? "-" : (onceki - basina).toFixed(1) + "/sn";
  const b = bayat(r, gecikmeR(R));
  const yuk = (r.yazma / PENCERE) * YUK_YAZMA + yon * YUK_OKUMA +
    R * (r.yazma / PENCERE) * YUK_COGALTMA;
  console.log(`${s(R, 5)} | ${s(gecikmeR(R).toFixed(2) + " sn", 7)} | ${s(basina.toFixed(1), 21)} | ` +
    `${s(marj, 24)} | ${s(y(b, r.okuma), 9)} | ${s(yuk.toFixed(1), 23)}`);
  onceki = basina;
}
console.log(`\nkosumdan bagimsiz: yapiskan pencere kopya gecikmesinden buyuk oldugunda kendi ` +
  `yazdigini goremeyen istek kalmaz; bedeli birincile giden okuma sayisidir.`);

// Aktarim bedeli: bolge disindaki her kopya her yazmayi bolge sinirindan gecirir. Kurgu birim.
const KAYIT_KB = 1.8, AY = 2592000, BOYUT_GB = 220;
const gbAy = (r.yazma / PENCERE) * KAYIT_KB * AY / 1048576;
console.log(`\ncogaltma akisi: ${(r.yazma / PENCERE).toFixed(0)} yazma/sn x ${KAYIT_KB} KB = ` +
  `${gbAy.toFixed(0)} GB/ay, kopya basina.`);
console.log("kopya yerlesimi | birim/GB | 1 kopya | 2 kopya | 3 kopya  (kurgu birim/ay)");
console.log("----------------|----------|---------|---------|---------");
for (const [ad, birim] of [["ayni bolge", 0], ["baska bolge", 2]])
  console.log(`${ad.padEnd(15)} | ${s(birim, 8)} | ${s((birim * gbAy).toFixed(0), 7)} | ` +
    `${s((2 * birim * gbAy).toFixed(0), 7)} | ${s((3 * birim * gbAy).toFixed(0), 7)}`);
console.log(`geri alinamayan kalem: yukseltilen kopya eski cogaltma bagina donmez; bagi yeniden ` +
  `kurmak ${BOYUT_GB} GB tam kopya demektir.`);
console.log(`bolge ici 95 MB/sn ile ${(BOYUT_GB * 1024 / 95 / 3600).toFixed(2)} sa; bolgeler arasi ` +
  `30 MB/sn ile ${(BOYUT_GB * 1024 / 30 / 3600).toFixed(2)} sa + ${2 * BOYUT_GB} kurgu birim.`);
```

```
420000 istek / 300 sn: 92400 yazma, 327600 okuma. 2400 oturum, 50000 is emri. Tohum 20260802.
yazmalarin %31 kadari ayni oturum tarafindan geri okunur.

kopya gecikmesi | bayat okuma | bayat pay | kendi yazdigini goremeyen | KYO pay
----------------|-------------|-----------|---------------------------|---------
        0.10 sn |         208 |     %0.06 |                         0 |   %0.00
        0.25 sn |        5253 |     %1.60 |                      4755 |   %1.45
        0.50 sn |       14702 |     %4.49 |                     13733 |   %4.19
        1.00 sn |       30039 |     %9.17 |                     28093 |   %8.58
        2.00 sn |       31877 |     %9.73 |                     28093 |   %8.58
        5.00 sn |       37473 |    %11.44 |                     28093 |   %8.58

yonlendirme kurali, kopya gecikmesi 0.55 sn sabit (15546 istek kendi yazdigini goremiyor):
yapiskan pencere W | birincile giden okuma | kurtarilan | kalan | birincile kayan okuma payi
-------------------|-----------------------|------------|-------|---------------------------
           0.00 sn |                     0 |          0 | 15546 |                      %0.00
           0.25 sn |                 14986 |       5078 | 10468 |                      %4.57
           0.50 sn |                 33134 |      13843 |  1703 |                     %10.11
           1.00 sn |                 64155 |      15546 |     0 |                     %19.58
           2.00 sn |                 95648 |      15546 |     0 |                     %29.20
           5.00 sn |                168901 |      15546 |     0 |                     %51.56
          15.00 sn |                278984 |      15546 |     0 |                     %85.16

kopya sayisi arttikca cogaltma akisi birincilden daha cok cekilir: gecikme 0.40 sn (1 kopya) -> 1.45 sn (8 kopya).
kopya | gecikme | kopya basina okuma/sn | eklenen kopyanin kazanci | bayat pay | birincil yuk (birim/sn)
------|---------|-----------------------|--------------------------|-----------|------------------------
    1 | 0.40 sn |                 878.1 |                        - |     %3.34 |                   418.2
    2 | 0.55 sn |                 439.1 |                 439.1/sn |     %5.08 |                   442.8
    3 | 0.70 sn |                 292.7 |                 146.4/sn |     %6.79 |                   467.5
    4 | 0.85 sn |                 219.5 |                  73.2/sn |     %8.53 |                   492.1
    5 | 1.00 sn |                 175.6 |                  43.9/sn |     %9.17 |                   516.7
    6 | 1.15 sn |                 146.4 |                  29.3/sn |     %9.27 |                   541.4
    7 | 1.30 sn |                 125.5 |                  20.9/sn |     %9.35 |                   566.0
    8 | 1.45 sn |                 109.8 |                  15.7/sn |     %9.44 |                   590.7

kosumdan bagimsiz: yapiskan pencere kopya gecikmesinden buyuk oldugunda kendi yazdigini goremeyen istek kalmaz; bedeli birincile giden okuma sayisidir.

cogaltma akisi: 308 yazma/sn x 1.8 KB = 1370 GB/ay, kopya basina.
kopya yerlesimi | birim/GB | 1 kopya | 2 kopya | 3 kopya  (kurgu birim/ay)
----------------|----------|---------|---------|---------
ayni bolge      |        0 |       0 |       0 |       0
baska bolge     |        2 |    2741 |    5482 |    8223
geri alinamayan kalem: yukseltilen kopya eski cogaltma bagina donmez; bagi yeniden kurmak 220 GB tam kopya demektir.
bolge ici 95 MB/sn ile 0.66 sa; bolgeler arasi 30 MB/sn ile 2.09 sa + 440 kurgu birim.
```

#### Gecikme Bir Sayı, Yansıması Bir Eğridir

İlk tablo gecikmenin isteğe nasıl çevrildiğini gösteriyor. 0,1 saniyede 327.600 okumanın yalnızca
208'i bayat; yarım saniyede 14.702, bir saniyede 30.039. Eğri doğrusal değil, çünkü bayat okuma
sayısı gecikmeyle değil, **gecikme penceresine düşen yazma yoğunluğuyla** artar.

Sağ sütun asıl bilgiyi taşıyor. 0,25 saniyelik gecikmedeki 5.253 bayat okumanın 4.755'i, yani
yüzde 90'ı, kendi yazdığını göremeyen isteklerdir. Sebep YV9'dur: geri okumalar yazmadan hemen
sonra gelir, dar bir gecikme penceresine düşen okumaların neredeyse tamamı geri okumadır.

Gecikme 1 saniyeden 5 saniyeye çıkınca toplam bayat okuma 30.039'dan 37.473'e yükseliyor ama kendi
yazdığını göremeyen istek 28.093'te sabit kalıyor: geri okumalar en geç 900 ms sonra geldiği için
1 saniyeyi aşan gecikmede zaten hepsi bayattır. Gecikmeyi büyütmek yeni bir hata türü üretmiyor,
mevcut hatanın etrafına daha çok tutarsızlık ekliyor.

#### Yönlendirme Kuralı Kurtarır, Faturayı Birincile Keser

İkinci tablo gecikmeyi 0,55 saniyede sabitleyip yapışkan pencereyi tarıyor. Kural uygulamanın
bildiği tek şeye dayanıyor: bir oturum yazdıktan sonra W saniye boyunca okumaları kopyaya değil
birincile gider.

W sıfırken kural yoktur ve 15.546 istek kendi yazdığını göremez. W 0,25 saniyeye çıktığında
5.078'i kurtarılıyor, 10.468'i kalıyor — pencere gecikmeden dar olduğu için yetmiyor. W 0,5'te
kalan 1.703'e iniyor. **W 1 saniyede kalan sıfırdır** ve bu satır koşumdan bağımsızdır: yapışkan
pencere kopya gecikmesini aştığı anda, kendi yazmasından etkilenen her okuma birincile gider.

Bedel sağ sütunda. Kalanı sıfırlayan W = 1 ayarı, okumaların yüzde 19,58'ini birincile kaydırıyor:
327.600 okumanın 64.155'i. Kopyaları açmanın amacı birincili boşaltmaktı; kural o kazancın beşte
birini geri veriyor. W'yi güvenli olsun diye 15 saniyeye çekmek yüzde 85,16'ya çıkarıyor ve
kopyalar boşa düşer. Doğru ayar en büyük W değil, **gecikmenin biraz üzerindeki** W'dir; gecikme
kopya sayısına bağlı olduğu için iki karar birbirine bağlıdır.

#### Kopya Eklemenin Azalan Getirisi

Üçüncü tablo kopya sayısını 1'den 8'e çıkarıyor. Kopya başına düşen okuma 878,1'den 109,8'e
iniyor; beklenen budur. Kazanç sütunu beklenmeyeni gösteriyor: ikinci kopya 439,1 okuma/sn
hafifletiyor, üçüncüsü 146,4, dördüncüsü 73,2, sekizincisi 15,7. Yedinci ve sekizinci kopya
birlikte, ikinci kopyanın kazancının yüzde 8'ini getiriyor.

İki sütun daha bu tabloyu tersine çeviriyor. **Gecikme kopya sayısıyla büyüyor** (YV10): 8 kopyada
1,45 saniye ve bayat okuma payı yüzde 3,34'ten yüzde 9,44'e çıkıyor. **Birincil yük de büyüyor:**
418,2 birimden 590,7 birime, çünkü her kopyaya çoğaltma akışı gönderilir. Sekizinci kopya
eklendiğinde birincil yüzde 41 daha yüklüdür ve okuma tarafında kazandığı 15,7 istek/sn'dir. Bu
noktadan sonra kopya eklemek yükü dağıtmaz, taşır.

#### Aktarım Bedeli ve Geri Alınamayan Kalem

Son blok kopyanın yerleşimini ücretlendiriyor. Çoğaltma akışı saniyede 308 yazma × 1,8 KB, yani
kopya başına ayda 1.370 GB: aynı bölgede 0 kurgu birim, başka bölgede 2.741, üç kopya için 8.223.
Kopyaların bölgeye dağıtılması dayanıklılık kararı gibi görünür; faturada bir aktarım kalemidir ve
**yazma hızıyla** ölçeklenir, veri boyutuyla değil.

Geri alınamayan kalem bu derste incedir. Bir kopya birincile yükseltildiğinde eski çoğaltma bağına
dönmez; bağı yeniden kurmak 220 GB'lik tam bir kopya demektir: bölge içinde 0,66 saat, bölgeler
arasında 2,09 saat ve 440 kurgu birim. Yükseltme düğmesine basmak bir saniyelik iştir, geri dönüşü
değildir.

#### Özet

- Kopya gecikmesi 0,1 saniyeden 5 saniyeye çıkınca bayat okuma 208'den 37.473'e yükseliyor;
  eğri doğrusal değil, gecikme penceresine düşen yazma yoğunluğuna bağlıdır.
- Dar gecikmede bayat okumaların yüzde 90'ı kendi yazdığını göremeyen isteklerdir; gecikme 1
  saniyeyi aştıktan sonra bu sayı 28.093'te sabitlenir, yalnızca çevresindeki tutarsızlık artar.
- Yapışkan pencere gecikmeyi aştığında (W = 1 sn, gecikme 0,55 sn) kendi yazdığını göremeyen istek
  sıfırlanır; bedeli okumaların yüzde 19,58'inin birincile kaymasıdır.
- Pencereyi 15 saniyeye açmak aynı 15.546 isteği kurtarır ama okumaların yüzde 85,16'sını birincile
  taşır: kopyaları açmanın kazancı büyük ölçüde geri verilir.
- Kopya eklemenin getirisi azalıyor (439,1 → 15,7 okuma/sn) ve iki maliyet artıyor: gecikme 0,40'tan
  1,45 saniyeye, birincil yük 418,2'den 590,7 birime.
- Bölge dışı kopya yazma hızıyla ölçeklenen bir aktarım kalemidir (ayda 1.370 GB, 2.741 kurgu
  birim); yükseltilen kopya çoğaltma bağına dönmez, yeniden kurmak 220 GB'lik tam kopyadır.

#### Sonraki Adım

Bu iki ders ilişkisel veritabanının kiralanmasını ölçtü ve elde kalan kararların çoğu ayardı:
yanlış seçilen bir yapışkan pencere değiştirilebilir, fazla kopya kapatılabilir. Sonraki ders aynı
soruyu anahtar–değer tarafında soruyor ve orada tabloyu tersine çeviren tek bir kalem var: veri
seçilen **bölüm anahtarına** göre yerleşir ve anahtar seçildikten sonra hangi sorguların
karşılanabileceği sabitlenir. Üç aday anahtar aynı gerçek anahtar dağılımında koşturulacak, en
yoğun bölümün payı ve anahtarla desteklenmeyen erişim örüntüsü sayılacak, sonra anahtarı
değiştirmenin bedeli bayt ve süre olarak hesaplanacak.

### Yönetilen Anahtar–Değer Servisi

Source: https://academia.sh/tr/kurslar/bulut-depolama/yonetilen-anahtar-deger-servisi

Bölüm anahtarı seçiminin üç aday üzerinde gerçek anahtar dağılımıyla ölçülmesi: her adayda bölüm başına düşen istek, en dolu bölümün payı ve anahtarla desteklenmeyen erişim örüntüsünün karşılanamayan sorgu olarak sayılması, ayrılmış kapasite ile istek başına modelin aynı yük profilinde karşılaştırılıp sıcak bölümün zorladığı aşırı ayırmanın hesaplanması ve bölüm anahtarını değiştirmenin süre ve kurgu birim olarak bedelinin çıkarılması.

Önceki iki derste elde kalan kararların hemen hepsi ayardı: yapışkan pencere değiştirilebilir,
kopya kapatılabilir. Yönetilen anahtar–değer servisinde tablo değişir. Veri, **bölüm anahtarı**
denen alanın değerine göre yerleşir ve o anahtar seçildikten sonra hangi sorguların
karşılanabileceği sabitlenir.

Bölümlemenin mekaniği — aralığa göre mi karmaya göre mi bölündüğü, yeniden dengelemenin taşıdığı
veri — İleri Veri Ölçekleme kursunda ölçüldü ve burada tekrarlanmaz. Bu dersin ölçtüğü iki şey
bulut bağlamına özgüdür: anahtarın **kapasite modeline** ne yaptığı ve anahtarı değiştirmenin
**geri alınamazlığı**.

#### Karşılanamayan Sorgu

Bir sorgu bölüm anahtarını eşitlikle sabitliyorsa istek doğrudan ilgili bölüme gider;
sabitlemiyorsa servis nereye bakacağını bilemez ve tek yol tablonun tamamını taramaktır. Bu
ölçekte tarama bir sorgu değil bir toplu işlemdir; böyle bir erişim örüntüsü **karşılanamayan
sorgu** sayılır ve aşağıda ayrı bir sütun olarak durur.

İkinci ölçü, karşılanabilen isteklerin bölümlere nasıl dağıldığıdır: on altı bölüme yayılan bir
yükte bölüm başına düşen istek ile en dolu bölümün aldığı istek arasındaki fark, **sıcak bölümün**
kendisidir.

#### Düzenek

**YV13 — kurgu ölçüm ağında 40.000 sayaç, 12 bölge ve 26.000 abone vardır; her sayaç 15 dakikada
bir okuma yazar (günde 96) ve saklama 90 gündür: 345,6M öğe, öğe başına 180 bayt, 62,2 GB.**
Bölge payları 27'den 1'e iner; merkez bölge sayaçların yaklaşık dörtte birini taşır. **YV14 —
erişim karışımı: bir sayacın son 24 saati yüzde 38, tek okuma kaydı yüzde 22, bir bölgenin günlük
toplamı yüzde 17, bir abonenin son okumaları yüzde 10, günün eşik aşan okumaları yüzde 8, son bir
saatin tüm okumaları yüzde 5.** **YV15 — servis veriyi 16 bölüme yayar; ayrılmış kapasitede toplam
birim bölümlere eşit bölünür ve bu modelde bir bölüm kendi payını aşamaz. Gerçek servisler bunu
uyarlanır kapasiteyle yumuşatır; aşağıdaki çarpanlar üst sınırdır.** **YV16 — istek hızı ortalama
1.200/sn, günlük profil 24 saatlik kurgu bir çarpan dizisidir.** **YV17 — kurgu fiyat: ayrılmış
kapasite 0,12 birim/kapasite-saat, istek başına 0,25 birim/1.000 istek, yazma birimi okumanın 5
katı.** **YV18 — anahtar değiştirme işi 12.000 öğe/sn koşar.** YV14 belirleyicidir; ağırlıklar
değişirse karşılanamayan istek payı aynı yönde değişir.

```js
// yv/model.mjs — yonetilen anahtar-deger servisi MODELI: kurgu bolgesel olcum aginin sayac
// okumalari uzerinde bolum anahtari adaylari kosturulur. Bolumleme MEKANIGI (aralik mi karma mi,
// yeniden dengeleme) M17/K05'te olculdu, burada tekrarlanmaz; olculen sey anahtarin DEGER
// DAGILIMI ile erisim orunttusune uygunlugudur. Uretec kendi yazilmistir, tohum gorunurdur.
export const BOLGE = [["merkez", 27], ["kuzey", 14], ["liman", 11], ["sanayi", 9], ["bati", 8],
  ["dogu", 7], ["yayla", 6], ["kiyi", 5], ["ova", 5], ["baraj", 4], ["tepe", 3], ["ada", 1]];
export const SAYAC = 40000, ABONE = 26000, DILIM = 96, SAKLAMA = 90, BOLUM = 16;
export const OGE = SAYAC * DILIM * SAKLAMA, OGE_BAYT = 180;
export const BUGUN = SAKLAMA - 1;

// Sayac kutugu cagirandadir: sayac_id verilince bolgesi, abone verilince sayaclari bilinir.
export function kutuk(tohum = 20260803) {
  let s = tohum % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const toplam = BOLGE.reduce((t, [, w]) => t + w, 0);
  const bolgesi = new Int32Array(SAYAC), abonesi = new Int32Array(SAYAC);
  const bolgeSayac = new Array(BOLGE.length).fill(0), aboneninSayaclari = new Map();
  for (let i = 0; i < SAYAC; i += 1) {
    let x = rast() * toplam, b = 0;
    for (let j = 0; j < BOLGE.length; j += 1) { if (x < BOLGE[j][1]) { b = j; break; } x -= BOLGE[j][1]; }
    bolgesi[i] = b; bolgeSayac[b] += 1;
    const a = Math.floor(rast() * ABONE);
    abonesi[i] = a;
    if (!aboneninSayaclari.has(a)) aboneninSayaclari.set(a, []);
    aboneninSayaclari.get(a).push(i);
  }
  return { rast, bolgesi, abonesi, bolgeSayac, aboneninSayaclari };
}

// Erisim orunttusu, sorguyu kurarken SABITLEYEBILDIGI alanlarla tanimlidir (YV14 sirasiyla);
// bolum anahtari o alanlar arasinda degilse sorgu karsilanamaz.
export const ERISIM = [38, 17, 22, 8, 10, 5];

export function istekUret(k, adet = 300000) {
  const agirlik = ERISIM, toplam = agirlik.reduce((a, b) => a + b, 0);
  const istek = [];
  for (let i = 0; i < adet; i += 1) {
    let x = k.rast() * toplam, tur = 0;
    for (let j = 0; j < agirlik.length; j += 1) { if (x < agirlik[j]) { tur = j; break; } x -= agirlik[j]; }
    const sayac = Math.floor(k.rast() * SAYAC);
    const abone = k.abonesi[Math.floor(k.rast() * SAYAC)];
    const eski = Math.floor(k.rast() * SAKLAMA);       // E2 ve E3 gecmise de bakar
    const gun = tur === 0 ? BUGUN                      // E1 "son 24 saat" hep bugundur
      : tur === 3 ? (k.rast() < 0.7 ? BUGUN : BUGUN - Math.floor(k.rast() * 7)) : eski;
    istek.push({ tur, sayac, bolge: k.bolgesi[sayac], abone, gun });
  }
  return istek;
}

// Istek hangi bolum anahtari DEGERLERINE dokunuyor; null = anahtar sabitlenemiyor, yani
// KARSILANAMAYAN sorgu (tum tablo taranir).
export function anahtarlar(q, aday, k) {
  const sayaclar = () => k.aboneninSayaclari.get(q.abone) ?? [q.sayac];
  if (aday === "bolge") {
    if (q.tur === 3 || q.tur === 5) return null;
    if (q.tur === 4) return [...new Set(sayaclar().map((i) => k.bolgesi[i]))].map((b) => "b" + b);
    return ["b" + q.bolge];
  }
  if (aday === "gun") {
    if (q.tur === 0) return ["g" + q.gun, "g" + Math.max(0, q.gun - 1)];
    return ["g" + (q.tur === 4 || q.tur === 5 ? BUGUN : q.gun)];
  }
  if (q.tur === 1 || q.tur === 3 || q.tur === 5) return null;   // sayac_id sabitlenemiyor
  return q.tur === 4 ? sayaclar().map((i) => "s" + i) : ["s" + q.sayac];
}

export const karma = (m) => { let h = 2166136261;
  for (const c of m) h = Math.imul(h ^ c.charCodeAt(0), 16777619); return (h >>> 0) % BOLUM; };
```

```js
// yv/olc.mjs — uc bolum anahtari adayi, sicak bolum, karsilanamayan sorgu ve kapasite modeli
import { kutuk, istekUret, anahtarlar, karma, ERISIM, BOLGE, SAYAC, ABONE,
  DILIM, SAKLAMA, BOLUM, OGE, OGE_BAYT } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const yz = (a, b) => "%" + (100 * a / b).toFixed(2);
const k = kutuk();
const istek = istekUret(k);
const ADAY = [["bolge | zaman", "bolge", BOLGE.length], ["gun | sayac_id#zaman", "gun", SAKLAMA],
  ["sayac_id | zaman", "sayac_id", SAYAC]];
console.log(`${SAYAC} sayac, ${BOLGE.length} bolge, ${ABONE} abone, ${DILIM} okuma/gun, ` +
  `${SAKLAMA} gun saklama -> ${(OGE / 1e6).toFixed(1)}M oge, ${(OGE * OGE_BAYT / 1e9).toFixed(1)} GB.`);
console.log(`${istek.length} istek uzerinde olculdu. Tohum 20260803.\n`);

const sonuc = new Map();
console.log("bolum anahtari       | farkli deger | karsilanamayan orunttu | karsilanamayan istek | bolum basina istek (ort / en dolu) | sicak bolum");
console.log("---------------------|--------------|------------------------|----------------------|-----------------------------------|------------");
for (const [ad, aday, farkli] of ADAY) {
  const yuk = new Array(BOLUM).fill(0);
  let bos = 0;
  const orunttu = new Set();
  for (const q of istek) {
    const a = anahtarlar(q, aday, k);
    if (a === null) { bos += 1; orunttu.add(q.tur); continue; }
    for (const deger of a) yuk[karma(deger)] += 1;      // her deger ayri bir bolum istegidir
  }
  const toplam = yuk.reduce((a, b) => a + b, 0), enDolu = Math.max(...yuk);
  sonuc.set(aday, { sicak: enDolu / toplam, bos });
  console.log(`${ad.padEnd(20)} | ${s(farkli, 12)} | ${s(orunttu.size + " / " + ERISIM.length, 22)} | ` +
    `${s(bos + " (" + yz(bos, istek.length) + ")", 20)} | ` +
    `${s(Math.round(toplam / BOLUM) + " / " + enDolu, 33)} | ${s(yz(enDolu, toplam), 11)}`);
}
console.log(`ideal sicak bolum payi ${BOLUM} bolum icin %${(100 / BOLUM).toFixed(2)}; ` +
  `bolum basina istek karsilanabilen isteklerin dokundugu bolum sayisi uzerinden sayildi.`);

// Kapasite modeli. Ayrilmis kapasitede toplam birim BOLUM parcaya esit bolunur; bir bolum kendi
// payini asamaz, dolayisiyla sicak bolum toplam ayirmayi yukari zorlar.
const TABAN = 1200, FIYAT_AYRILMIS = 0.12, FIYAT_ISTEK = 0.25;
const PROFIL = [0.22, 0.18, 0.16, 0.16, 0.20, 0.35, 0.70, 1.20, 1.75, 2.10, 2.20, 2.05,
  1.80, 1.70, 1.80, 2.00, 2.30, 2.55, 2.45, 1.90, 1.30, 0.85, 0.50, 0.32];
const ort = PROFIL.reduce((a, b) => a + b, 0) / 24;
const hiz = PROFIL.map((p) => TABAN * p / ort);
const gunlukIstek = hiz.reduce((a, b) => a + b, 0) * 3600;
const tepe = Math.max(...hiz);
console.log(`\nyuk profili: ortalama ${TABAN} istek/sn, tepe ${tepe.toFixed(0)} istek/sn ` +
  `(${(tepe / TABAN).toFixed(2)} kat), gunluk ${(gunlukIstek / 1e6).toFixed(1)}M istek.`);
console.log(`kurgu fiyat: ayrilmis kapasite ${FIYAT_AYRILMIS} birim/kapasite-saat, istek basina ` +
  `${FIYAT_ISTEK} birim/1000 istek.`);
console.log("bolum anahtari       | asiri ayirma | ayrilmis (birim/gun) | istek basina | tepeye ayirmada kisilan istek");
console.log("---------------------|--------------|----------------------|--------------|------------------------------");
for (const [ad, aday] of ADAY) {
  const h = sonuc.get(aday).sicak;
  const ayrilmis = BOLUM * h * tepe * 24 * FIYAT_AYRILMIS;   // kisilmasiz ayirma = BOLUM * h * tepe
  const tavan = tepe / BOLUM;                       // yalniz toplami karsilayan ayirma: C = tepe
  const kisilan = hiz.reduce((t, r) => t + Math.max(0, h * r - tavan) * 3600, 0);
  console.log(`${ad.padEnd(20)} | ${s((BOLUM * h).toFixed(2) + " kat", 12)} | ${s(ayrilmis.toFixed(0), 20)} | ` +
    `${s((gunlukIstek / 1000 * FIYAT_ISTEK).toFixed(0), 12)} | ${s((kisilan / 1e6).toFixed(1) + "M", 29)}`);
}

// Geri alinamayan kalem: bolum anahtarini degistirmek veriyi yeniden yazmaktir.
const AKTARMA_HIZ = 12000, YAZMA_KAT = 5;
const esdeger = OGE * (1 + YAZMA_KAT), sure = OGE / AKTARMA_HIZ / 3600;
const bedel = esdeger / 1000 * FIYAT_ISTEK, gunluk = gunlukIstek / 1000 * FIYAT_ISTEK;
const cikis = OGE * OGE_BAYT / 1e9;
console.log(`\nanahtari degistirmek: ${(OGE / 1e6).toFixed(1)}M oge okunup yeni anahtarla yeniden ` +
  `yazilir (yazma birimi okumanin ${YAZMA_KAT} kati) -> esdeger istek ${(esdeger / 1e9).toFixed(2)}G.`);
console.log(`bedel ${(bedel / 1000).toFixed(1)} bin kurgu birim = gunluk isletimin ` +
  `(${gunluk.toFixed(0)} birim) ${(bedel / gunluk).toFixed(0)} kati; sure ${sure.toFixed(1)} sa ` +
  `(${AKTARMA_HIZ} oge/sn) ve o sure boyunca cift yazma penceresi.`);
console.log(`servisten cikis daha ucuz: ${cikis.toFixed(1)} GB disa aktarim, internet uzerinden ` +
  `9 birim/GB = ${(cikis * 9).toFixed(0)} kurgu birim. Farkli deger sayisi (bolge icin ` +
  `${BOLGE.length}) bolum sayisinin kosumdan bagimsiz ust siniridir.`);
```

```
40000 sayac, 12 bolge, 26000 abone, 96 okuma/gun, 90 gun saklama -> 345.6M oge, 62.2 GB.
300000 istek uzerinde olculdu. Tohum 20260803.

bolum anahtari       | farkli deger | karsilanamayan orunttu | karsilanamayan istek | bolum basina istek (ort / en dolu) | sicak bolum
---------------------|--------------|------------------------|----------------------|-----------------------------------|------------
bolge | zaman        |           12 |                  2 / 6 |       39168 (%13.06) |                     18545 / 78103 |      %26.32
gun | sayac_id#zaman |           90 |                  0 / 6 |            0 (%0.00) |                    25888 / 184840 |      %44.62
sayac_id | zaman     |        40000 |                  3 / 6 |       89856 (%29.95) |                     16010 / 16312 |       %6.37
ideal sicak bolum payi 16 bolum icin %6.25; bolum basina istek karsilanabilen isteklerin dokundugu bolum sayisi uzerinden sayildi.

yuk profili: ortalama 1200 istek/sn, tepe 2389 istek/sn (1.99 kat), gunluk 103.7M istek.
kurgu fiyat: ayrilmis kapasite 0.12 birim/kapasite-saat, istek basina 0.25 birim/1000 istek.
bolum anahtari       | asiri ayirma | ayrilmis (birim/gun) | istek basina | tepeye ayirmada kisilan istek
---------------------|--------------|----------------------|--------------|------------------------------
bolge | zaman        |     4.21 kat |                28978 |        25920 |                         16.8M
gun | sayac_id#zaman |     7.14 kat |                49127 |        25920 |                         34.7M
sayac_id | zaman     |     1.02 kat |                 7010 |        25920 |                          0.0M

anahtari degistirmek: 345.6M oge okunup yeni anahtarla yeniden yazilir (yazma birimi okumanin 5 kati) -> esdeger istek 2.07G.
bedel 518.4 bin kurgu birim = gunluk isletimin (25920 birim) 20 kati; sure 8.0 sa (12000 oge/sn) ve o sure boyunca cift yazma penceresi.
servisten cikis daha ucuz: 62.2 GB disa aktarim, internet uzerinden 9 birim/GB = 560 kurgu birim. Farkli deger sayisi (bolge icin 12) bolum sayisinin kosumdan bagimsiz ust siniridir.
```

#### Üç Aday, Üç Farklı Başarısızlık

Hiçbir aday üstün çıkmıyor; her biri başka bir sütunda batıyor.

**`bolge` işletme düzenine uyuyor ve sıcak bölüm üretiyor.** Bölüm başına ortalama 18.545 istek
düşerken en dolu bölüm 78.103 alıyor: yüzde 26,32, ideal olan yüzde 6,25'in dört katı. Sebep, on
iki farklı değerden birinin sayaçların dörtte birini taşımasıdır; bölüm eklemek bunu düzeltmez,
çünkü bir anahtar değeri bölünemez.

**`gun` her sorguyu karşılıyor ve en kötü sıcak bölümü üretiyor.** Karşılanamayan örüntü sıfır —
tabloda tek sıfır bu. Karşılığında bugünün bölümü 184.840 istek alıyor, ortalamanın yedi katı,
isteklerin yüzde 44,62'si: artan bir anahtarda yeni yazma ve okumaların çoğu tek değere yığılır.

**`sayac_id` kusursuz dengeleniyor ve isteklerin yaklaşık üçte birini karşılayamıyor.**
Ortalama 16.010,
en dolu bölüm 16.312 — sıcak bölüm yüzde 6,37, ideale yüzde 2 uzaklıkta. Buna karşılık altı
örüntünün üçü, bölge toplamı, eşik taraması ve son bir saatin okumaları, anahtarı hiç
sabitlemiyor: isteklerin yüzde 29,95'i, 89.856 istek. Bunlar yavaş çalışmıyor; **hiç çalışmıyor**.

#### Sıcak Bölüm Faturaya Kapasite Modelinden Geçer

İkinci tablo sıcak bölümü paraya çeviriyor. Ayrılan toplam birim bölümlere eşit bölünür ve bir
bölüm kendi payını aşamaz (YV15); sıcak bölümün payı h ise kısılmamak için ayrılması gereken
kapasite 16 × h × tepe'dir. İlk sütun bu katsayıyı veriyor: `sayac_id` için 1,02, `bolge` için
4,21, `gun`
için 7,14 kat. Sıcak bölümü olan bir anahtarda ayrılan kapasitenin altıda beşi hiç kullanılmaz;
**kapasitenin karşılığı işlem değil, dengesizliktir.**

Gündelik bedel bunun sonucudur. `sayac_id` ile ayrılmış kapasite 7.010 kurgu birim, istek başına
model 25.920 — ayrılmış model 3,7 kat ucuz. `bolge` ile ayrılmış 28.978'e çıkıp istek başına
modelin üstüne geçiyor, `gun` ile 49.127 oluyor. **Hangi kapasite modelinin ucuz olduğunu belirleyen
şey yük değil, bölüm anahtarıdır.** İstek başına model dengesizliğe duyarsızdır; ayrılmış model onu
katsayısıyla ücretlendirir.

Son sütun ayırmanın kısıldığı durumu gösteriyor: yalnız toplam tepeyi karşılayacak kadar (2.389
birim) ayrıldığında `sayac_id` hiç kısılmıyor, `bolge` günde 16,8M, `gun` 34,7M isteği kısıyor.
Toplam kapasite yeterlidir; kısılan tek bölümdür.

#### Anahtarı Değiştirmenin Bedeli

Buraya kadar ölçülen her şey bir seçim gibi görünüyor; son blok neden öyle olmadığını sayıyor.
Bölüm anahtarını değiştirmek bir ayar değişikliği değildir: 345,6M öğenin tamamı okunur ve yeni
anahtarla yeniden yazılır. Yazma birimi okumanın beş katı olduğu için eşdeğer istek 2,07 milyar,
kurgu bedeli 518,4 bin birim — **günlük işletim bedelinin 20 katı.** Süre 8 saat ve o süre boyunca
uygulama iki tabloya birden yazar, çünkü aktarma sürerken gelen yazmaların da bir yere düşmesi
gerekir. İlişkisel taraftaki ana sürüm yükseltmesi de tek yönlüydü ama veri yerinde kalıyordu;
burada geri dönüş verinin kendisini yeniden yazmaktır. Servisten büsbütün çıkmak daha ucuzdur:
62,2 GB dışa aktarım ve 560 kurgu birim. **Anahtarı değiştirmek, servisi terk etmekten 900 kat
pahalıya geliyor**; bağlayıcı olan sağlayıcı değil, şemadır.

#### Özet

- `bolge` anahtarında sıcak bölüm ideal payın dört katıdır (%26,32) ve on iki farklı değer bölüm
  sayısının üst sınırını çizer; bölüm eklemek dengeyi düzeltmez.
- `gun` altı erişim örüntüsünün altısını da karşılıyor ama bugünün bölümü 184.840 istek alıyor
  (%44,62); `sayac_id` 16.010'a karşı 16.312 ile kusursuz dengeleniyor ama altı örüntünün üçünü,
  isteklerin %29,95'ini karşılayamıyor.
- Sıcak bölüm ayrılmış kapasitede aşırı ayırmaya çevrilir: 1,02 / 4,21 / 7,14 kat. Hangi kapasite
  modelinin ucuz olduğunu yük değil, bölüm anahtarı belirliyor (7.010'a karşı 25.920 kurgu birim).
- Toplam tepeyi karşılayan bir ayırma bile sıcak anahtarda günde 16,8M ve 34,7M isteği kısar.
- Anahtarı değiştirmek 345,6M öğenin yeniden yazılmasıdır: 8 saat, 518,4 bin kurgu birim ve 8
  saatlik çift yazma penceresi — servisten büsbütün çıkmanın 900 katı.

#### Sonraki Adım

Tablo bir eksik bırakıyor. En iyi dengeyi veren `sayac_id` anahtarında isteklerin yüzde 29,95'i
karşılanamıyor ve bunu düzeltmenin yolu anahtarı değiştirmek değil — o kapı 518,4 bin kurgu birimle
kapandı. Yönetilen anahtar–değer servisleri bu boşluk için **ikincil dizin** sunar: aynı veriyi
başka bir anahtara göre ikinci kez yerleştirir. Sonraki ders ikincil dizinin karşılanamayan üç
örüntünün kaçını kurtardığını ve karşılığında ne aldığını sayar — ek yazma, ek saklama, geri kalma
süresi — ve **değişim akışını** bir tüketiciyle modelleyip olay sırasını, yeniden işlemeyi ve
akışın saklama süresi dolduğunda kaçırılan pencereyi ölçer.

### İkincil Dizinler ve Akışlar

Source: https://academia.sh/tr/kurslar/bulut-depolama/ikincil-dizinler-ve-akislar

Önceki dersin karşılanamayan üç erişim örüntüsünün ikincil dizinle kurtarılması ve karşılığında alınanın sayılması: her dizinin kurtardığı istek, eklediği yazma bedeli, saklama ve dizin gecikmesinden doğan eksik sonuç payı, yansıtma seçiminin taban tabloya dönüşle takası, değişim akışının bir tüketiciyle modellenip olay sırası, yeniden işlenen olay ve akışın saklama süresi dolduğunda geri getirilemeyen kaçırılan pencerenin ölçülmesi.

Önceki ders `sayac_id` bölüm anahtarını en dengeli aday olarak buldu ve aynı satırda bir borç
bıraktı: altı erişim örüntüsünün üçü — bölge günlük toplamı, eşik taraması, son bir saatin
okumaları — anahtarı sabitleyemediği için hiç karşılanamıyordu; isteklerin yüzde 30'u. Anahtarı
değiştirmek 518,4 bin kurgu birimle kapalı bir kapı olduğuna göre geriye tek yol kalıyor: aynı
veriyi **başka bir anahtara göre bir kez daha yerleştirmek**.

Buna **ikincil dizin** denir; dizinin kurulması, güncellenmesi ve bölümlenmesi devredilmiş
kararlardır. Devredilmeyen kısım seçimin kendisidir: hangi anahtar, hangi öznitelikler, kaç dizin.

#### Düzenek

**YV19 — taban tablo önceki dersteki `sayac_id | zaman` anahtarıyla kuruludur; karşılanamayan üç
örüntü E2 yüzde 17, E4 yüzde 8, E6 yüzde 5 ağırlığındadır.** **YV20 — üç ikincil dizin adayı:
`bolge | gun#sayac_id`, `gun | okuma_degeri` ve `gun#saat | sayac_id`; ikincisi seyrek dizindir ve
yalnız eşiği aşan öğeleri taşır (öğelerin binde 4'ü).** **YV21 — dizin eşzamansız
güncellenir, gecikme 0,8 saniyedir.** **YV22 — yansıtma seçenekleri öğe başına 48, 96 ve 180
bayttır; kurgu saklama fiyatı 0,9 birim/GB-ay, yazma birimi okumanın 5 katı ve istek başına fiyat
önceki dersteki gibi 0,25 birim/1.000 istektir.** **YV23 — değişim akışı 16 parçadır, saklama
süresi 24 saattir; olay hızı yazma hızına eşittir (44,4 olay/sn) ve tüketici kapasitesi 55
olay/sn'dir.** **YV24 — tüketici konumunu C saniyede bir kaydeder ve günde ortalama 0,4 çökme
yaşanır.** YV23'teki kapasite payı belirleyicidir: 55 yerine 45 yazılırsa yetişme süresi sütunu
patlar.

```js
// yv/model.mjs — ikincil dizin ve degisim akisi MODELI. Onceki dersin taban tablosu (bolum
// anahtari sayac_id) uzerine kurulur; oradaki karsilanamayan uc orunttu girdi alinir. Rastgelelik
// olay uretecindedir, uretec kendi yazilmistir ve tohum gorunurdur.
export const OGE = 345_600_000, GUNLUK_YAZMA = 3_840_000, GUNLUK_ISTEK = 103_700_000;
export const YAZMA_KAT = 5, FIYAT_ISTEK = 0.25, FIYAT_GB_AY = 0.9, OGE_BAYT = 180;
export const LAMBDA = GUNLUK_YAZMA / 86400;              // olay/sn = yazma/sn

// [ad, kurtardigi orunttu, orunttunun agirligi, dizinlenen oge orani, o araliga giren yazma/sn]
export const DIZIN = [
  ["bolge | gun#sayac_id", "E2 bolge gunluk toplami", 17, 1, LAMBDA * 0.27],
  ["gun | okuma_degeri", "E4 esik asan okumalar", 8, 0.004, LAMBDA * 0.004],
  ["gun#saat | sayac_id", "E6 son bir saat", 5, 1, LAMBDA],
];
export const YANSITMA = [["yalniz anahtar", 48], ["secili oznitelik", 96], ["tum oznitelikler", 180]];

export const yazmaBedeliAy = (oran) =>
  GUNLUK_YAZMA * oran * 30 * YAZMA_KAT / 1000 * FIYAT_ISTEK;
export const saklamaBedeliAy = (oran, bayt) => OGE * oran * bayt / 1e9 * FIYAT_GB_AY;
export const eksikOge = (yazmaHizi, L) => yazmaHizi * L;
export const eksikSorguPayi = (yazmaHizi, L) => 1 - Math.exp(-yazmaHizi * L);

// Degisim akisi: her yazma bir olaydir. Olaylarin SIRASI yalnizca ayni bolum anahtari icinde
// korunur; tuketici parcalari sirayla okudugunda genel zaman sirasi bozulur.
export function akisiOku({ adet = 60000, parca = 16, tur = 64, tohum = 20260804 } = {}) {
  let s = tohum % 2147483647;
  const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;
  const karma = (x) => { let h = 2166136261;
    for (const c of String(x)) h = Math.imul(h ^ c.charCodeAt(0), 16777619); return (h >>> 0) % parca; };
  const kutu = Array.from({ length: parca }, () => []);
  let t = 0;
  for (let i = 0; i < adet; i += 1) {                    // olaylar zaman sirasinda uretilir
    t += rast() * 2 / LAMBDA;
    const sayac = Math.floor(rast() * 40000);
    kutu[karma(sayac)].push({ t, sayac });
  }
  const okunan = [];                                     // tuketici: her parcadan `tur` olay
  for (let d = 0; okunan.length < adet; d += 1)
    for (let p = 0; p < parca; p += 1)
      for (const o of kutu[p].slice(d * tur, (d + 1) * tur)) okunan.push(o);
  let ters = 0, enBuyukKayma = 0, enYuksek = -Infinity;
  const sonAnahtar = new Map();
  let anahtarIciTers = 0;
  for (const o of okunan) {
    if (o.t < enYuksek) { ters += 1; enBuyukKayma = Math.max(enBuyukKayma, enYuksek - o.t); }
    enYuksek = Math.max(enYuksek, o.t);
    if ((sonAnahtar.get(o.sayac) ?? -Infinity) > o.t) anahtarIciTers += 1;
    sonAnahtar.set(o.sayac, o.t);
  }
  return { adet, parca, ters, enBuyukKayma, anahtarIciTers, sure: t };
}

// Duraklama: tuketici P saniye durur, sonra K olay/sn ile yetisir. Akisin saklama suresi R'dir;
// P > R olan her saniyenin olaylari akistan duser ve BIR DAHA GELMEZ.
export const K = 55, R = 24 * 3600, COKME = 0.4;
export function duraklama(P) {
  const birikim = LAMBDA * P;
  const yetisme = K > LAMBDA ? birikim / (K - LAMBDA) : Infinity;
  return { birikim, yetisme, kacirilan: LAMBDA * Math.max(0, P - R), toplam: P + yetisme };
}
export const yenidenIslenen = (C) => LAMBDA * C * COKME;
```

```js
// yv/olc.mjs — ikincil dizinin kurtardigi sorgu ve bedeli; degisim akisinin tuketici tarafi
import { DIZIN, YANSITMA, yazmaBedeliAy, saklamaBedeliAy, eksikOge, eksikSorguPayi, akisiOku,
  duraklama, yenidenIslenen, OGE, OGE_BAYT, GUNLUK_YAZMA, GUNLUK_ISTEK, LAMBDA, K, R, COKME } from "./model.mjs";

const s = (x, n) => String(x).padStart(n);
const L = 0.8;
console.log(`taban tablo: ${(OGE / 1e6).toFixed(1)}M oge, ${(GUNLUK_YAZMA / 1e6).toFixed(2)}M yazma/gun, ` +
  `${(GUNLUK_ISTEK / 1e6).toFixed(1)}M istek/gun. Karsilanamayan orunttu: E2 %17, E4 %8, E6 %5 (toplam %30).`);
console.log(`dizin gecikmesi ${L} sn, olay hizi ${LAMBDA.toFixed(1)}/sn.\n`);
console.log("ikincil dizin        | kurtardigi istek/gun | dizinlenen oge | ek yazma (birim/ay) | ek saklama (birim/ay) | eksik oge | eksik sonuc");
console.log("---------------------|----------------------|----------------|---------------------|-----------------------|-----------|------------");
let kurtarilanT = 0, yazmaT = 0, saklamaT = 0;
for (const [ad, , agirlik, oran, hiz] of DIZIN) {
  const kurtarilan = GUNLUK_ISTEK * agirlik / 100;
  const yazma = yazmaBedeliAy(oran), saklama = saklamaBedeliAy(oran, 180);
  kurtarilanT += kurtarilan; yazmaT += yazma; saklamaT += saklama;
  console.log(`${ad.padEnd(20)} | ${s((kurtarilan / 1e6).toFixed(1) + "M (%" + agirlik + ")", 20)} | ` +
    `${s((OGE * oran / 1e6).toFixed(1) + "M", 14)} | ${s(yazma.toFixed(0), 19)} | ${s(saklama.toFixed(1), 21)} | ` +
    `${s(eksikOge(hiz, L).toFixed(1), 9)} | ${s("%" + (100 * eksikSorguPayi(hiz, L)).toFixed(1), 11)}`);
}
console.log(`toplam: gunde ${(kurtarilanT / 1e6).toFixed(1)}M istek kurtarildi (karsilanamayan %30 -> %0); ` +
  `bedel ayda ${(yazmaT + saklamaT).toFixed(0)} kurgu birim.`);
console.log(`ek yazma ek saklamanin ${(yazmaT / saklamaT).toFixed(0)} katidir: ikincil dizinin ` +
  `bedeli sakladigi bayt degil, her yazmanin ikinci kez yazilmasidir.`);

console.log("\nyansitma secimi (yalniz E2 dizini icin, 345.6M oge):");
console.log("yansitma          | oge basina bayt | dizin boyutu | saklama (birim/ay) | taban tabloya donus");
console.log("------------------|-----------------|--------------|--------------------|--------------------");
for (const [ad, bayt] of YANSITMA)
  console.log(`${ad.padEnd(17)} | ${s(bayt, 15)} | ${s((OGE * bayt / 1e9).toFixed(1) + " GB", 12)} | ` +
    `${s(saklamaBedeliAy(1, bayt).toFixed(0), 18)} | ${s(bayt === 180 ? "gerekmez" : "her oge icin 1 okuma", 19)}`);

const a = akisiOku({ tur: 24 });
console.log(`\ndegisim akisi: ${a.adet} olay, ${a.parca} parca, ${a.sure.toFixed(0)} sn'lik pencere. Tohum 20260804.`);
console.log(`genel zaman sirasinda ters gorunen olay: ${a.ters} (%${(100 * a.ters / a.adet).toFixed(1)}), ` +
  `en buyuk zaman kaymasi ${a.enBuyukKayma.toFixed(2)} sn.`);
console.log(`ayni bolum anahtari icinde ters gorunen olay: ${a.anahtarIciTers}. Garanti burada, genel sirada degil.`);
console.log(`yeniden isleme (konum kaydetme araligi C, gunde ${COKME} cokme):`);
console.log("C     | 1 sn | 5 sn | 15 sn | 60 sn | 300 sn");
console.log("olay  | " + [1, 5, 15, 60, 300].map((C) => s(yenidenIslenen(C).toFixed(0), C < 10 ? 4 : C < 100 ? 5 : 6)).join(" | "));

console.log(`\nduraklama: tuketici kapasitesi ${K} olay/sn, olay hizi ${LAMBDA.toFixed(1)}/sn ` +
  `-> yetisme carpani ${(K / (K - LAMBDA)).toFixed(2)}. Akis saklama suresi ${R / 3600} sa.`);
console.log("duraklama | birikmis olay | yetisme suresi | kesintiden tam yetismeye | kacirilan olay");
console.log("----------|---------------|----------------|--------------------------|---------------");
for (const P of [900, 3600, 4 * 3600, 12 * 3600, 24 * 3600, 30 * 3600]) {
  const d = duraklama(P);
  console.log(`${s((P / 3600).toFixed(2) + " sa", 9)} | ${s((d.birikim / 1e3).toFixed(0) + "K", 13)} | ` +
    `${s((d.yetisme / 3600).toFixed(2) + " sa", 14)} | ${s((d.toplam / 3600).toFixed(2) + " sa", 24)} | ` +
    `${s(d.kacirilan === 0 ? "0" : (d.kacirilan / 1e3).toFixed(0) + "K", 14)}`);
}
console.log(`kosumdan bagimsiz: kacirilan olay yalniz duraklama saklama suresini astiginda dogar ` +
  `(${R / 3600} sa) ve geri getirilemez; yetisme suresi bunu degistirmez, yalniz uzatir.`);

// Aktarim bedeli: tuketici baska bolgedeyse her olay bolge sinirindan gecer (olay = ogenin onceki
// ve sonraki goruntusu, yani oge boyutunun iki kati). Kurgu birim.
const gbAy = GUNLUK_YAZMA * 2 * OGE_BAYT * 30 / 1e9;
console.log(`\naktarim: ${gbAy.toFixed(1)} GB/ay olay trafigi. Tuketici ayni bolgede 0, baska ` +
  `bolgede ${(gbAy * 2).toFixed(0)}, bolge disinda ${(gbAy * 9).toFixed(0)} kurgu birim/ay.`);
```

```
taban tablo: 345.6M oge, 3.84M yazma/gun, 103.7M istek/gun. Karsilanamayan orunttu: E2 %17, E4 %8, E6 %5 (toplam %30).
dizin gecikmesi 0.8 sn, olay hizi 44.4/sn.

ikincil dizin        | kurtardigi istek/gun | dizinlenen oge | ek yazma (birim/ay) | ek saklama (birim/ay) | eksik oge | eksik sonuc
---------------------|----------------------|----------------|---------------------|-----------------------|-----------|------------
bolge | gun#sayac_id |          17.6M (%17) |         345.6M |              144000 |                  56.0 |       9.6 |      %100.0
gun | okuma_degeri   |            8.3M (%8) |           1.4M |                 576 |                   0.2 |       0.1 |       %13.3
gun#saat | sayac_id  |            5.2M (%5) |         345.6M |              144000 |                  56.0 |      35.6 |      %100.0
toplam: gunde 31.1M istek kurtarildi (karsilanamayan %30 -> %0); bedel ayda 288688 kurgu birim.
ek yazma ek saklamanin 2572 katidir: ikincil dizinin bedeli sakladigi bayt degil, her yazmanin ikinci kez yazilmasidir.

yansitma secimi (yalniz E2 dizini icin, 345.6M oge):
yansitma          | oge basina bayt | dizin boyutu | saklama (birim/ay) | taban tabloya donus
------------------|-----------------|--------------|--------------------|--------------------
yalniz anahtar    |              48 |      16.6 GB |                 15 | her oge icin 1 okuma
secili oznitelik  |              96 |      33.2 GB |                 30 | her oge icin 1 okuma
tum oznitelikler  |             180 |      62.2 GB |                 56 |            gerekmez

degisim akisi: 60000 olay, 16 parca, 1349 sn'lik pencere. Tohum 20260804.
genel zaman sirasinda ters gorunen olay: 56199 (%93.7), en buyuk zaman kaymasi 94.73 sn.
ayni bolum anahtari icinde ters gorunen olay: 0. Garanti burada, genel sirada degil.
yeniden isleme (konum kaydetme araligi C, gunde 0.4 cokme):
C     | 1 sn | 5 sn | 15 sn | 60 sn | 300 sn
olay  |   18 |   89 |   267 |  1067 |   5333

duraklama: tuketici kapasitesi 55 olay/sn, olay hizi 44.4/sn -> yetisme carpani 5.21. Akis saklama suresi 24 sa.
duraklama | birikmis olay | yetisme suresi | kesintiden tam yetismeye | kacirilan olay
----------|---------------|----------------|--------------------------|---------------
  0.25 sa |           40K |        1.05 sa |                  1.30 sa |              0
  1.00 sa |          160K |        4.21 sa |                  5.21 sa |              0
  4.00 sa |          640K |       16.84 sa |                 20.84 sa |              0
 12.00 sa |         1920K |       50.53 sa |                 62.53 sa |              0
 24.00 sa |         3840K |      101.05 sa |                125.05 sa |              0
 30.00 sa |         4800K |      126.32 sa |                156.32 sa |           960K
kosumdan bagimsiz: kacirilan olay yalniz duraklama saklama suresini astiginda dogar (24 sa) ve geri getirilemez; yetisme suresi bunu degistirmez, yalniz uzatir.

aktarim: 41.5 GB/ay olay trafigi. Tuketici ayni bolgede 0, baska bolgede 83, bolge disinda 373 kurgu birim/ay.
```

#### Dizin Sorguyu Kurtarır, Bedeli Yazmadan Alır

Üç dizin karşılanamayan üç örüntünün üçünü de kurtarıyor: günde 31,1M istek geri geliyor,
karşılanamayan pay yüzde 30'dan sıfıra iniyor. Fatura tek sütunda toplanıyor.

**Ek yazma ek saklamanın 2.572 katıdır.** Tam dizin ayda 144.000 kurgu birim ek yazma getirirken
aynı dizinin sakladığı 62,2 GB yalnız 56 birim tutuyor. Sebep, dizinin bir kopya olmaktan çok bir
**ikinci yazma yolu** olmasıdır: taban tabloya giden her öğe dizine de yazılır. İki tam dizin
ekleyen tasarım, veri katmanının yazma bedelini üçe katlar.

**Seyrek dizin bu kuralın istisnasıdır.** `gun | okuma_degeri` yalnız eşiği aşan öğeleri, yani
binde dördünü taşıyor ve aynı istekleri ayda 576 birime kurtarıyor: tam dizinin 250'de biri.
Dizinin bedelini belirleyen şey kaç sorguyu kurtardığı değil, **kaç yazmaya dokunduğudur.**

Son iki sütun eşzamansız güncellemenin sonucunu sayıyor. Dizin 0,8 saniye geride olduğu için
herhangi bir anda `bolge` dizininde 9,6, saat dizininde 35,6 öğe eksiktir; bölge toplamı ve son
bir saat sorguları neredeyse her koşumda eksik döner (yüzde 100), ama eksik olan pay küçüktür.
Asıl uyarı orta satırdadır: eşik taramalarının yüzde 13,3'ü, o an eşiği aşmış bir okumayı
görmüyor — sekiz taramadan biri taze alarmı kaçırıyor.

Yansıtma tablosu ikinci takası veriyor: yalnız anahtar taşıyan dizin 16,6 GB ve ayda 15 birim, tüm
öznitelikleri taşıyan 62,2 GB ve 56 birim. Aradaki 41 birim, dizinden dönen her öğe için taban
tabloya ek okuma yapmamanın karşılığıdır ve o okumalar 17,6M sorgu/gün ölçeğinde çok daha
pahalıdır.

#### Değişim Akışının Üç Sayısı

Aynı verinin ikinci bir kullanıcısı var: her yazmayı bir olay olarak dışarı veren **değişim
akışı**. Faturalama özetlerini üreten tüketici bu akıştan beslenir ve üç şeyi bilmek zorundadır.

**Sıra garantisi bölüm anahtarı içindedir, akışın tamamında değil.** 60.000 olayın 56.199'u, yani
yüzde 93,7'si, tüketiciye genel zaman sırasında ters görünüyor ve en büyük zaman kayması 94,73
saniye. Aynı sayacın olaylarında ters çift sayısı sıfır: garanti oradadır. İki farklı sayacın
olayını zaman sırasında geldi sanan bir tüketici yanılır.

**Teslim en az bir kezdir, tam bir kez değil.** Tüketici çöktüğünde son kaydedilen konumdan
başlar; konum aralığı 1 saniyeyken günde 18, 300 saniyeyken 5.333 olay ikinci kez işlenir. Bu
sayı bir hata değil, tüketicinin **etkisiz-tekrarlı** olması gereken aralıktır: aynı olayın ikinci
işlenişi faturaya ikinci kalem eklememelidir.

**Kaçırılan pencere geri getirilemez.** Son tablo tüketiciyi P saniye durduruyor. 12 saatlik bir
duraklamada 1,92M olay birikiyor ve tüketicinin yetişmesi 50,53 saat sürüyor — kesintiden tam
yetişmeye 62,53 saat. Buna karşın **kaçırılan olay sıfırdır**, çünkü tüketici her zaman en eskiyi
önce okur ve hiçbir olay duraklama süresinden fazla beklemez. Sınır tek bir yerdedir: duraklama
akışın saklama süresini aştığı anda. 30 saatlik duraklamada 960K olay akıştan düşer ve bir daha
gelmez. Bu, kursun geri alınamayan kalemler listesine yeni bir satır ekler — ve ilk kez geri
alınamayan şey bir karar değil, **bir zaman aralığıdır**.

Aktarım satırı kısa: 41,5 GB/ay olay trafiği aynı bölgede ücretsiz, başka bölgede 83, bölge
dışında 373 kurgu birim — yazma hızıyla ölçeklenen bir kalem.

#### Özet

- Üç ikincil dizin karşılanamayan üç örüntünün üçünü de kurtarıyor (günde 31,1M istek, %30'dan
  %0'a) ve bedeli saklama değil yazmadır: ek yazma ek saklamanın **2.572 katı** (144.000'e karşı 56
  kurgu birim/ay); seyrek dizin aynı sorguları 576 birime kurtarıyor.
- Eşzamansız dizin 0,8 saniye geridedir: bölge dizininde 9,6, saat dizininde 35,6 öğe eksik ve eşik
  taramalarının %13,3'ü o an eşiği aşmış bir okumayı görmüyor.
- Yansıtma saklama ile okuma arasında takastır: yalnız anahtar 16,6 GB ve 15 birim, tüm öznitelikler
  62,2 GB ve 56 birim — ama ilki her sonuç öğesi için taban tabloya bir okuma ekler.
- Değişim akışında sıra yalnız bölüm anahtarı içinde korunur: genel sırada olayların %93,7'si ters
  görünüyor (en büyük kayma 94,73 sn), anahtar içi ters çift sıfır.
- Kaçırılan pencere tek geri alınamayan kalemdir: duraklama saklama süresini aşana kadar kayıp
  yok, aştığında (30 sa) 960K olay düşüyor ve geri gelmiyor.

#### Sonraki Adım

Bu dört ders veri katmanının iki ucunu ölçtü ve ikisinde de aynı şey görüldü: kararın devri ucuz,
geri alınması pahalı. Ama her istek diske gitti. Oysa ölçüm ağının en sık sorulan şeyi çok dar bir
kümedir — son okuma değeri, sayaç kütüğü, açık alarm listesi — ve bunları her seferinde taban
tablodan okumak aynı yanıtı gün boyunca binlerce kez üretmek demektir. Sonraki ders bu tekrarı
bellek içi bir katmana taşıyan yönetilen önbellek servisini ele alır ve yalnız **hizmet olmasının**
getirdiğini sayar: hangi karar devrediliyor, ölçekleme birimi ne, düğüm kaybedildiğinde açılan veri
kaybı penceresi ne kadar.

### Yönetilen Önbellek Servisi

Source: https://academia.sh/tr/kurslar/bulut-depolama/yonetilen-onbellek-servisi

Bellek içi katmanın hizmet olarak kiralanmasının ölçülmesi: iki ölçekleme ekseninin aynı isabeti ve aynı faturayı vermesi, yüzde yüz isabetin en pahalı satır çıkması, bir düğüm değiştiğinde giden üç milyon üç yüz yetmiş bin anahtarın satın alınan kapasiteyi yüzde üç yüz yirmi beş aşması, ısınmanın parça sayısıyla kısalmaması ve başka alandaki önbelleğin yedi yüz yirmi iki birimlik aktarım kalemi yazıp önbelleksiz düzenden pahalıya gelmesi.

Bir önceki ders erişim örüntüsünü genişletti: ikincil dizin ve değişim akışı, bölüm anahtarının
kapattığı sorguların bir bölümünü geri açtı. Ama açılan her sorgu hâlâ veri katmanına iniyor.

Bellek içi depolar ve tahliye politikaları daha önce ölçüldü; bu ders o mekaniği tekrarlamaz.
Burada bellek içi katman **kiralanan bir hizmettir** ve ölçülen üç şey ölçekleme biriminin ne
olduğu, bir düğüm değiştiğinde ne gittiği ve önbelleğin nerede durduğunun faturaya ne yazdığıdır.

- **YV25.** Kurgu bölgesel ölçüm ağının okuma kümesi üç ailedir: sayaç son okuması (2,4 milyon
  anahtar, 180 bayt), fatura özeti (600 bin, 2.400 bayt), iş emri kaydı (4 milyon, 600 bayt);
  toplam 4,272 GB.
- **YV26.** Her aile üç popülerlik dilimiyle modellenir. Model önbelleği anahtar başına olasılık
  sırasına göre doldurur, ilk dokunuş ıskalarını saymaz, rastgelelik kullanmaz.
- **YV27.** Okuma ortalama dört yüz, tepede üç bin istek/s; ayrıca sürekli dört yüz istek/s yazma
  vardır ve yazma önbelleğe uğramaz. Bir ay 2.592.000 saniye sayılır.
- **YV28.** Fiyatlar kurgudur, para biriminin adı **birim**dir: önbellek düğümü GB başına ayda
  altmış birim; okuma kapasitesi yüz istek/s adımıyla satın alınır, adım ayda otuz birimdir.
  Sağlayıcı düğüm belleğinin **yüzde yetmiş beşini** kullanıma açar.
- **YV29.** Gecikmeler kurgudur: veri katmanı 6 ms, aynı alandaki yönetilen önbellek 0,8 ms, başka
  alandaki 1,9 ms, süreç içi 0,02 ms. Alanlar arası aktarım GB başına bir birimdir.
- **YV30.** Sayaç toplayıcısı dakikalık toplamayı önbellekte biriktirip beş saniyede bir boşaltır;
  önbellek kopyasının gecikmesi 0,25 saniyedir. İkisi de kurgudur.

```js
// onbellek/onbellek.mjs — model: bellek ici katman hizmet olarak kiralandiginda ne degisiyor.
// Tahliye politikalari M17/K06'da olculdu, tekrarlanmaz. Is kumesi populerlik dilimleriyle
// modellenir, rastgelelik yok; fiyatlar kurgudur ve 1 GB = 1e9 bayt sayilir.
const DILIM = [                       // [aile, dilim, anahtar, bayt, erisim payi]
  ["sayac", "sicak", 150000, 180, 0.15], ["sayac", "ilik", 850000, 180, 0.20],
  ["sayac", "soguk", 1400000, 180, 0.16],
  ["fatura", "sicak", 18000, 2400, 0.10], ["fatura", "ilik", 140000, 2400, 0.09],
  ["fatura", "soguk", 442000, 2400, 0.04],
  ["isemri", "sicak", 80000, 600, 0.06], ["isemri", "ilik", 620000, 600, 0.10],
  ["isemri", "soguk", 3300000, 600, 0.10],
];
const SIRA = [...DILIM].sort((a, b) => b[4] / b[2] - a[4] / a[2]);  // anahtar basina olasilik
const doldur = (kap) => {             // onbellek en cok istenen anahtardan baslayarak dolar
  let kalan = kap, anahtar = 0, isabet = 0;
  const tutulan = [];
  for (const [, , n, b, pay] of SIRA) {
    const alinan = Math.min(n, Math.floor(kalan / b));
    if (alinan === 0) break;
    kalan -= alinan * b; anahtar += alinan; isabet += pay * alinan / n;
    tutulan.push([pay * alinan / n, pay / n]);   // [tutulan pay, anahtar basina olasilik]
  }
  return { anahtar, isabet, tutulan };
};
const TEPE = 3000, YAZMA = 400, ORAN = 0.75, GB_UCRET = 60;
const ucret = (inen) => Math.ceil((inen + YAZMA) / 100) * 30;
const sutun = (E, sol = 1) => (h) =>
  h.map((d, i) => String(d)[i < sol ? "padEnd" : "padStart"](E[i])).join("");
const y1 = sutun([14, 5, 16, 14, 11, 15, 10, 8, 15]);
console.log(y1(["dugum x GB", "GB", "kullanilabilir", "anahtar(bin)", "isabet(%)",
  "inen(istek/s)", "kapasite", "dugum", "toplam(birim)"]));
for (const [ad, d, g] of [["onbellek yok", 0, 0], ["1 x 1", 1, 1], ["1 x 2", 1, 2],
  ["2 x 1", 2, 1], ["1 x 4", 1, 4], ["1 x 8", 1, 8]]) {
  const o = d ? doldur(d * g * 1e9 * ORAN) : { anahtar: 0, isabet: 0 };
  const inen = Math.round(TEPE * (1 - o.isabet));
  const kap = ucret(inen), dug = d * g * GB_UCRET;
  console.log(y1([ad, d * g, (d * g * ORAN).toFixed(2), (o.anahtar / 1e3).toFixed(0),
    (o.isabet * 100).toFixed(1), inen, kap, dug, kap + dug]));
}

// --- Bir dugum degistiginde ------------------------------------------------------
// 2 GB duzen. Karma anahtar adini dagittigi icin her parca her dilimden esit pay alir.
const D = doldur(2 * 1e9 * ORAN), INEN = Math.round(TEPE * (1 - D.isabet)) + YAZMA;
const ALINAN = ucret(INEN - YAZMA) / 30 * 100, BEKLEYEN = YAZMA * 5, GECIKME = 0.25;
const y2 = sutun([14, 18, 16, 15, 10, 15]);
console.log("\n" + y2(["parca", "kaybolan anahtar", "kaybolan erisim", "inen(istek/s)",
  "asim(%)", "bekleyen kayit"]));
for (const [p, kopyali] of [[1, 0], [2, 0], [4, 0], [8, 0], [16, 0], [4, 1]]) {
  const anahtar = Math.round((kopyali ? INEN * GECIKME : D.anahtar) / p);
  const pay = kopyali ? 0 : D.isabet / p;
  const inen = Math.round(TEPE * (1 - D.isabet + pay)) + YAZMA;
  console.log(y2([kopyali ? `${p} (kopyali)` : p, anahtar, (pay * 100).toFixed(1), inen,
    ((inen / ALINAN - 1) * 100).toFixed(0),
    Math.round((kopyali ? YAZMA * GECIKME : BEKLEYEN) / p)]));
}
const donen = (t) => D.tutulan.reduce((a, [pay, r]) => a + pay * (1 - Math.exp(-r * TEPE * t)), 0);
const isinma = (oran) => {
  let alt = 1, ust = 1e6;
  for (let k = 0; k < 60; k++) {
    const t = Math.sqrt(alt * ust);
    if (donen(t) < oran * D.isabet) alt = t; else ust = t;
  }
  return ust.toFixed(0);
};
console.log(`isinma, parca sayisindan bagimsiz: %50 ${isinma(0.5)} s, %90 ${isinma(0.9)} s`);

// --- Onbellek nerede duruyor -----------------------------------------------------
const VERI_MS = 6, ALAN_UCRET = 1, AY = 2592000;   // ms; alanlar arasi birim/GB; saniye/ay
const ORT_BAYT = DILIM.reduce((a, [, , , b, pay]) => a + b * pay, 0);
const y3 = sutun([10, 26, 11, 14, 11, 11, 10, 15], 2);
const satir = (kume, ad, h, ms, okuma, bayt, tepe, yazma, onbellek, uzak) => {
  const inen = Math.round(tepe * (1 - h));
  const kapasite = Math.max(1, Math.ceil((inen + yazma) / 100)) * 30;
  const aktarim = (uzak ? h * okuma * bayt / 1e9 : 0) * ALAN_UCRET;
  console.log(y3([kume, ad, (h * 100).toFixed(1), (ms + (1 - h) * VERI_MS).toFixed(2),
    onbellek, kapasite, aktarim.toFixed(0), (onbellek + kapasite + aktarim).toFixed(0)]));
};
console.log("\n" + y3(["kume", "duzen", "isabet(%)", "gecikme(ms)", "onbellek", "kapasite",
  "aktarim", "toplam(birim)"]));
const TAM = (ad, h, ms, onbellek, uzak) =>
  satir("tam kume", ad, h, ms, 400 * AY, ORT_BAYT, TEPE, YAZMA, onbellek, uzak);
TAM("onbellek yok", 0, 0, 0, false);
TAM("surec ici 12 x 256 MB", doldur(256e6).isabet, 0.02, 0, false);
TAM("yonetilen 2 GB ayni alan", D.isabet, 0.8, 2 * GB_UCRET, false);
TAM("yonetilen 2 GB baska alan", D.isabet, 1.9, 2 * GB_UCRET, true);
// Tarife tablosu: 20 bin anahtar x 2000 bayt = 40 MB, ayda 320 milyon okuma, tepe 900/s.
const TAR = (ad, h, ms, onbellek, uzak) =>
  satir("tarife", ad, h, ms, 320e6, 2000, 900, 0, onbellek, uzak);
TAR("surec ici 12 x 40 MB", 1, 0.02, 0, false);
TAR("yonetilen 1 GB ayni alan", 1, 0.8, GB_UCRET, false);
TAR("yonetilen 1 GB baska alan", 1, 1.9, GB_UCRET, true);
```

```
dugum x GB       GB  kullanilabilir  anahtar(bin)  isabet(%)  inen(istek/s)  kapasite   dugum  toplam(birim)
onbellek yok      0            0.00             0        0.0           3000      1020       0           1020
1 x 1             1            0.75          1476       63.8           1085       450      60            510
1 x 2             2            1.50          3370       87.0            390       240     120            360
2 x 1             2            1.50          3370       87.0            390       240     120            360
1 x 4             4            3.00          4880       93.6            193       180     240            420
1 x 8             8            6.00          7000      100.0              0       120     480            600

parca           kaybolan anahtar kaybolan erisim  inen(istek/s)   asim(%) bekleyen kayit
1                        3370000            87.0           3400       325           2000
2                        1685000            43.5           2095       162           1000
4                         842500            21.8           1442        80            500
8                         421250            10.9           1116        40            250
16                        210625             5.4            953        19            125
4 (kopyali)                   49             0.0            790        -1             25
isinma, parca sayisindan bagimsiz: %50 539 s, %90 3514 s

kume      duzen                       isabet(%)   gecikme(ms)   onbellek   kapasite   aktarim  toplam(birim)
tam kume  onbellek yok                      0.0          6.00          0       1020         0           1020
tam kume  surec ici 12 x 256 MB            34.7          3.94          0        720         0            720
tam kume  yonetilen 2 GB ayni alan         87.0          1.58        120        240         0            360
tam kume  yonetilen 2 GB baska alan        87.0          2.68        120        240       722           1082
tarife    surec ici 12 x 40 MB            100.0          0.02          0         30         0             30
tarife    yonetilen 1 GB ayni alan        100.0          0.80         60         30         0             90
tarife    yonetilen 1 GB baska alan       100.0          1.90         60         30       640            730
```

#### İki Eksen, Tek Eğri

Yönetilen önbellek servisi iki ölçekleme kolu sunar: düğümü büyütmek ve düğüm eklemek. Birinci
tablo ikisini yan yana koyuyor ve ilk okuma şudur: **fark yok.** İki GB'a bir düğümle de iki
düğümle de varılıyor; ikisinde de önbellekte üç milyon üç yüz yetmiş bin anahtar, isabet yüzde
seksen yedi, fatura üç yüz altmış birim. Ölçekleme birimi kararı **isabet ve fiyat üzerinden
verilemez.**

Faturanın kendisi ikinci okumadır. Önbelleksiz düzen bin yirmi birim; bir GB isabeti yüzde altmış
üç virgül sekize çıkarıp faturayı beş yüz ona, iki GB üç yüz altmışa indiriyor. Sonra eğri
**dönüyor**: dört GB'da dört yüz yirmi, sekiz GB'da altı yüz. Yüzde yüz isabetli satır iki GB'lık
satırdan **yüzde altmış yedi pahalıdır**; kalan yüz yirmi birim önbelleğe hiç uğramayan dört yüz
istek/s yazmaya gidiyor ve onu düşürmenin yolu önbellek değildir.

Kullanılabilir sütunu üçüncü okumadır: sekiz GB satın alındığında altı GB kullanılıyor, aradaki
dörtte bir sağlayıcının defterine gidiyor. İş kümesi 4,272 GB olduğuna göre onu tümüyle bellekte
tutmak için gereken düğüm dört GB değil, sekiz GB'dır.

#### Bir Düğüm Değiştiğinde

Düğüm değişimi olağan bir olaydır — sürüm yükseltmesi, yama penceresi ya da arızalı düğümün yerine
konması — ve önbellek kalıcı değildir: değişen düğümün belleği boş gelir.

Tek parçalı düzende üç milyon üç yüz yetmiş bin anahtarın **tamamı** gidiyor. İnen istek yedi yüz
doksandan üç bin dört yüze çıkıyor ve satın alınan sekiz yüz istek/s kapasitenin **yüzde üç yüz
yirmi beş üstüne** oturuyor. Bu bir çökme değil, kısılmadır: veri katmanı fazlasını geri çevirir,
pano boş döner.

Parça sayısı dalganın **yüksekliğini** düşürüyor: dört parçada aşım yüzde seksen, on altı parçada
yüzde on dokuz. Sayı düşüyor ama **hiçbir parça sayısında sıfırlanmıyor.** Son satır tek çözümü
gösteriyor: her parçaya bir kopya eklendiğinde düğüm değişimi devralmaya dönüşüyor ve giden anahtar
kırk dokuza — çeyrek saniyelik kopya gecikmesinde yazılmış anahtarlara — iniyor. Bedeli birinci
tabloda okunur: düğüm ücreti yüz yirmiden iki yüz kırka, toplam üç yüz altmıştan dört yüz seksene
çıkar.

Son sütun bu dersin **geri alınamayan kalemidir**. Toplayıcı dakikalık toplamayı önbellekte
biriktirip beş saniyede bir yazıyor; her an iki bin kayıt yalnızca bellektedir ve dört parçalı
düzende bir düğüm gittiğinde bunların beş yüzü kaybolur. Önbellekteki bir kopya geri getirilebilir,
önbellekteki bir **asıl** getirilemez.

Isınma satırı dalganın uzunluğunu veriyor: erişim payının yarısı beş yüz otuz dokuz, yüzde doksanı
3.514 saniyede geri geliyor. Bu süre **parça sayısından bağımsızdır**: karma anahtar adını
dağıttığı için her parça her popülerlik diliminden aynı oranda pay alır ve bir parçanın ısınma
eğrisi bütünün eğrisiyle aynıdır. **Bölmek dalganın yüksekliğini düşürür, uzunluğunu düşürmez.**
Dört parçalı düzende veri katmanı bir saate yakın süre satın alınanın üstünde yük taşır; o
pencerenin ne zaman açılacağı senin kararın değildir.

#### Önbellek Nerede Duruyor

Üçüncü tablonun ilk dört satırı aynı okumayı dört düzende karşılıyor. Yönetilen önbellek aynı
alanda durduğunda hem en ucuz hem en hızlıdır: üç yüz altmış birim, 1,58 ms.

Süreç içi önbellek satırı hizmet olmanın ne getirdiğini gösteriyor. On iki uygulama örneğinin her
biri iki yüz elli altı MB ayırıyor — toplam üç GB — ve isabet yüzde otuz dört virgül yedide
kalıyor; yönetilen önbellek bir buçuk GB kullanarak yüzde seksen yediye çıkıyor. Fark bellek
miktarında değil, **havuzun tekliğinde**: on iki ayrı önbellek aynı anahtarların on iki kopyasını
tutar ve her biri yalnız kendi gördüğü isteklerle ısınır.

Dördüncü satır bu dersin aktarım kalemidir. Önbellek başka bir alana konduğunda isabet değişmiyor
ve faturaya **yedi yüz yirmi iki birimlik** yeni bir kalem yazılıyor: ayda bir milyar otuz altı
milyon sekiz yüz bin okumanın yüzde seksen yedisi, ortalama sekiz yüz bayt yanıt, GB başına bir
birim. Önbellek düğümünün kendisi yüz yirmi birimdir; yanlış alana koymanın bedeli düğümün **altı
katıdır** ve toplam bin seksen iki birim, yani **önbelleksiz düzenden pahalı**.

#### Kazandırmadığı Durum

Son üç satır bölge tarife tablosunu ölçüyor: kırk MB, ayda üç yüz yirmi milyon okuma, her düzene
tümüyle sığan bir küme. Süreç içi önbellek otuz birime ve 0,02 milisaniyeye mal oluyor; aynı
alandaki yönetilen önbellek doksan birim ve 0,80 ms — üç kat pahalı, kırk kat yavaş. Başka alanda
yedi yüz otuz birim, yani **yirmi dört katı**.

Yönetilen önbellek burada hiçbir şey kazandırmıyor: küme zaten her sürecin belleğine sığdığı için
paylaşılan havuz gereksizdir, ağ üzerinden erişim saf bedeldir. Kural şudur: **yönetilen önbellek,
iş kümesi tek sürecin belleğine sığmadığında kazandırır.** Süreç içi düzenin bedeli tabloda yok:
on iki kopya, on iki ayrı tazelik penceresidir.

#### Devredilen Karar

Kiralanan kümede kararlar şöyle bölünüyor:

| Grup | Sende | Sağlayıcıda | Yaratılışta sabit |
|---|---|---|---|
| sürüm | motor sürümü, yama penceresi | yamanın zorunlu olduğu an | — |
| bakım | yedekleme açık mı | değişim zamanı, düğüm yenileme, yedeğin yeri | — |
| ölçekleme | düğüm boyutu, parça sayısı, kopya sayısı | kullanılabilir bellek oranı | parça sayısı |
| veri | tahliye politikası, anahtar adlandırması, yaşam süresi | değişimde giden veri | — |
| ağ | kümenin alanı | istemcinin düştüğü düğüm | kümenin alanı |

On yedi kalemin **onu sende**, yedisi sağlayıcıda, ikisi yaratılışta sabit. Bakım grubunun dört
kaleminin üçü devredilmiştir; ikinci tablonun bir saatlik ısınma penceresi buraya bağlanır —
pencerenin **ne zaman açılacağına** karar veren sen değilsin.

Motor sürümünü sen seçiyorsun ama seçim tek yönlüdür: yükseltilen bir küme eski sürüme dönmez.
Ölçeklemede sabitlenen kalem **parça sayısıdır**; değiştirildiğinde bütün anahtarlar yeniden
dağıtılır ve dağıtım boyunca isabet düşer. Birinci tablonun "aynı isabet, aynı fiyat" sonucu bu
yüzden yanıltıcıdır: iki kol aynı yere çıkar ama biri geri dönülebilir, diğeri değildir. Kümenin
alanı da sabittir ve yedi yüz yirmi iki birimlik kalem doğrudan buna bağlıdır.

#### Özet

- İki GB'a hangi yoldan varılırsa varılsın isabet yüzde seksen yedi, fatura üç yüz altmış birim:
  ölçekleme birimi kararı isabetten ve fiyattan okunamaz.
- Fatura eğrisi dönüyor: önbelleksiz bin yirmi, bir GB'da beş yüz on, iki GB'da üç yüz altmış, dört
  GB'da dört yüz yirmi, sekiz GB'da altı yüz birim. Yüzde yüz isabet en pahalı satırdır.
- Tek parçalı bir düğüm değişimi inen isteği satın alınan kapasitenin yüzde üç yüz yirmi beş üstüne
  çıkarıyor; on altı parçada bu yüzde on dokuza iner ama sıfırlanmaz. Isınma her düzende 3.514
  saniyedir. Geri alınamayan kalem yazma-arkası kipte bekleyen kayıtlardır.
- Önbelleği başka alana koymak yedi yüz yirmi iki birimlik aktarım kalemi yazıp toplamı önbelleksiz
  düzenin üstüne çıkarıyor. Kırk MB'lık tarife tablosunda süreç içi önbellek otuz, yönetilen
  önbellek doksan birim tutuyor: iş kümesi tek sürece sığdığında yönetilen önbellek kazandırmaz.

#### Sonraki Adım

Bu derste aktarım tek bir sütundu ve tek bir fiyatı vardı: alanlar arası, GB başına bir birim. O
tek sütun, yerleşim kararı yanlış olduğunda faturanın en büyük kalemi oldu.

Ölçüm ağının geri kalanında aynı sütun defalarca yazılıyor: toplayıcı veri katmanına yazıyor, veri
katmanı okuma kopyasına çoğaltıyor, yedekler gönderiliyor, günlükler akıyor, pano yanıtları genel
ağa çıkıyor. Her akış, kaynağının ve hedefinin **nerede durduğuna** göre farklı fiyatlanıyor: aynı
alan, komşu alan, uzak bölge ya da internet.

Sonraki ders bu kursun para dersidir: aynı mimari üç yerleşimde koşturulup çıkış ücreti kalem kalem
çıkarılır, ardından kopya sayısı, günlük ve yedek gönderimi, kenar kullanımı ve sıkıştırma
kararlarının bu ücrete etkisi sayılır.

### Veri Aktarımı ve Çıkış Maliyeti

Source: https://academia.sh/tr/kurslar/bulut-depolama/veri-aktarimi-ve-cikis-maliyeti

Bölge ve internet çıkışının ölçülmesi: aynı altı bin yüz seksen GB'ın tek alanda bin dört yüz kırk, iki alanda dört bin üç yüz seksen, iki bölgede yedi bin üç yüz yirmi birim yazması, sıkıştırmanın bin dört yüz altmış üç birim indirirken ikinci okuma kopyasının bin dört yüz birim eklemesi, aynı bin GB'ın içeri girerken sıfır çıkarken dokuz bin birim tutması ve yirmi dört ayda biriken otuz üç bin altı yüz GB'ı çıkarmanın altmış dokuz aylık faturaya denk gelmesi.

Bir önceki ders önbelleği yanlış alana koymanın yedi yüz yirmi iki birimlik bir kalem yazdığını
gösterdi. O kalem tek bir akıştan geliyordu ve tek bir fiyatı vardı.

Ölçüm ağının tamamına bakıldığında sekiz ayrı akış var: sayaç toplayıcısı veri katmanına yazıyor,
uygulama veri katmanından ve okuma kopyasından okuyor, önbelleğe yazıyor, veri katmanı okuma
kopyasına çoğaltıyor, yedekler bir depoya gidiyor, günlükler toplayıcıya akıyor ve pano yanıtları
genel ağa çıkıyor. Sonuncusu dışında hiçbiri istemci trafiği değil; yedisi sistemin kendi iç
trafiği. Ve hepsi ücretli olabiliyor.

Belirleyen şey bayt miktarı değil, **iki ucun nerede durduğudur**. Bu ders aynı mimariyi üç
yerleşimde koşturuyor, çıkış ücretini kalem kalem çıkarıyor, beş tasarım kararının bu ücrete
etkisini tek tek ölçüyor ve verinin girmesiyle çıkması arasındaki bakışımsızlığı sayıyor.

- **YV31.** Kurgu bölgesel ölçüm ağının aylık akışları GB olarak şunlardır: toplayıcı → veri
  katmanı 1.400, veri katmanı → uygulama 900, uygulama → önbellek 780, veri katmanı → okuma
  kopyası 1.400, okuma kopyası → uygulama 620, veri katmanı → yedek 600, uygulama → günlük 320,
  uygulama → internet 160. Toplam 6.180 GB.
- **YV32.** Fiyatlar kurgudur, para biriminin adı **birim**dir: alan içi 0, alanlar arası 1,
  bölgeler arası 2, internete 9 birim/GB. İnternetten içeri giren bayt ücretsizdir. Modelin
  gerçeğe dayandığı tek nokta bu sıralamadır.
- **YV33.** Üç yerleşim ölçülür: her şey tek alanda; okuma kopyası, yedek ve günlük toplayıcısı
  ikinci alanda; aynı üçü ikinci bölgede.
- **YV34.** Sıkıştırma yalnız günlük, yedek ve pano yanıtlarına uygulanır ve kurgu oranı 0,38'dir.
  Çoğaltma akışı zaten sıkıştırılmış, sayaç yazmaları sıkıştırmaya değmeyecek kadar küçüktür.
- **YV35.** Kenar isabeti **yüzde altmış yedidir** ve kenar çıkışı GB başına beş birimdir. İkisi de
  M23/K02'de ölçüldü; burada girdi olarak kullanılır, yeniden ölçülmez.
- **YV36.** Veri katmanı ve nesne deposu birlikte ayda net 1.400 GB büyür; toplu çıkarma bir
  Gbit/s hattan yapılır. İkisi de kurgudur.

```js
// veri/cikis.mjs — model: ayni mimari uc yerlesimde kosturulup cikis ucreti kalem kalem
// cikariliyor. Akislar, fiyatlar ve buyume kurgudur; para biriminin adi "birim"dir.
// Kenarin isabet orani M23/K02'de olculdu, burada girdidir. Rastgelelik yok.
const AKIS = [                         // [kaynak, hedef, aylik GB]
  ["toplayici", "veri", 1400], ["veri", "uygulama", 900], ["uygulama", "onbellek", 780],
  ["veri", "kopya", 1400], ["kopya", "uygulama", 620], ["veri", "yedek", 600],
  ["uygulama", "gunluk", 320], ["uygulama", "internet", 160],
];
const TEK = { toplayici: "b1a1", veri: "b1a1", uygulama: "b1a1", onbellek: "b1a1",
  kopya: "b1a1", yedek: "b1a1", gunluk: "b1a1" };
const ALAN = { ...TEK, kopya: "b1a2", yedek: "b1a2", gunluk: "b1a2" };
const BOLGE = { ...TEK, kopya: "b2a1", yedek: "b2a1", gunluk: "b2a1" };
const FIYAT = { "alan ici": 0, "alanlar arasi": 1, "bolgeler arasi": 2, "internete": 9 };
const sinif = (y, k, h) => h === "internet" ? "internete"
  : y[k] === y[h] ? "alan ici" : y[k][1] === y[h][1] ? "alanlar arasi" : "bolgeler arasi";
const hesap = (akis, y) => {
  const gb = { "alan ici": 0, "alanlar arasi": 0, "bolgeler arasi": 0, "internete": 0 };
  for (const [k, h, v] of akis) gb[sinif(y, k, h)] += v;
  const toplam = Object.keys(gb).reduce((a, s) => a + gb[s] * FIYAT[s], 0);
  return { gb, toplam, tumGB: akis.reduce((a, f) => a + f[2], 0) };
};
const sutun = (E, sol = 1) => (h) =>
  h.map((d, i) => String(d)[i < sol ? "padEnd" : "padStart"](E[i])).join("");
const y1 = sutun([16, 12, 16, 17, 12, 11, 15]);
console.log(y1(["yerlesim", "alan ici", "alanlar arasi", "bolgeler arasi", "internete",
  "toplam GB", "ucret(birim)"]));
for (const [ad, y] of [["tek alan", TEK], ["iki alan", ALAN], ["iki bolge", BOLGE]]) {
  const r = hesap(AKIS, y);
  console.log(y1([ad, ...Object.values(r.gb), r.tumGB, r.toplam.toFixed(0)]));
}

// --- Tasarim kararinin faturaya yazdigi ------------------------------------------
// Taban: iki alan. Her karar tabana tek basina uygulanir.
const TABAN = hesap(AKIS, ALAN);
const degis = (akis, hedef, carpan) =>
  akis.map(([k, h, gb]) => [k, h, h === hedef ? gb * carpan : gb]);
const SIK = 0.38, ISABET = 0.67, KENAR = 5;   // sikistirma orani; kenar isabeti ve birim/GB
const kenarli = 160 * KENAR + 160 * (1 - ISABET) * FIYAT["internete"];
const KARAR = [
  ["ikinci okuma kopyasi", hesap([...AKIS, ["veri", "kopya2", 1400]],
    { ...ALAN, kopya2: "b1a2" })],
  ["gunluk ornekleme 1/5", hesap(degis(AKIS, "gunluk", 0.2), ALAN)],
  ["yedegi uzak bolgeye", hesap(AKIS, { ...ALAN, yedek: "b2a1" })],
  ["kenar, isabet %67", { tumGB: TABAN.tumGB, toplam: TABAN.toplam - 160 * 9 + kenarli }],
  ["sikistirma, oran 0.38", hesap(["gunluk", "yedek", "internet"]
    .reduce((a, h) => degis(a, h, SIK), AKIS), ALAN)],
];
const y2 = sutun([24, 13, 14, 15]);
console.log("\n" + y2(["karar", "GB farki", "ucret farki", "yeni toplam"]));
console.log(y2(["taban: iki alan", TABAN.tumGB.toFixed(0), "-", TABAN.toplam.toFixed(0)]));
for (const [ad, r] of KARAR)
  console.log(y2([ad, (r.tumGB - TABAN.tumGB).toFixed(0),
    (r.toplam - TABAN.toplam).toFixed(0), r.toplam.toFixed(0)]));

// --- Girmesi ucuz, cikmasi pahali ------------------------------------------------
const y3 = sutun([22, 14, 18]);
console.log("\n" + y3(["1000 GB nereye", "birim/GB", "ucret(birim)"]));
console.log(y3(["internetten iceri", 0, 0]));
for (const s of Object.keys(FIYAT)) console.log(y3([s, FIYAT[s], 1000 * FIYAT[s]]));
const BUYUME = 1400, HAT = 1;                 // net buyume GB/ay; cikarma hatti Gbit/s
const y4 = sutun([10, 14, 18, 18, 14]);
console.log("\n" + y4(["ay", "biriken GB", "cikarma(birim)", "kac aylik fatura", "hat(gun)"]));
for (const ay of [12, 24, 36]) {
  const gb = BUYUME * ay, uc = gb * FIYAT["internete"];
  console.log(y4([ay, gb, uc, (uc / TABAN.toplam).toFixed(1), (gb * 8 / HAT / 86400).toFixed(1)]));
}
```

```
yerlesim            alan ici   alanlar arasi   bolgeler arasi   internete  toplam GB   ucret(birim)
tek alan                6020               0                0         160       6180           1440
iki alan                3080            2940                0         160       6180           4380
iki bolge               3080               0             2940         160       6180           7320

karar                        GB farki   ucret farki    yeni toplam
taban: iki alan                  6180             -           4380
ikinci okuma kopyasi             1400          1400           5780
gunluk ornekleme 1/5             -256          -256           4124
yedegi uzak bolgeye                 0           600           4980
kenar, isabet %67                   0          -165           4215
sikistirma, oran 0.38            -670         -1463           2917

1000 GB nereye              birim/GB      ucret(birim)
internetten iceri                  0                 0
alan ici                           0                 0
alanlar arasi                      1              1000
bolgeler arasi                     2              2000
internete                          9              9000

ay            biriken GB    cikarma(birim)  kac aylik fatura      hat(gun)
12                 16800            151200              34.5           1.6
24                 33600            302400              69.0           3.1
36                 50400            453600             103.6           4.7
```

#### Aynı Bayt, Üç Fatura

Birinci tablonun en önemli sütunu **toplam GB**'dir ve üç satırda da aynıdır: 6.180. Hiçbir
yerleşimde tek bir bayt fazla ya da eksik taşınmıyor. Aynı bileşenler, aynı akışlar, aynı hacim.

Fatura ise bin dört yüz kırk, dört bin üç yüz seksen ve yedi bin üç yüz yirmi birim. **Beş kattan
fazla fark.** Tek değişen, hangi bileşenin nerede durduğudur.

Tek alan satırında 6.020 GB alan içi kalıyor ve alan içi sıfır ücretlidir; geriye yalnız yüz altmış
GB internet çıkışı ve onun bin dört yüz kırk birimi kalıyor. Bu satırın faturası tümüyle
istemciye giden trafiktir; iç trafiğin bedeli yoktur.

İkinci satırda okuma kopyası, yedek deposu ve günlük toplayıcısı komşu alana taşınıyor. Taşınan
bileşen sayısı üç, taşınan akış sayısı dört: veri katmanından kopyaya çoğaltma (1.400), kopyadan
uygulamaya okuma (620), veri katmanından yedeğe (600) ve uygulamadan günlüğe (320). Toplam 2.940
GB, sınıf değiştirdiği anda GB başına bir birim yazıyor. Fatura **üç katına** çıkıyor ve karşılığı
tek bir alanın kaybını atlatabilmektir.

Üçüncü satır aynı üç bileşeni ikinci bölgeye taşıyor. Akışlar aynı, hacim aynı, tek fark
fiyatlandırma sınıfının değişmesi: 2.940 GB artık iki birim. Fatura yedi bin üç yüz yirmi.
Dayanıklılığı bir alandan bir bölgeye çıkarmanın bedeli, **aynı baytlar için** iki bin dokuz yüz
kırk birim daha yazmaktır.

İkinci satırın 2.940 GB'ı dört akışa eşit dağılmıyor. Çoğaltma tek başına 1.400 GB, yani sınır
geçen trafiğin **yüzde kırk yedisi**; kalanı kopyadan okuma (620), yedek (600) ve günlük (320)
paylaşıyor. Çoğaltma akışının büyüklüğü de tesadüf değil: toplayıcının veri katmanına yazdığı
1.400 GB ile birebir aynı. Okuma kopyası, yazma akışının bir aynasıdır ve alanlar arası faturanın
yarısı bu yüzden **okuma hacmine değil yazma hacmine** bağlıdır. Okumayı önbelleğe alarak bu kalemi
küçültmenin yolu yoktur.

Buradaki karar iki parçalıdır ve yalnız biri sende. Sınıfların nerede başlayıp bittiğini ve her
sınıfın fiyatını sağlayıcı belirler; hangi bileşenin hangi sınıfın içinde duracağını sen
belirlersin. Model bu ayrımı görünür kılıyor: fiyat listesi bir sabit, yerleşim haritası bir
değişken.

#### Tasarım Kararının Faturaya Yazdığı

İkinci tablo iki alanlı yerleşimi taban alıyor ve beş kararı tek tek uyguluyor.

**İkinci okuma kopyası** faturaya bin dört yüz birim ekliyor. Sebebi doğrudandır: her kopya, veri
katmanından kendisine akan çoğaltma trafiğinin tamamını yeniden yazdırır. Okuma kopyası eklemek
okuma kapasitesi satın almak gibi görünür; faturada ise bir aktarım kalemi olarak da görünür ve o
kalem kopya sayısıyla doğrusal büyür.

**Günlük örnekleme** en ucuz kazançtır: günlükleri beşte bire indirmek 256 GB ve 256 birim
düşürüyor. GB farkı ile ücret farkının eşit olması alanlar arası fiyatın bir olmasındandır; aynı
karar bölgeler arası yerleşimde iki katını kazandırırdı.

**Yedeği uzak bölgeye almak** GB farkı sıfırken faturaya altı yüz birim ekliyor. Tabloda bu iki
sütunun ayrıştığı ilk satırdır ve dersin cümlesi buradadır: **taşınan bayt değişmeden ücret
değişebilir.** Altı yüz birim, yedeğin bölge kaybından da kurtulmasının fiyatıdır.

**Kenar** yüz altmış GB'lık internet çıkışını yeniden fiyatlandırıyor: yüz altmış GB kenar
çıkışından beş birim, ıskalanan yüzde otuz üçlük pay kaynak çıkışından dokuz birim. Toplam fark
eksi yüz altmış beş birim — dört bin üç yüz seksenlik fatura içinde yüzde dörtten az. Kenarın
asıl kazancı bu tabloda görünmez; o kazanç kaynak yükündeydi ve daha önce ölçüldü.

**Sıkıştırma** açık ara en büyük kalemdir: bin dört yüz altmış üç birim, tabanın **üçte biri**.
Altı yüz yetmiş GB'lık düşüşün bin dört yüz altmış üç birim kazandırması, düşen baytların pahalı
sınıflarda olmasındandır. Yüz GB'ı internete çıkmaktan kurtarmak dokuz yüz birim, komşu alana
gitmekten kurtarmak yüz birimdir. Aynı sıkıştırma oranı, uygulandığı akışa göre dokuz kat farklı
sonuç verir.

İki uç satır birlikte okunmalı: sıkıştırma bin dört yüz altmış üç birim indiriyor, ikinci kopya bin
dört yüz birim ekliyor. Biri bir yapılandırma satırı, diğeri bir dayanıklılık kararı — ve faturada
neredeyse birbirini götürüyorlar.

Beş satırın her biri tabana **tek başına** uygulandı ve toplanmaları doğru olmaz: sıkıştırma zaten
örneklenmiş bir günlüğe uygulandığında ikinci kez aynı payı kazandırmaz. Satırların ayrıldığı asıl
nokta geri alınabilirliktir. Günlük örnekleme ve sıkıştırma birer yapılandırma satırıdır; ertesi
gün kapatılabilir ve fatura eski hâline döner. Kopya eklemek ve yedeği başka bölgeye almak ise
veri taşımayı gerektirir; o kararlardan dönmek yeni bir aktarım kalemi yazar. Aynı tabloda hem
bedava geri alınabilen hem de dönüşü paralı olan kararlar var.

#### Girmesi Ucuz, Çıkması Pahalı

Üçüncü tablo aynı bin GB'ı beş hedefe gönderiyor. İnternetten içeri girmek sıfır, alan içinde
dolaşmak sıfır, komşu alana geçmek bin, komşu bölgeye geçmek iki bin, internete çıkmak **dokuz
bin** birim.

Bu tablo tek bir olguyu gösteriyor: veriyi içeri koymak bedava, dışarı almak fiyat listesinin en
üst satırı. Saha fotoğrafları ayda yüzlerce GB olarak sisteme giriyor ve girişleri hiçbir satıra
yazılmıyor; aynı fotoğraflar bir gün dışarı çıkarılmak istendiğinde GB başına dokuz birim
yazılacak. Bakışımsızlık bir hata değil, fiyatlandırmanın kendisidir.

Birinci tablonun akış listesinde girişin hiç yer almaması da bundandır: sahadan gelen fotoğraf ve
sayaç okuması ücretsiz olduğu için modele girmesi faturayı değiştirmez. Sistemi büyüten akış,
faturada hiç görünmeyen akıştır. Aylık gidere bakarak veri büyümesini izlemek bu yüzden çalışmaz;
gider yatay seyrederken biriken hacim, dolayısıyla dördüncü tablonun çıkarma sütunu her ay
yükselir.

Dördüncü tablo bu bakışımsızlığın zamanla ne yaptığını ölçüyor. Ayda net 1.400 GB büyüyen bir
veri katmanı on iki ayda 16.800, yirmi dört ayda 33.600, otuz altı ayda 50.400 GB biriktiriyor.
Bu birikimi bir kerede internete çıkarmak sırasıyla 151.200, 302.400 ve 453.600 birim tutuyor —
yani **34,5, 69,0 ve 103,6 aylık faturaya** denk geliyor.

Son sütun ikinci bir sınırı gösteriyor. Bir Gbit/s hattan 33.600 GB'ı geçirmek 3,1 gün sürüyor,
50.400 GB'ı 4,7 gün. Bu süre boyunca eski sistem çalışmaya, yeni veri birikmeye ve iki taraf da
faturalanmaya devam eder.

#### Çıkış Ücreti ve Çıkış Maliyeti

Bu iki terim birbirine benziyor ve ayrılmaları gerekiyor. **Çıkış ücreti** her ay faturada duran
bir kalemdir; bu modelde dört bin üç yüz seksen birimin bir bölümüdür ve tasarım kararlarıyla
küçültülebilir. **Çıkış maliyeti** ise M23/K01'de kurulan kavramdır: kiralanan bir yerden ayrılmanın
toplam bedeli. Bağ tek cümledir: **çıkış ücreti çıkış maliyetinin fiyat etiketidir ve biriken
veriyle birlikte her ay büyür.**

Bu kursun **geri alınamayan kalemi** burada görünüyor. Yerleşim kararı kâğıt üzerinde geri
alınabilir; bir bileşeni ikinci alandan birinci alana geri taşımak bir yapılandırma değişikliğidir.
Ama bileşenin **verisi** taşınmadan bileşen taşınmaz ve o taşımanın kendisi bir çıkış kalemi yazar:
otuz üç bin altı yüz GB'ı komşu bölgeden geri getirmek altmış yedi bin iki yüz birimdir, yani on
beş aylık fatura. Yanlış yerleşimden çıkmak, yanlış yerleşimde kalmaktan pahalıya gelebilir.

Devredilen karar da bu tablodan okunuyor. Sağlayıcıda dört kalem var: dört sınıfın fiyatı, sınıf
sınırlarının nerede çizildiği, bir akışın hangi sınıfa düştüğü ve girişin ücretsiz kalmaya devam
edip etmeyeceği. Sende beş kalem var: hangi bileşenin nerede duracağı, kaç kopya tutulacağı,
günlüğün ne kadarının gönderileceği, yedeğin nereye yazılacağı ve sıkıştırmanın açık olup
olmayacağı. Dokuz kalemin **beşi sende**, ama tablodaki sayıların büyüklüğünü belirleyen çarpanlar
öteki dörttedir.

#### Özet

- Aynı 6.180 GB üç yerleşimde bin dört yüz kırk, dört bin üç yüz seksen ve yedi bin üç yüz yirmi
  birim yazıyor. Bayt miktarı değil, iki ucun nerede durduğu fiyatlandırıyor.
- İki alana yayılmak 2.940 GB'ı alan içi sınıfından çıkarıp faturayı üç katına taşıyor; aynı üç
  bileşeni ikinci bölgeye almak iki bin dokuz yüz kırk birim daha ekliyor.
- Beş karar tek tek ölçüldüğünde sıkıştırma bin dört yüz altmış üç birim indiriyor, ikinci okuma
  kopyası bin dört yüz birim ekliyor. Yedeği uzak bölgeye almak GB farkı sıfırken altı yüz birim
  yazıyor: taşınan bayt değişmeden ücret değişebilir.
- Aynı bin GB içeri girerken sıfır, komşu alana bin, komşu bölgeye iki bin, internete dokuz bin
  birim tutuyor. Yirmi dört ayda biriken 33.600 GB'ı çıkarmak 302.400 birim, yani altmış dokuz
  aylık fatura ve bir Gbit/s hatta 3,1 gündür.
- Geri alınamayan kalem yerleşimin kendisi değil, altındaki veridir: bir bileşeni geri taşımak
  verisini de taşımak demektir ve o taşıma otuz üç bin altı yüz GB için altmış yedi bin iki yüz
  birim yazar.

#### Sonraki Adım

Bu ders veriyi bir yerden bir yere taşımanın fiyatını çıkardı ve yedek akışını sıradan bir kalem
gibi ele aldı: ayda altı yüz GB, hedefine göre altı yüz ya da bin iki yüz birim.

Yedek, taşındığı için değil **geri alınabildiği için** vardır. Fiyat listesinde görünen o altı yüz
GB'ın karşılığı, bir gün yanlış bir yazma ya da bozulmuş bir tablo bulunduğunda hangi ana
dönülebileceğidir. Yönetilen bir veritabanında bu soru artık elde tutulan bir dosyaya değil,
sağlayıcının anlık görüntü takvimine ve tuttuğu günlüklere bağlıdır.

Sonraki ders bunu ölçer: dönülebilen en eski nokta nerede, dönüş ne kadar sürüyor, dönerken hangi
pencere kaybediliyor ve saklama süresi ile depolama ücreti arasındaki denge nereye oturuyor.

### Yedekleme ve Geri Yükleme

Source: https://academia.sh/tr/kurslar/bulut-depolama/yedekleme-ve-geri-yukleme

Anlık görüntü ile sürekli günlüğün karşılaştırılması: sıklık tarandığında kaybedilen pencerenin saklama ücretiyle birlikte sayılması, yirmi dört saatlik anlık görüntü artı yedi günlük günlüğün saatlik anlık görüntüden hem ucuz hem altmış kat dar çıkması, geri yükleme süresinin dört bileşene ayrılıp elli sekiz dakikalık tabanının bulunması ve yedeklerin hizmetin kendi biçiminde olması nedeniyle taşınabilir kopyanın ayda üç yüz bir birimden başlayan ek maliyeti.

Bir önceki ders verinin nerede durduğunu ve taşınmasının ne tuttuğunu kalem kalem çıkardı. Yedek
akışı orada sıradan bir satırdı: ayda altı yüz GB, hedefine göre altı yüz ya da bin iki yüz birim.

Yedek taşındığı için değil **geri alınabildiği için** vardır: bir gün yanlış bir toplu güncelleme
bulunduğunda hangi ana dönülebileceğidir. Yönetilen bir veri katmanında bu soru artık elde tutulan
bir dosyaya değil, sağlayıcının anlık görüntü takvimine ve tuttuğu günlüklere bağlıdır.

Yedekleme kapsamı ve geri yükleme tatbikatı daha önce ölçüldü; bu ders onu tekrarlamaz, girdi alır.
Burada sayılan üç şey vardır: kaybedilen pencerenin saklama ücretiyle takası, geri yükleme
süresinin bileşenleri ve yedeğin kimin biçiminde durduğu.

- **YV37.** Kurgu bölgesel ölçüm ağının iş emri veri katmanı 220 GB'dir; yirmi dört saatte verinin
  yüzde dördü değişir ve daha kısa aralıklarda değişen pay üstel olarak azalır, çünkü aynı bloklar
  tekrar tekrar yazılır.
- **YV38.** Sürekli günlük günde 46 GB üretir ve altmış saniyede bir arşivlenir. Anlık görüntüler
  otuz gün saklanır. İkisi de kurgudur.
- **YV39.** Fiyat kurgudur, para biriminin adı **birim**dir: yedek saklaması GB başına ayda 0,9
  birim; aktarım GB başına aynı alanda 0, komşu alanda 1, komşu bölgede 2, internete 9 birimdir.
- **YV40.** Geri yükleme hızları kurgudur: yeni örnek açma 210 saniye sabit, yükleme 95 MB/sn,
  günlüğü ileri sarma 12 MB/sn, doğrulama 260 MB/sn. İleri sarma en yavaş adımdır, çünkü kayıtlar
  tek tek uygulanır.
- **YV41.** Mantıksal dışa aktarım 40 MB/sn okur, sıkışma oranı 0,38'dir; dışa aktarılmış kopyadan
  geri yükleme 26 MB/sn'dir, çünkü indeksler yeniden kurulur. Taşınabilir kopya haftada bir alınır,
  ayda dördü saklanır. Hepsi kurgudur.

```js
// yedek/donus.mjs — model: yonetilen veri katmaninda yedekleme ve zaman noktasina donus.
// Yedekleme kapsami ve geri yukleme tatbikati M22/K07'de olculdu, burada tekrarlanmaz.
// Boyutlar, hizlar ve fiyatlar kurgudur; para biriminin adi "birim"dir. Rastgelelik yok.
const VERI_GB = 220, GUN_DEGISIM = 0.04, USTEL = 0.7;   // 24 saatte degisen pay; kisalma usteli
const GUNLUK_GB = 46, FIYAT = 0.9;      // surekli gunluk uretimi GB/gun; birim/GB-ay
const ANLIK_GUN = 30, ARSIV_SN = 60;    // anlik goruntu saklamasi; gunluk arsivleme araligi
const degisenPay = (saat) => GUN_DEGISIM * Math.pow(saat / 24, USTEL);
const anlikGB = (saat) => VERI_GB + (ANLIK_GUN * 24 / saat) * degisenPay(saat) * VERI_GB;
const sutun = (E, sol = 1) => (h) =>
  h.map((d, i) => String(d)[i < sol ? "padEnd" : "padStart"](E[i])).join("");
const y1 = sutun([28, 16, 16, 14, 13, 16]);
console.log(y1(["duzen", "kayip penceresi", "surekli donus", "en eski nokta", "saklanan GB",
  "ucret(birim/ay)"]));
const satir = (ad, saat, gunlukGun) => {
  const gb = anlikGB(saat) + gunlukGun * GUNLUK_GB;
  console.log(y1([ad, gunlukGun ? ARSIV_SN + " sn" : saat + " sa",
    gunlukGun ? gunlukGun + " gun" : "yok", ANLIK_GUN + " gun", gb.toFixed(0),
    (gb * FIYAT).toFixed(0)]));
};
for (const saat of [24, 12, 6, 3, 1]) satir(`anlik goruntu ${saat} sa`, saat, 0);
for (const gun of [1, 7, 35]) satir(`24 sa + gunluk ${gun} gun`, 24, gun);

// --- Geri yukleme suresi bilesenlerine ayrilir -----------------------------------
const ORNEK_SN = 210, YUKLE_MBS = 95, ILERI_MBS = 12, DOGRU_MBS = 260;
const gunlukSaat = (gb) => GUNLUK_GB / 24 * (gb / VERI_GB);   // saatte uretilen gunluk GB
const geriYukle = (gb, mesafe) => {
  const yukle = gb * 1024 / YUKLE_MBS, ileri = gunlukSaat(gb) * mesafe * 1024 / ILERI_MBS;
  const dogru = gb * 1024 / DOGRU_MBS;
  return { yukle, ileri, dogru, toplam: ORNEK_SN + yukle + ileri + dogru };
};
const y2 = sutun([14, 12, 15, 19, 17, 14, 10]);
console.log("\n" + y2(["veri (GB)", "ornek (sn)", "yukleme (sn)", "ileri sarma (sn)",
  "dogrulama (sn)", "toplam (sn)", "saat"]));
for (const gb of [55, 110, 220, 440, 880]) {
  const r = geriYukle(gb, 18);
  console.log(y2([gb, ORNEK_SN, r.yukle.toFixed(0), r.ileri.toFixed(0), r.dogru.toFixed(0),
    r.toplam.toFixed(0), (r.toplam / 3600).toFixed(2)]));
}
const TABAN = ORNEK_SN + VERI_GB * 1024 / YUKLE_MBS + VERI_GB * 1024 / DOGRU_MBS;
const y3 = sutun([22, 17, 19, 15, 17]);
console.log("\n" + y3(["anlik goruntu araligi", "en kotu mesafe", "ileri sarma (sn)",
  "toplam (saat)", "ucret(birim/ay)"]));
for (const saat of [24, 12, 6, 3, 1]) {
  const r = geriYukle(VERI_GB, saat);
  console.log(y3([saat + " sa", saat + " sa", r.ileri.toFixed(0), (r.toplam / 3600).toFixed(2),
    (anlikGB(saat) * FIYAT).toFixed(0)]));
}
console.log(`taban (ornek + yukleme + dogrulama, ileri sarma sifir): ${(TABAN / 3600).toFixed(2)} saat`);

// --- Disa aktarilabilir yedek ---------------------------------------------------
// Hizmetin kendi yedegi kendi bicimindedir. Tasinabilir kopya mantiksal disa aktarimdir.
const SIKISMA = 0.38, HAFTALIK = 4, OKUMA_MBS = 40, YUKLEME_MBS = 26;
const CIKIS = { "ayni alan": 0, "komsu alan": 1, "komsu bolge": 2, "internete": 9 };
const KOPYA_GB = VERI_GB * SIKISMA, HIZMET = (anlikGB(24) + 7 * GUNLUK_GB) * FIYAT;
const y4 = sutun([14, 12, 16, 18, 16, 16]);
console.log("\n" + y4(["hedef", "birim/GB", "aktarim(ay)", "saklama(ay)", "ek toplam",
  "hizmet + ek"]));
for (const [ad, birim] of Object.entries(CIKIS)) {
  const aktarim = KOPYA_GB * HAFTALIK * birim, saklama = KOPYA_GB * HAFTALIK * FIYAT;
  console.log(y4([ad, birim, aktarim.toFixed(0), saklama.toFixed(0),
    (aktarim + saklama).toFixed(0), (HIZMET + aktarim + saklama).toFixed(0)]));
}
console.log(`hizmetin kendi yedegi ${HIZMET.toFixed(0)} birim/ay; tasinabilir kopya ` +
  `${KOPYA_GB.toFixed(1)} GB x ${HAFTALIK}/ay (sikisma ${SIKISMA}).`);
console.log(`disa aktarim ${(VERI_GB * 1024 / OKUMA_MBS / 3600).toFixed(2)} sa (${OKUMA_MBS} MB/sn); ` +
  `ondan geri yukleme ${(VERI_GB * 1024 / YUKLEME_MBS / 3600).toFixed(2)} sa (${YUKLEME_MBS} MB/sn, ` +
  `indeksler yeniden kurulur) — hizmetin kendi donusunun ` +
  `${(VERI_GB * 1024 / YUKLEME_MBS / geriYukle(VERI_GB, 1).toplam).toFixed(1)} kati.`);
```

```
duzen                        kayip penceresi   surekli donus en eski nokta  saklanan GB ucret(birim/ay)
anlik goruntu 24 sa                    24 sa             yok        30 gun          484             436
anlik goruntu 12 sa                    12 sa             yok        30 gun          545             491
anlik goruntu 6 sa                      6 sa             yok        30 gun          620             558
anlik goruntu 3 sa                      3 sa             yok        30 gun          713             641
anlik goruntu 1 sa                      1 sa             yok        30 gun          905             814
24 sa + gunluk 1 gun                   60 sn           1 gun        30 gun          530             477
24 sa + gunluk 7 gun                   60 sn           7 gun        30 gun          806             725
24 sa + gunluk 35 gun                  60 sn          35 gun        30 gun         2094            1885

veri (GB)       ornek (sn)   yukleme (sn)   ileri sarma (sn)   dogrulama (sn)   toplam (sn)      saat
55                     210            593                736              217          1755      0.49
110                    210           1186               1472              433          3301      0.92
220                    210           2371               2944              866          6392      1.78
440                    210           4743               5888             1733         12574      3.49
880                    210           9485              11776             3466         24937      6.93

anlik goruntu araligi    en kotu mesafe   ileri sarma (sn)  toplam (saat)  ucret(birim/ay)
24 sa                             24 sa               3925           2.05              436
12 sa                             12 sa               1963           1.50              491
6 sa                               6 sa                981           1.23              558
3 sa                               3 sa                491           1.09              641
1 sa                               1 sa                164           1.00              814
taban (ornek + yukleme + dogrulama, ileri sarma sifir): 0.96 saat

hedef             birim/GB     aktarim(ay)       saklama(ay)       ek toplam     hizmet + ek
ayni alan                0               0               301             301            1026
komsu alan               1             334               301             635            1361
komsu bolge              2             669               301             970            1695
internete                9            3010               301            3311            4036
hizmetin kendi yedegi 725 birim/ay; tasinabilir kopya 83.6 GB x 4/ay (sikisma 0.38).
disa aktarim 1.56 sa (40 MB/sn); ondan geri yukleme 2.41 sa (26 MB/sn, indeksler yeniden kurulur) — hizmetin kendi donusunun 2.4 kati.
```

#### Pencere mi, Fatura mı

Birinci tablonun ilk beş satırı yalnız anlık görüntüyle çalışıyor. Sıklığı yirmi dört saatten bir
saate çekmek kaybedilen pencereyi yirmi dört kat daraltıyor ve saklamayı 484 GB'den 905 GB'ye
çıkarıyor — fatura 436 birimden 814 birime, yüzde seksen yedi artış.

Saklanan baytın büyümesi ters görünür: daha sık anlık görüntü her seferinde daha az değişen bayt
taşır. Sayı yine de büyüyor, çünkü aynı bloklar aralık kısaldıkça **birden çok anlık görüntüde** yer
alır. Sıklığı artırmanın bedeli istek sayısı değil, tekrardır.

Son üç satır sürekli günlüğü açıyor ve tabloyu yeniden yazıyor. Yirmi dört saatlik anlık görüntüye
yedi günlük sürekli günlük eklendiğinde kaybedilen pencere **altmış saniyeye** iniyor ve
fatura 725 birim oluyor; saatlik anlık görüntü ise 814 birime bir saatlik pencere
veriyor. **Daha ucuz olan seçenek,
pencereyi altmış kat daha çok daraltıyor.** Anlık görüntü sıklığını artırmak, sürekli günlüğün
yerini tutmaz.

Üçüncü ve dördüncü sütun sınırı gösteriyor. Sürekli dönüş penceresi günlüğün saklama süresidir:
yedi günlük düzende son yedi günün **herhangi bir saniyesine** dönülebilir. En eski ayrık nokta ise
otuz gündür — yirmi gün önceki anlık görüntüye dönülür, o günün öğleden sonrasına dönülemez. Fatura
birinciyle ölçeklenir: otuz beş günlük sürekli günlük 2.094 GB ve 1.885 birim, yedi günlüğün iki
buçuk katı.

#### Geri Yüklemenin Tabanı

İkinci tablo süreyi dört bileşene ayırıyor. Yeni örnek açma 210 saniyede sabittir ve payı veri
büyüdükçe düşer: 55 GB'de toplamın yüzde on ikisi, 880 GB'de yüzde biri. Yükleme ve doğrulama
boyutla doğrusal büyür. İleri sarma iki kere büyür — veri büyüdükçe günlük üretimi de artar — ve
220 GB'de 2.944 saniyeyle **en büyük bileşendir**.

Buradan bir tasarım kararı çıkıyor: geri yükleme süresini belirleyen şey veri boyutu kadar, hedef
noktanın **son anlık görüntüden ne kadar uzakta** olduğudur. Yirmi dört saatlik aralıkta en kötü hâl
3.925 saniyelik ileri sarmadır ve toplam 2,05 saat; bir saatlik aralıkta ileri sarma 164 saniyeye
iner, toplam 1,00 saat olur.

Süreyi yarıya indirmenin bedeli birinci tablodadır: 436 birimden 814 birime. Ve iniş burada durur:
örnek açma, yükleme ve doğrulama toplamı **0,96 saattir** ve anlık görüntü aralığı sıfıra
yaklaştırılsa bile bu tabanın altına inilmez. Sürekli günlük kaybedilen pencereyi indirir, geri
yükleme süresini indirmez. **İki sayı iki ayrı kalemden satın alınır.**

#### Devredilen Karar

"Yönetilen hizmette yedekleme otomatiktir" cümlesi dört kalemi gizler: yedeğin **nasıl** alındığı,
hangi biçimde tutulduğu, nerede saklandığı ve nasıl doğrulandığı sağlayıcıdadır. Yukarıdaki 95, 12
ve 260 MB/sn de yapılandırma satırı değil, hizmetin verdiği sayıdır.

Elde kalan üç kalem bu dersin tablolarını doğrudan belirliyor: **saklama süresi** (birinci tablonun
üçüncü ve dördüncü sütunu), **şifreleme anahtarının kimde durduğu** ve **bölge dışına kopyalanıp
kopyalanmayacağı** (son tablonun hedef sütunu). Yedi kalemin dördü devredilmiş, üçü eldedir; elde
kalan üçün ikisi doğrudan bir aktarım kalemi yazar.

Şifreleme anahtarı en sessizidir: sağlayıcının deposundaysa yedek okunabilir ama taşınabilir
değildir, sende ise kaybedilen anahtar yedeği de siler. Bu kalem faturaya hiç yazılmaz.

#### Yedek Kimin Biçiminde

Son tablo bu dersin geri alınamayan kalemini ölçüyor. Hizmetin aldığı yedek kendi biçimindedir:
başka bir yere yüklenemez, başka bir motora verilemez. Taşınabilir kopya ayrıca üretilir —
mantıksal dışa aktarım, 220 GB için 1,56 saat okuma.

Ek maliyet iki kalemdir. Sıkışmış 83,6 GB'lik dört kopya ayda 301 birim saklama tutar; aktarım
kalemi hedefe bağlıdır: aynı alanda sıfır, komşu alanda 334, komşu bölgede 669, internete 3.010
birim. Hizmetin kendi yedeği 725 birimdir; taşınabilirlik eklemek toplamı aynı alanda 1.026 birime
(yüzde 41), komşu bölgede 1.695'e (yüzde 134) çıkarır.

Üçüncü bedel süredir: dışa aktarılmış kopyadan geri yükleme 2,41 saat, hizmetin kendi dönüşünün
**2,4 katı**. Taşınabilir yedek yalnız pahalı değil, yavaş bir yedektir.

Bu kalem M23/K01'in çıkış sütununa bir cümleyle bağlanır: taşınabilir yedek, **çıkış maliyetinin
taksitle ödenmesidir.** Ödenmediğinde tasarruf gerçektir ve bedeli, ayrılma günü tek seferde
çıkar.

#### Özet

- Anlık görüntü sıklığını yirmi dört saatten bir saate çekmek pencereyi yirmi dört kat daraltıp
  faturayı 436'dan 814 birime çıkarıyor: sıcak bloklar birden çok anlık görüntüde tekrarlanıyor.
- Yirmi dört saatlik anlık görüntü artı yedi günlük sürekli günlük pencereyi altmış saniyeye
  indiriyor ve 725 birim tutuyor: saatlik anlık görüntüden hem ucuz hem altmış kat dar.
- Sürekli dönüş penceresi günlüğün saklama süresidir, en eski ayrık nokta anlık görüntününki: yedi
  güne kadar herhangi bir saniyeye, otuz güne kadar yalnız belirli anlara dönülebilir.
- Geri yükleme dört bileşendir ve tabanı 0,96 saattir; ileri sarma 220 GB'de 2.944 saniyeyle en
  büyük bileşendir ve yalnız anlık görüntü aralığıyla kısalır.
- Yedi karar kaleminin dördü devredilmiştir; elde kalan üçün ikisi doğrudan aktarım ücreti yazar.
  Yedek biçimi taşınamaz: taşınabilir kopya ayda 301 ile 3.311 birim ekler, ondan dönüş 2,4 kat
  yavaştır.

#### Kurs Kapanışı

| Ders | Devredilen karar | Geri alınamayan kalem | Çıkış ya da aktarım bedeli |
|---|---|---|---|
| Nesne Depolama | yerleşim, çoğaltma, onarım | anahtar düzeni: 2.481.240 istek | 2,77 GiB → 0,055 / 0,236 birim |
| Depolama Sınıfları | dayanıklılık, dört sınıfta aynı | en az saklama borcu: dönüş 0,338 birim | 276,3 GiB getirme → 23,48 birim |
| Sürümleme ve Yaşam Döngüsü | kuralın işletilmesi | sürümleme: kapatınca 93,6 GiB kalır | 8.931.900 geçiş → 239,75 birim |
| Blok Depolama | diskler, çoğaltma, onarım | boyut küçülmez: yılda 1.056 birim | 110 GiB anlık görüntü → 2,20 / 9,35 |
| Dosya Depolama | üst veri sunucusu, büyüme | erişim protokolü: 54 noktanın 30'u | 640 GiB → 12,80 / 54,40 birim |
| Arşiv Depolama | saklama ortamı, okunabilirlik | 180 günlük borç: 4,5 ay boş ödeme | 297,9 GiB → 25,32 birim |
| Erişim Denetimi | yalnız doğrulama | üretilmiş bağlantı: iptali 3.360.000 kırar | sızan kova: 184,8 GiB → 15,71 birim |
| Yönetilen İlişkisel Veritabanı | 28 kalemin 8'i; 9'u erişilemez | 11 kalemin 4'ü tek yönlü | 220 GB → 3,97 saat, 1.980 birim |
| Okuma Kopyaları | çoğaltma mekaniği | yükseltilen kopya: 220 GB tam kopya | 1.370 GB/ay/kopya → 2.741 birim |
| Yönetilen Anahtar–Değer | bölümleme ve dengeleme | bölüm anahtarı: 8 saat, 518,4 bin birim | 62,2 GB dışa aktarım → 560 birim |
| İkincil Dizinler ve Akışlar | dizin kurulumu ve güncellemesi | kaçırılan pencere: 30 saatte 960K olay | 41,5 GB/ay olay → 83 / 373 birim |
| Yönetilen Önbellek | 17 kalemin 7'si | bekleyen 500 kayıt; parça sayısı sabit | başka alan → 722 birim/ay |
| Veri Aktarımı ve Çıkış | 9 kalemin 4'ü: fiyat listesi | biriken veri: 33.600 GB → 67.200 birim | 6.180 GB: 1.440 → 7.320 birim |
| Yedekleme ve Geri Yükleme | yedeğin alınması ve doğrulaması | yedek biçimi: dışa aktarım +301 birim | 83,6 GB x 4 → 0 / 334 / 669 / 3.010 |

Üçüncü sütun on dört satırda üç aileye ayrılıyor. **Altı satır şema ve biçimdir:** anahtar düzeni,
erişim protokolü, harmanlama seçimi, bölüm anahtarı, parça sayısı ve yedek biçimi — hiçbiri veriyi
yeniden yazmadan değişmez. **Beş satır peşin ödenmiş ya da birikmiş bayttır:** en az saklama borcu,
sürümleme birikimi, arşivin yüz seksen günü, küçültülemeyen birim ve biriken verinin kendisi;
bunlarda karar geri alınır, ücret alınmaz. **Üç satır kapanmış zaman penceresidir:** üretilmiş
imzalı bağlantı, kopanan çoğaltma bağı ve kaçırılan olay penceresi.

Dördüncü sütun on dört satırda aynı yönü gösteriyor: veri girerken hiçbir satırda ücret yazılmadı,
çıkması her satırda ücretlendi ve ücreti nereye gittiğiyle ölçüldü. **Kursun kuralı budur: veri
girerken ucuz, çıkarken pahalıdır — ve kiralanan veri katmanında asıl bağlayıcı kalem fiyat değil,
geri alınamayan şemadır.** Faturayı ödemeyi seçebilirsin; altı satırlık şema ailesini ödeyerek geri
alamazsın.

Üç kurs boyunca makine kiralandı, ağ kiralandı, veri kiralandı. Hepsinin altında hâlâ aynı şey
duruyor: **sürekli çalışan bir sunucu.** Uygulama örnekleri gece üçte de ayakta, ölçüm ağının panosu
hiç istek gelmese de bekliyor ve ikisi de saat başına faturalanıyor. Sonraki kurs — **M23/K04
Sunucusuz ve Kenar Bilişim** — bunu soruyor: sürekli çalışan sunucunun kendisi de kiralanabilir mi,
yoksa yalnız çalıştığı saniyeler mi?

