---
title: 'İçerik Dağıtım Tasarımı'
source: 'https://academia.sh/tr/kurslar/vaka-calismalari/icerik-dagitim-tasarimi'
course: 'Vaka Çalışmaları'
language: tr
updated: '2026-08-17T18:10:55+00:00'
license: 'CC BY-SA 4.0'
---

# İçerik Dağıtım Tasarımı

Statik ve dinamik trafiğin ayrılması: ayrımın kökene inen istek sayısına ve bayta etkisinin kenar önbelleği modeliyle ölçülmesi, eşiğin gerektirdiği isabet oranının hesaptan türetilmesi, istek isabeti ile bayt isabetinin ayrılması ve sürümlü adın bayatlık penceresini sıfırlaması.

Üç vakada da yanıt bir kayıttı, taşınan bayt küçüktü ve pahalı kalem hesap ya da bellekti. Bu
vakada aynı sistem iki farklı trafik taşıyor: birkaç yüz baytlık **kişiye özel yanıtlar** ve her
istekte tekrar gönderilen büyük, değişmeyen **statik varlıklar**. İkisi aynı yoldan geçtiğinde
birinin özelliği ötekini bozar — kişiye özel yanıt önbelleklenemez, ve bütün yol o yüzden
önbelleklenemez sayılır. Bu ders ayrımın kökene inen istek sayısına ve bayta ne yaptığını ölçer.

## Kısıtlar

**İşlevsel gereksinimler.** I1: uygulama kabuğu ve varlıkları (betik, biçem, görsel) istemciye
ulaşır. I2: kişiye özel veri isteği yanıtlanır. I3: yeni sürüm yayımlandığında istemci eskisini
kullanmaz. I4: yayımlanan bir sürüm geri alınabilir.

**Kapsam daraltması.** Görsellerin yeniden boyutlandırılması ve kodlanması, çevrimdışı çalışma ve
kabuğun sunucuda mı istemcide mi kurulacağı dışarıdadır; üçü de taşınan **bayt sayısını** değiştirir,
trafiğin nereden ayrılacağını değil.

| Kod | Eşik | Eşiğin kaynağı |
|---|---|---|
| G1 | kişiye özel yanıtın ortancası 150 ms'yi geçmez | ekranda veri beklenen süre |
| G2 | kökene saniyede 2000'den fazla istek inmez | kökenin kurulu kapasitesi |
| G3 | yeni sürüm 300 saniye içinde bütün istemcilerde etkin olur | hatalı sürümün geri alınabilmesi |
| G4 | kenar düğümü başına önbellek 8 GB'yi geçmez | düğümün yerel depolama payı |

## Varsayımlar

| Kod | Varsayım | Değer | Gerekçe |
|---|---|---|---|
| VI1 | günlük oturum | 4.000.000 | uygulamayı açan kullanıcı sayısı |
| VI2 | oturum başına statik varlık isteği | 25 | betik, biçem ve görsellerin toplamı |
| VI3 | oturum başına kişiye özel istek | 8 | ekranı dolduran veri çağrıları |
| VI4 | tepe çarpanı | 3 | tepe saatteki hızın gün ortalamasına oranı |
| VI5 | statik varlık boyutu | taban 20 KB, üs 2, tavan 4 MB | birkaç büyük paket, çok sayıda küçük varlık; ortalaması 40 KB |
| VI6 | kişiye özel yanıt | 6 KB | ekranı dolduran alanlar |
| VI7 | farklı statik varlık | 500.000 | sürümlü adlar ve görseller dahil |
| VI8 | statik istek dağılımı | Zipf, üs 0,9 | az sayıda varlık her oturumda, çoğu seyrek istenir |

## Kabaca Büyüklük Hesabı

```js
// dagitim/hesap.mjs — VI1–VI8'den cikan hesap ve G2'nin gerektirdigi isabet oraninin turetilmesi
const VI = { oturum: 4e6, statikIstek: 25, dinamikIstek: 8, tepe: 3, varlikBayt: 40_960, yanitBayt: 6144 };
const GUN = 86_400, KOKEN = 2000;                     // KOKEN: G2 esigi, istek/s
const b = (x, n = 2) => x.toFixed(n);
const mbit = (x) => (x * 8) / 1e6;

const statikTepe = (VI.oturum * VI.statikIstek / GUN) * VI.tepe;
const dinamikTepe = (VI.oturum * VI.dinamikIstek / GUN) * VI.tepe;
const statikBayt = statikTepe * VI.varlikBayt, dinamikBayt = dinamikTepe * VI.yanitBayt;
console.log(`tepe statik istek/s = ${b(statikTepe)}   tepe dinamik istek/s = ${b(dinamikTepe)}   toplam = ${b(statikTepe + dinamikTepe)}`);
console.log(`istek orani statik/dinamik = ${b(statikTepe / dinamikTepe)}   bayt orani = ${b(statikBayt / dinamikBayt)}`);
console.log(`tepe cikis: statik ${b(mbit(statikBayt))} Mbit/s, dinamik ${b(mbit(dinamikBayt))} Mbit/s`);
console.log(`G2 esigi ${KOKEN} istek/s; ayrimsiz tasarim ${b(statikTepe + dinamikTepe - KOKEN)} istek/s asiyor`);
console.log(`G2'yi tutmak icin gereken statik istek isabeti = ${b(1 - (KOKEN - dinamikTepe) / statikTepe, 4)}`);
console.log(`dinamik taban tek basina kokene ${b(dinamikTepe)} istek/s = toplamin ${b(dinamikTepe / (statikTepe + dinamikTepe), 4)}'i`);

const iki = (VI.oturum * VI.statikIstek * 2 / GUN) * VI.tepe;
console.log(`VI2 duyarliligi: oturum basina statik istek 25 -> 50 ise tepe statik ${b(iki)} istek/s ve gereken isabet ${b(1 - (KOKEN - dinamikTepe) / iki, 4)}`);
```

```
tepe statik istek/s = 3472.22   tepe dinamik istek/s = 1111.11   toplam = 4583.33
istek orani statik/dinamik = 3.13   bayt orani = 20.83
tepe cikis: statik 1137.78 Mbit/s, dinamik 54.61 Mbit/s
G2 esigi 2000 istek/s; ayrimsiz tasarim 2583.33 istek/s asiyor
G2'yi tutmak icin gereken statik istek isabeti = 0.7440
dinamik taban tek basina kokene 1111.11 istek/s = toplamin 0.2424'i
VI2 duyarliligi: oturum basina statik istek 25 -> 50 ise tepe statik 6944.44 istek/s ve gereken isabet 0.8720
```

Dört sayı tasarımı belirliyor. Birincisi iki oranın **birbirinden farklı** olması: statik trafik
istek olarak dinamiğin 3,13 katı, bayt olarak 20,83 katı. Tek bir "trafik" sayısıyla konuşmak bu
yüzden yanıltıcıdır — hangi kaynağın sıkıştığına göre iki farklı yanıt çıkar. İkincisi ayrımsız
tasarımın G2'yi 2583,33 istek/s ile aşması. Üçüncüsü eşiğin bir isabet oranına dönüşmesi: kökeni
2000 istek/s'nin altında tutmak için statik isabetin en az **0,7440** olması gerekiyor. Dördüncüsü
tabanın kendisi: dinamik akış tek başına kökene 1111,11 istek/s indiriyor ve bu, isabet oranı ne
olursa olsun **inmez**; toplam isteğin 0,2424'ü hiçbir önbellekle azalmaz.

## Ayrımın Ölçülmesi

```js
// dagitim/ayrim.mjs — statik ve dinamik ayriminin kokene inen istege ve bayta etkisi.
// Kenar onbellegi en son kullanilani tutan bir Map'tir (ekleme sirasi = kullanim sirasi).
// Varlik boyutlari ve istek akisi kendi yazilmis uretecle uretilir, tohum sabittir. MODELDIR.
const TOHUM = 20260730, VARLIK = 500_000, ISTEK = 1_800_000, ISINMA = 600_000;
const TABAN = 20_480, US = 2.0, TAVAN = 4 << 20, ZIPF = 0.9;   // VI5 ve VI8
const STATIK_TEPE = 3472.22, DINAMIK_TEPE = 1111.11, DINAMIK_BAYT = 6144;   // hesap blogundan
let s = TOHUM % 2147483647;
const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;

const boyut = new Int32Array(VARLIK);
for (let i = 0; i < VARLIK; i += 1) boyut[i] = Math.min(TAVAN, Math.round(TABAN * Math.pow(rast(), -1 / US)));
const toplamBayt = boyut.reduce((a, b) => a + b, 0);
// Zipf(0,9) tersten ornekleme: sira = (1 + u (N^(1-z) - 1))^(1/(1-z))
const ust = Math.pow(VARLIK, 1 - ZIPF);
const cek = () => Math.min(VARLIK - 1, Math.floor(Math.pow(1 + rast() * (ust - 1), 1 / (1 - ZIPF))) - 1);
const istekler = new Int32Array(ISTEK);
for (let i = 0; i < ISTEK; i += 1) istekler[i] = cek();

function kosum(kapasite) {
  const onbellek = new Map();
  let gezgin = onbellek.keys();
  let dolu = 0, isabet = 0, isabetBayt = 0, olcum = 0, olcumBayt = 0;
  for (let i = 0; i < ISTEK; i += 1) {
    const v = istekler[i], bt = boyut[v], sayiliyor = i >= ISINMA;
    if (sayiliyor) { olcum += 1; olcumBayt += bt; }
    if (onbellek.has(v)) {
      onbellek.delete(v); onbellek.set(v, bt);
      if (sayiliyor) { isabet += 1; isabetBayt += bt; }
      continue;
    }
    if (bt > kapasite) continue;                       // sigmayan varlik onbellege alinmaz
    while (dolu + bt > kapasite) {                     // en eski kullanilan cikarilir
      let n = gezgin.next();
      if (n.done) { gezgin = onbellek.keys(); n = gezgin.next(); }
      const eskiB = onbellek.get(n.value);
      if (eskiB !== undefined) { onbellek.delete(n.value); dolu -= eskiB; }
    }
    onbellek.set(v, bt); dolu += bt;
  }
  return { istekIsabet: isabet / olcum, baytIsabet: isabetBayt / olcumBayt, tutulan: onbellek.size };
}

const b = (x, n = 2) => x.toFixed(n);
const mbit = (baytS) => (baytS * 8) / 1e6;
console.log(`model: ${VARLIK.toLocaleString("tr-TR")} varlik, toplam ${b(toplamBayt / 1e9)} GB, ortalama ` +
  `${b(toplamBayt / VARLIK / 1024)} KB, ${ISTEK.toLocaleString("tr-TR")} istek (ilk ${ISINMA.toLocaleString("tr-TR")} isinma)`);
const ayrimsizIstek = STATIK_TEPE + DINAMIK_TEPE;
const ayrimsizBayt = STATIK_TEPE * (toplamBayt / VARLIK) + DINAMIK_TEPE * DINAMIK_BAYT;
console.log(`\nayrim yok (kisiye ozel belge butun yolu onbelleklenemez kiliyor):`);
console.log(`  kokene inen ${b(ayrimsizIstek)} istek/s ve ${b(mbit(ayrimsizBayt))} Mbit/s`);

console.log(`\n${"kenar onbellegi".padStart(16)}${"tutulan varlik".padStart(16)}${"istek isabeti".padStart(15)}` +
  `${"bayt isabeti".padStart(14)}${"kokene istek/s".padStart(16)}${"kokene Mbit/s".padStart(15)}${"istek kati".padStart(12)}${"bayt kati".padStart(11)}`);
for (const gb of [0.5, 2, 8, 20.5]) {
  const r = kosum(gb * 1e9);
  const kokIstek = STATIK_TEPE * (1 - r.istekIsabet) + DINAMIK_TEPE;
  const kokBayt = STATIK_TEPE * (1 - r.baytIsabet) * (toplamBayt / VARLIK) + DINAMIK_TEPE * DINAMIK_BAYT;
  console.log(`${`${gb} GB`.padStart(16)}${r.tutulan.toLocaleString("tr-TR").padStart(16)}${b(r.istekIsabet, 4).padStart(15)}` +
    `${b(r.baytIsabet, 4).padStart(14)}${b(kokIstek).padStart(16)}${b(mbit(kokBayt)).padStart(15)}${b(ayrimsizIstek / kokIstek).padStart(12)}${b(ayrimsizBayt / kokBayt).padStart(11)}`);
}
```

```
model: 500.000 varlik, toplam 20.44 GB, ortalama 39.93 KB, 1.800.000 istek (ilk 600.000 isinma)

ayrim yok (kisiye ozel belge butun yolu onbelleklenemez kiliyor):
  kokene inen 4583.33 istek/s ve 1190.40 Mbit/s

 kenar onbellegi  tutulan varlik  istek isabeti  bayt isabeti  kokene istek/s  kokene Mbit/s  istek kati  bayt kati
          0.5 GB          12.118         0.4562        0.4390         2999.18         691.80        1.53       1.72
            2 GB          49.111         0.6188        0.6059         2434.84         502.20        1.88       2.37
            8 GB         196.218         0.8272        0.8209         1711.28         258.06        2.68       4.61
         20.5 GB         324.829         0.8773        0.8727         1537.00         199.14        2.98       5.98
```

Model varlıkların ortalamasını 39,93 KB buluyor; hesap bloğu VI5'in kuramsal ortalamasını (40 KB)
kullandığı için iki bloğun bayt sayıları ikinci hanede ayrışıyor. Ölçülen değer tavanla kesilmiş
dağılımın gerçek ortalamasıdır.

**Ayrım G2'yi ancak yeterli önbellekle tutuyor.** G4'ün izin verdiği 8 GB'de istek isabeti 0,8272,
gereken 0,7440'ın üstünde; kökene 1711,28 istek/s iniyor ve eşik tutuyor. 2 GB'de isabet 0,6188'e,
köken 2434,84 istek/s'ye çıkıyor ve **G2 kırılıyor**. Önbellek boyutu bu tasarımda bir kolaylık
değil, eşiği tutan parametredir.

**Ayrım isteği ve baytı aynı oranda azaltmıyor.** 8 GB'de istek 2,68 kat, bayt 4,61 kat azalıyor.
Nedeni hesapta duruyordu: dinamik akış isteklerin 0,2424'ünü tutuyor ama baytların
yirmide birinden azını. Önbellek statik tarafı kaldırdıkça geriye **istek olarak ağır, bayt olarak hafif**
bir taban kalıyor. Bir tasarım "kökeni yüzde yetmiş azalttık" cümlesiyle savunulamaz; hangi
sayının azaldığı söylenmelidir.

**İstek isabeti ile bayt isabeti ayrı sayılardır.** Her satırda bayt isabeti istek isabetinden
düşük (0,8272'ye karşı 0,8209): büyük varlıklar önbellekten daha çabuk çıkıyor, çünkü yerlerine
onlarca küçük varlık sığıyor. Fark küçüktür ama işareti sabittir ve önbellek küçüldükçe büyür
(0,5 GB'de 0,4562'ye karşı 0,4390).

## Tasarım

- **İçerik dağıtım ağı ve kenar önbelleği** (Trafik Katmanı, İçerik Dağıtım Ağları). Parametre
  düğüm başına **8 GB**'dir ve ölçülen istek isabeti 0,8272 ile G2'nin gerektirdiği 0,7440'ın
  üstündedir.
- **Statik içerik barındırma** (Trafik Katmanı, Statik İçerik Barındırma). Parametre **sürümlü
  addır**: içeriği değişen varlığın adı da değişir, bu yüzden ömrü sınırsız verilebilir.
- **API ağ geçidi** (Trafik Katmanı, API Ağ Geçidi). Dinamik yol buradan geçer; parametre, kökene
  inen 1111,11 istek/s'lik tabandır.
- **Ön yüz için backend** (Trafik Katmanı, Ön Yüz İçin Backend). Parametre oturum başına **8**
  kişiye özel istektir; bu sayı düşerse taban da düşer, çünkü taban önbellekle değil **birleştirmeyle**
  azaltılır.
- **İtme tabanlı dağıtım** (Trafik Katmanı, İtme ve Çekme Tabanlı Dağıtım). Yeni sürümün varlıkları
  yayımdan önce kenara itilir; parametre G3'ün **300 saniyelik** penceresidir.
- **Zarif bozulma** (Dayanıklılık ve Güvenilirlik, Zarif Bozulma). Köken düştüğünde kenar elindeki
  varlıkları sunmaya devam eder; parametre, ayakta kalan istek payıdır.

**Bilerek kullanılmayan iki kalıp.** Önden tazeleme (Veri Katmanı Ölçekleme, Önden Tazeleme)
kullanılmıyor: sürümlü adda bir varlık hiç bayatlamaz, tazelenecek bir şey yoktur. Oturum
yapışkanlığı (Trafik Katmanı, Oturum Yapışkanlığı) kullanılmıyor: statik yolda durum yoktur ve
yapışkanlık kenar önbelleğinin paylaşılmasını engelleyerek isabeti düşürürdü.

## Elenen Alternatif: Tek Yol, Kısa Ömürlü Önbellek

Alternatif tasarım iki trafiği ayırmaz; hepsini aynı yoldan geçirir ve statik varlıklara kısa bir
önbellek ömrü verir. Kazandığı şey gerçektir: tek dağıtım hattı, tek yayım adımı, sürüm karışması
olmaz — belge ve varlıklar hep birlikte tazelenir. Yayımın atomik kalması küçük bir kazanç değildir.

Eleme sayısı kökendedir. Kişiye özel belge önbelleklenemediği için tek yolda önbellekleme yalnız
varlıklara verilebilir ve ömrü kısa tutulmak zorundadır, çünkü adları değişmez; bu da isabet
oranını tablonun 0,5 GB satırına yaklaştırır. Ayrımsız tasarımda köken 4583,33 istek/s ve
1190,40 Mbit/s alır — G2'yi 2583,33 istek/s aşar ve hiçbir önbellek boyutu bunu kurtarmaz, çünkü
sorun boyut değil **önbelleklenebilirliktir**. Alternatif hangi kısıt değişirse kazanır: kökenin
kapasitesi 5000 istek/s olsaydı G2 kendiliğinden tutar ve ayrımın tek gerekçesi bant genişliği
kalırdı.

## Arıza Davranışı ve Feda Edilen

**Köken düşerse** statik yol ayakta kalır: kenar isteklerin 0,8272'sini elindeki varlıklarla
karşılamaya devam eder ve sürümlü ad sayesinde sunduğu şey bayat değil, doğru sürümdür. Düşen,
dinamik tabanın tamamıdır — isteklerin 0,2424'ü. Uygulama açılır ama verisi gelmez; bu, zarif
bozulmanın bu vakadaki biçimidir.

**Bir kenar düğümü düşerse** yükü öteki düğümler alır ama önbellekleri o varlıklar için soğuktur.
Soğuk önbelleğin alt sınırını tablonun ilk satırı veriyor: 0,4562 isabetle köken 2999,18 istek/s
alır ve **G2 kırılır**. Devralmanın maliyeti burada kapasite değil, **ısınma süresidir**.

**Feda edilen yayımın atomikliğidir.** İki yol iki hızda ilerlediği için G3'ün 300 saniyelik
penceresinde bir istemci yeni belgeyle eski varlığı ya da tersini görebilir. Sürümlü ad bayatlık
penceresini statik tarafta sıfırladı, ama karşılığında **iki tarafın birbirine göre bayatlığı**
diye yeni bir pencere açtı.

## Özet

- Statik trafik istek olarak dinamiğin 3,13 katı, bayt olarak 20,83 katı; tek bir trafik sayısıyla
  yapılan savunma hangi kaynağın sıkıştığını gizler.
- G2'nin 2000 istek/s eşiği bir isabet oranına dönüşüyor: statik isabet en az 0,7440 olmalı. G4'ün
  izin verdiği 8 GB'de ölçülen isabet 0,8272, 2 GB'de 0,6188 ve eşik kırılıyor.
- Ayrım isteği 2,68, baytı 4,61 kat azaltıyor; fark, dinamik tabanın isteklerin 0,2424'ünü ama
  baytların çok küçük bir payını tutmasından geliyor.
- Bayt isabeti istek isabetinden hep düşük (8 GB'de 0,8209'a karşı 0,8272) ve önbellek küçüldükçe
  fark büyüyor, çünkü büyük varlıklar önce çıkarılıyor.
- Sürümlü ad statik tarafta bayatlık penceresini sıfırlıyor; önden tazeleme bu yüzden gereksiz.
- Feda edilen yayımın atomikliğidir: 300 saniyelik pencerede yeni belge eski varlıkla eşleşebilir.

## Sonraki Adım

Dört vaka aynı ailedendi. Bağlantı kısaltmada okuma yazmanın 100 katıydı, haber akışında 40,
arama önerisinde 12, içerik dağıtımında dinamik istek bile önbellekli statiğin yanında küçük kaldı.
Bu oran her dört tasarımın da belkemiğiydi: iş okuma tarafından yazma tarafına kaydırıldı (kutuya
dağıtma, hazır öneri listesi, önek ağacı), çünkü yazma seyrekti ve kaydırılan işin bedeli ucuzdu.
Hepsinde ikinci bir ortak nokta vardı: **bayatlık ödenebilir bir bedeldi.** Kenarda 300 saniye eski
bir yönlendirme, 60 saniye görünmeyen bir gönderi, 600 saniye önerilmeyen bir sorgu, iki tarafın
birbirine göre kayması — hiçbiri kabul edilemez sayılmadı, çünkü bir okumanın biraz eski olması
düzeltilebilir bir hatadır.

Yazmanın hâkim olduğu bir sistemde bu kararların ikisi de tutmaz. Yazma seyrek değilse okuma
tarafına iş kaydırmak bir kazanç değil bir çarpandır; ve bir kaydın yanlış olması kabul edilemiyorsa
bayatlık artık ödenebilir bir bedel değil, doğrudan bir arızadır. Sonraki konu bu tersine dönmüş
kısıtlarla açılır: yazmanın okumayı geçtiği, sıranın ve teslimin garanti altına alınması gerektiği
ve bir kaydın iki kez işlenmesinin gerçek bir zarar ürettiği sistemler.
