---
title: 'İçinden Yazma ve Arkadan Yazma'
source: 'https://academia.sh/tr/kurslar/veri-olcekleme/icinden-yazma-ve-arkadan-yazma'
course: 'Veri Katmanı Ölçekleme'
language: tr
updated: '2026-08-17T18:11:01+00:00'
license: 'CC BY-SA 4.0'
---

# İçinden Yazma ve Arkadan Yazma

Yazma yolunun önbelleğe bağlanmasının iki düzeni: içinden yazmanın silmeyi kaldırıp isabeti 0,7285'ten 0,9170'e çıkarması, denormalizasyonun eklediği ikinci yazma hedefinin yolu iki depoya uzatması, arkadan yazmanın toplu aktarımla yazma başına depo yazmasını 2,00'dan 1,20'ye indirmesi ve bunun karşılığında bellekte bekleyen 200 olayın dayanıklılık penceresi olarak ölçülmesi.

Önceki dersin bütün maliyeti tek bir kısıttan doğdu: önbellek yazmanın olduğu yerde değildi, yeni
değeri koyamadı, yalnız eskisini sildi ve her silme bir depo okuması doğurdu. Gönderi durumunu
depoya yazan yol uygulamanın kendi içinden geçtiğinde bu kısıt kalkar. Yazma iki yere birden
gider ve silme hiç yapılmaz; ya da bir adım daha ileri gidilip yazma önce önbelleğe, depoya sonra
toplu olarak gönderilir. Birincisine **içinden yazma** (write-through), ikincisine **arkadan
yazma** (write-behind) denir. Bu ders iki düzeni ölçer.

İki stratejinin mekaniği Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursunda kuruldu ve
ölçüldü; burada yeniden anlatılmaz. Buradaki soru ölçekleme sorusudur: yazma yolu kaç yere
uzuyor, olay başına ne kadar ek iş çıkıyor ve K01'in hangi satırı oynuyor.

## İkinci Yazma Hedefi

Bu konunun kurduğu bir sayı bu derste değişir. Önceki konu okuma yolunu kısaltmak için
denormalizasyon uygulamıştı: bölge başına dağıtımdaki gönderi sayısı, sorgu anında sayılmak
yerine ayrı bir sayaçta tutulur. O karar okuma tarafında kazanç sağladı, ama yazma tarafında
sessiz bir borç bıraktı — her durum olayı artık **iki** yeri günceller: gönderinin takip kaydı ve
gönderinin bulunduğu bölgenin sayacı.

K01'in tablosunda yalnız bir yazma vardı; `tepe yazma istek/s` 97,22, bir olayın bir kayda
yazıldığı varsayımıyla hesaplanmıştı. Yazma hedefi ikiye çıktığında olay hızı değişmez ama depo
yazma hızı değişir. Bu dersin ilk ölçüsü bu yüzden **yazma yolunun uzunluğu**dur: bir olayın
kaç yere dokunduğu.

**B1 (bu dersin varsayımı): taşıyıcı ağı 40 dağıtım bölgesine ayrılmıştır.** Gerekçe: rota
adımları bölge düzeyinde raporlanır ve V5'teki takip yanıtı bölgeyi bir alan olarak taşır.
Duyarlılık son ölçümde yazılıdır: bölge sayısı büyüdükçe toplu aktarımdaki birleşme oranı düşer.
Varsayım K01'in tablosuna eklenmez.

```js
// onbellek/yazma.mjs — yazma yolunun onbellege baglandigi duzenlerin surec ici modeli.
// Onbellek, depo ve olay akisi birer modul; sayaclar aciktir. Toplu pencere ve bolge
// sayisi parametredir. Sureler olculmez, islem sayilir.
export function kutuAc(kapasite) {
  const m = new Map();
  const o = {
    tahliye: 0,
    var: (a) => m.has(a),
    al: (a) => { const d = m.get(a); if (d !== undefined) { m.delete(a); m.set(a, d); } return d; },
    koy: (a, d) => { m.delete(a); m.set(a, d); if (m.size > kapasite) { m.delete(m.keys().next().value); o.tahliye += 1; } },
    sil: (a) => m.delete(a),
  };
  return o;
}

// Her durum olayi iki yeri gunceller: gonderinin takip kaydi ve bolgenin dagitim sayaci.
export function akis({ okuma, oran, calismaKumesi, obek, bolge }) {
  let tohum = 20260730;
  const rast = () => ((tohum = (tohum * 1103515245 + 12345) % 2147483648) / 2147483648);
  let sonraki = 1;
  const etkin = Array.from({ length: calismaKumesi }, () => ({ no: sonraki++, kalan: obek }));
  const cikti = [];
  let borc = 0;
  for (let i = 0; i < okuma; i++) {
    const j = Math.floor(rast() * etkin.length);
    const g = etkin[j];
    cikti.push(["oku", `takip:${g.no}`]);
    if ((g.kalan -= 1) === 0) etkin[j] = { no: sonraki++, kalan: obek };
    for (borc += oran; borc >= 1; borc -= 1) {
      const h = etkin[Math.floor(rast() * etkin.length)].no;
      cikti.push(["yaz", `takip:${h}`, `bolge:${Math.floor(rast() * bolge) + 1}`]);
    }
  }
  return cikti;
}

// takipYazma: "sil" (yaninda okuma) ya da "guncelle" (icinden yazma).
// bolgeYazma: "icinden" ya da "arkadan"; arkadan yazmada toplu pencere `topluPencere` yazmadir.
export function kosum(islemler, { kapasite, takipYazma, bolgeYazma, topluPencere = 200 }) {
  const c = kutuAc(kapasite);
  const bolgeC = new Map();
  const bekleyen = new Map();                 // arkadan yazmada depoya gitmemis bolge sayaci
  const s = { isabet: 0, depoOkuma: 0, depoYazma: 0, dokunus: 0, yazmaDokunus: 0, bayat: 0, bekleyenOlay: 0 };
  const dogru = new Map();
  let sayim = 0, olayBorcu = 0, enCokBekleyenOlay = 0;
  for (const [tur, anahtar, bolge] of islemler) {
    if (!dogru.has(anahtar)) dogru.set(anahtar, 0);
    if (tur === "oku") {
      s.dokunus += 1;
      if (c.var(anahtar)) { s.isabet += 1; if (c.al(anahtar) !== dogru.get(anahtar)) s.bayat += 1; continue; }
      s.depoOkuma += 1; s.dokunus += 2;
      c.koy(anahtar, dogru.get(anahtar));
      continue;
    }
    const deger = dogru.get(anahtar) + 1;
    dogru.set(anahtar, deger);
    s.depoYazma += 1; s.yazmaDokunus += 1;                  // takip kaydi her zaman depoya gider
    s.yazmaDokunus += 1;
    if (takipYazma === "sil") c.sil(anahtar); else c.koy(anahtar, deger);
    bolgeC.set(bolge, (bolgeC.get(bolge) ?? 0) + 1);        // bolge sayaci once onbellekte
    s.yazmaDokunus += 1;
    if (bolgeYazma === "icinden") { s.depoYazma += 1; s.yazmaDokunus += 1; continue; }
    bekleyen.set(bolge, bolgeC.get(bolge));
    olayBorcu += 1;
    enCokBekleyenOlay = Math.max(enCokBekleyenOlay, olayBorcu);
    if ((sayim += 1) % topluPencere === 0) {
      s.depoYazma += bekleyen.size; s.yazmaDokunus += bekleyen.size;
      bekleyen.clear(); olayBorcu = 0;
    }
  }
  s.bekleyenOlay = olayBorcu;
  return { ...s, bekleyenGirdi: bekleyen.size, enCokBekleyenOlay };
}

// M19/K01 kabaca buyukluk hesabinin girdileri (V1-V4, V8).
export const K01 = {
  tepeOkuma: (2_000_000 * 6 / 86_400) * 3,
  tepeYazma: (400_000 * 7 / 86_400) * 3,
};
```

Model süreç içidir. Zaman ölçülmez, işlem sayılır; toplu aktarım bir süreyle değil bir yazma
sayısıyla tetiklenir, çünkü süre bu makineye bağlı olurdu ve sayım değildir.

## Üç Düzen

```js
// onbellek/duzen.mjs — uc yazma duzeninin ayni akista karsilastirilmasi
import { akis, kosum, K01 } from "./yazma.mjs";

const OKUMA = 200_000, KAPASITE = 2000, BOLGE = 40, PENCERE = 200;
const ORAN = K01.tepeYazma / K01.tepeOkuma;
const islemler = akis({ okuma: OKUMA, oran: ORAN, calismaKumesi: 1000, obek: 10, bolge: BOLGE });
const OLAY = islemler.filter(([t]) => t === "yaz").length;

console.log(`okuma ${OKUMA}, durum olayi ${OLAY}, bolge ${BOLGE}, toplu pencere ${PENCERE} yazma`);
console.log(`K01: tepe okuma ${K01.tepeOkuma.toFixed(2)}/s, tepe yazma ${K01.tepeYazma.toFixed(2)}/s\n`);

const DUZEN = [
  ["yaninda okuma + bolge icinden", { takipYazma: "sil", bolgeYazma: "icinden" }],
  ["icinden yazma + bolge icinden", { takipYazma: "guncelle", bolgeYazma: "icinden" }],
  ["icinden yazma + bolge arkadan", { takipYazma: "guncelle", bolgeYazma: "arkadan" }],
];

console.log("duzen                          isabet  depo okuma  depo yazma  yazma/olay  yol uzunlugu  depoya ulasan/s  depoda yazma/okuma  bekleyen olay");
console.log("------------------------------ ------ ----------- ----------- ----------- ------------- ---------------- ------------------- -------------");
for (const [ad, secim] of DUZEN) {
  const r = kosum(islemler, { kapasite: KAPASITE, topluPencere: PENCERE, ...secim });
  const h = r.isabet / OKUMA;
  const arka = K01.tepeOkuma * (1 - h);
  const yazmaS = K01.tepeYazma * (r.depoYazma / OLAY);
  console.log(`${ad.padEnd(30)} ${h.toFixed(4).padStart(6)} ${String(r.depoOkuma).padStart(11)} ` +
    `${String(r.depoYazma).padStart(11)} ${(r.depoYazma / OLAY).toFixed(2).padStart(11)} ` +
    `${(r.yazmaDokunus / OLAY).toFixed(2).padStart(13)} ` +
    `${(arka + yazmaS).toFixed(2).padStart(16)} ${(yazmaS / arka).toFixed(2).padStart(19)} ` +
    `${String(r.enCokBekleyenOlay).padStart(13)}`);
}

const arkadan = kosum(islemler, { kapasite: KAPASITE, topluPencere: PENCERE, takipYazma: "guncelle", bolgeYazma: "arkadan" });
console.log(`\nayni kural takip kaydina da uygulansaydi kayip penceresi:`);
console.log(`  bellekte bekleyen olay = ${arkadan.enCokBekleyenOlay}`);
console.log(`  olay kaydi 220 bayt (V6) -> ${arkadan.enCokBekleyenOlay * 220} bayt yazilmamis`);
console.log(`  tepe yazma ${K01.tepeYazma.toFixed(2)}/s -> ${(arkadan.enCokBekleyenOlay / K01.tepeYazma).toFixed(2)} saniyelik olay akisi`);

console.log("\ntoplu pencerede ayni anahtara dusen yazma sayisi birlesme oranidir:");
console.log("bolge sayisi  depo yazma  yazma/olay  depoya ulasan/s");
for (const bolge of [40, 200, 1000]) {
  const a = akis({ okuma: OKUMA, oran: ORAN, calismaKumesi: 1000, obek: 10, bolge });
  const r = kosum(a, { kapasite: KAPASITE, topluPencere: PENCERE, takipYazma: "guncelle", bolgeYazma: "arkadan" });
  const arka = K01.tepeOkuma * (1 - r.isabet / OKUMA);
  const yazmaS = K01.tepeYazma * (r.depoYazma / OLAY);
  console.log(`${String(bolge).padStart(12)} ${String(r.depoYazma).padStart(11)} ` +
    `${(r.depoYazma / OLAY).toFixed(2).padStart(11)} ${(arka + yazmaS).toFixed(2).padStart(16)}`);
}
```

```
okuma 200000, durum olayi 46666, bolge 40, toplu pencere 200 yazma
K01: tepe okuma 416.67/s, tepe yazma 97.22/s

duzen                          isabet  depo okuma  depo yazma  yazma/olay  yol uzunlugu  depoya ulasan/s  depoda yazma/okuma  bekleyen olay
------------------------------ ------ ----------- ----------- ----------- ------------- ---------------- ------------------- -------------
yaninda okuma + bolge icinden  0.7285       54308       93332        2.00          4.00           307.59                1.72             0
icinden yazma + bolge icinden  0.9170       16592       93332        2.00          4.00           229.01                5.63             0
icinden yazma + bolge arkadan  0.9170       16592       55908        1.20          3.20           151.04                3.37           200

ayni kural takip kaydina da uygulansaydi kayip penceresi:
  bellekte bekleyen olay = 200
  olay kaydi 220 bayt (V6) -> 44000 bayt yazilmamis
  tepe yazma 97.22/s -> 2.06 saniyelik olay akisi

toplu pencerede ayni anahtara dusen yazma sayisi birlesme oranidir:
bolge sayisi  depo yazma  yazma/olay  depoya ulasan/s
          40       55908        1.20           151.04
         200       75983        1.63           192.87
        1000       88862        1.90           219.70
```

Bütün sayılar **hesap** sınıfındadır: belirlenimli bir akış üzerinde sayılmışlardır ve süre
ölçülmemiştir.

## Sayıların Okunması

**İçinden yazma okuma tarafını düzeltiyor.** Silme kalkınca isabet 0,7285'ten 0,9170'e çıktı ve
depo okuması 54.308'den 16.592'ye indi. Dikkat çeken şey, 0,9170'in yazmasız koşumun 0,8976'sının
da **üstünde** olmasıdır: yazma yalnız girdiyi düşürmemekle kalmıyor, onu ısıtıyor da. Bir gönderi
olay ürettiği anda önbelleğe giriyor ve sonraki ilk sorgu ıska almıyor. V9'un 0,90'ı burada ilk
kez aşılıyor ve nedeni bir varsayım değil, yazma yolunun bağlanmasıdır.

**Yazma yolu iki depoya uzamış durumda.** İlk iki düzende olay başına depo yazması 2,00; yol
uzunluğu 4,00 dokunuş (iki depo yazması, bir takip önbelleği güncellemesi, bir bölge sayacı
güncellemesi). Bu, K01'in görmediği bir maliyettir: tablo bir olayın bir kayda yazıldığını
varsayıyordu. İkinci yazma hedefi denormalizasyon kararının bedelidir ve `depoya ulasan istek/s`
satırını yukarı çeker.

**Arkadan yazma yazma tarafını düzeltiyor.** Bölge sayacı önce önbellekte tutulup her 200
yazmada bir toplu aktarıldığında olay başına depo yazması 2,00'dan **1,20**'ye iniyor. Aynı
bölgeye düşen ardışık artışlar tek bir güncellemede birleşiyor. `depoya ulasan istek/s` 229,01'den
**151,04**'e düşüyor ve `depoda yazma/okuma orani` 5,63'ten 3,37'ye iniyor.

Üç düzenin `depoya ulasan istek/s` sütunu birlikte okunmalıdır: 307,59 → 229,01 → 151,04. K01'in
hesabındaki 138,89 bunların hiçbirine eşit değil, çünkü o hesap ne geçersizleştirmeyi ne ikinci
yazma hedefini biliyordu. 151,04, tasarım bittikten sonra o satırın gerçek değeridir.

**Birleşme oranı anahtar uzayına bağlı.** Son tablo kuralı veriyor: toplu pencerede aynı anahtara
kaç yazma düşerse o kadar kazanılır. Kırk bölgede 200 yazmalık pencere olay başına 1,20 depo
yazması bırakıyor; bölge sayısı 1000'e çıktığında pencere içinde neredeyse her yazma ayrı bir
anahtara düşüyor ve oran 1,90'a, `depoya ulasan istek/s` 219,70'e yükseliyor. Arkadan yazma
küçük ve sıcak bir anahtar uzayında kazandırır; geniş bir uzayda yalnız gecikme ekler.

## Hangi Veri Hangi Düzene

Arkadan yazmanın bedeli son üç satırda yazılı. Toplu pencere 200 yazma olduğuna göre bellekte
her an 200 olaya kadar yazılmamış değişiklik bulunur; tepe yazma hızında bu 2,06 saniyelik olay
akışıdır. Süreç o anda dursa bu değişiklikler kaybolur.

Bölge sayacı için kayıp katlanılabilir, çünkü sayaç **türetilmiş** bir değerdir: olay kayıtları
depodadır ve sayaç onlardan yeniden hesaplanabilir. Takip kaydı ve olay kaydının kendisi için
katlanılamaz. V6'ya göre bir olay kaydı 220 bayttır ve V12'ye göre 730 gün saklanır; saklama
süresinin gerekçesi sözleşme uyuşmazlıklarıdır. Kaybolan 200 olay 44.000 bayttır ve o baytların
hiçbir yerde ikinci bir kopyası yoktur.

Kural bu yüzden veriye göre yazılır, katmana göre değil: **kaynağı başka bir yerde duran veri**
arkadan yazmayla yazılabilir, **kendisi kaynak olan veri** yazılamaz. Aynı önbellek katmanında
iki anahtar iki ayrı düzenle çalışır ve bu bir tutarsızlık değil, bir yerleşim kararıdır.

## Özet

- Denormalizasyonun eklediği bölge sayacı yazma yolunu iki depoya uzattı: olay başına depo
  yazması 2,00, yol uzunluğu 4,00 dokunuş. K01'in tablosu bir olayın tek bir kayda yazıldığını
  varsayıyordu.
- İçinden yazma silmeyi kaldırınca isabet 0,7285'ten 0,9170'e çıktı — V9'un 0,90'ının üstüne —
  çünkü yazma girdiyi düşürmek yerine ısıtıyor; depo okuması 54.308'den 16.592'ye indi.
- Arkadan yazma bölge sayacında olay başına depo yazmasını 1,20'ye indirdi; `depoya ulasan
  istek/s` 229,01'den 151,04'e, `depoda yazma/okuma orani` 5,63'ten 3,37'ye indi.
- Birleşme oranı toplu pencerede aynı anahtara düşen yazma sayısıdır: 40 bölgede olay başına
  1,20 depo yazması, 1000 bölgede 1,90 ve `depoya ulasan istek/s` 219,70.
- Arkadan yazmanın kayıp penceresi 200 olay, 44.000 bayt ve 2,06 saniyelik akıştır; kaynağı
  başka yerde duran türetilmiş veride kabul edilir, kendisi kaynak olan olay kaydında edilmez.

## Sonraki Adım

Bu derste yazma, önbellekteki girdiyi ayakta tuttu; ama yazma gelmeyen bir anahtarın girdisi
yalnız bir nedenle düşer: süresi dolar. Süre dolduğu anda o anahtarı soran istek ıska alır,
depoya gider ve bekler — üstelik anahtar sıcaksa aynı anda birçok istek aynı şeyi yapar. Süre
dolmasını beklemek zorunlu değildir: girdi hâlâ geçerliyken, ömrünün sonuna yaklaştığında arka
planda yenilenebilir ve okuyucu hiç ıska görmez. Bu yenileme bedava değildir; yenilenen girdilerin
bir kısmı bir daha hiç okunmaz ve o tazelemeler doğrudan depoya yazılmış boş yüktür. Sonraki ders
eşiği bir parametre olarak oynatır ve iki sayıyı karşı karşıya koyar: kurtarılan ıska ile boşa
giden tazeleme.
