---
title: Çoğaltma
source: 'https://academia.sh/tr/kurslar/veri-olcekleme/cogaltma'
course: 'Veri Katmanı Ölçekleme'
language: tr
updated: '2026-08-17T18:11:02+00:00'
license: 'CC BY-SA 4.0'
---

# Çoğaltma

Aynı verinin birden çok yerde tutulmasının ölçekleme karşılığı: ana–kopya düzeninde okumanın bölünüp yazmanın her düğümde tekrarlanması, kopya eklemenin azalan kazancı, saklanan verinin kopya sayısıyla çarpılması, asenkron gerikliğin bayat takip yanıtına çevrilmesi ve çok ana düzende iki bölgenin aynı gönderiye yazmasının kalıcı ayrışma olarak sayılması.

Önceki ders deponun türünü erişim örüntüsüne bağladı ve okuma yolunu kısalttı. Ortada hâlâ tek bir
kopya var: saniyede 236,11 işlem alan, 718,24 GB taşıyan ve düştüğünde takip sorgusunun da
ücretlendirmenin de yanıtsız kaldığı tek bir düğüm. Yükü birden çok makineye dağıtmanın ilk yolu
veriyi bölmek değil, **çoğaltmaktır** (replication): aynı veriyi birden çok yerde tutmak.

Çoğaltmanın mekaniği İlişkisel Veritabanı Yönetimi kursunda kuruldu — günlük akışı, çoğaltma
gecikmesi, senkron onayın bedeli, çoğunluk kuralı ve devralma orada anlatıldı ve ölçüldü. Burada
mekanik tekrarlanmaz. Bu dersin sorusu bir **ölçekleme kararıdır**: kopya eklemek hangi sayıyı
düşürür, hangi sayıyı düşürmez ve karşılığında ne büyür. Tutarlılık modellerinin tanımları da
Sistem Tasarımına Giriş kursunda kuruldu; burada yalnız kullanılırlar.

## Çoğaltma Neyi Böler

**Ana–kopya** (leader–follower) düzeninde bir düğüm yazmaları kabul eder, ötekiler o düğümün
değişikliklerini uygular ve okumaları karşılar. Bölünen şey okumadır; yazma bölünmez, çünkü her
düğüm **her** yazmayı uygulamak zorundadır. Aşağıdaki hesap bu asimetriyi kopya sayısına göre
açar ve ikinci tabloda asenkron gerikliğin okuma tarafındaki karşılığını verir.

**VD2 — bir gönderinin yolda kalma süresi 3 gün.** Gerekçe: kabul ile teslim arasında geçen süre;
V4'ün yedi durum olayı bu süreye yayılır ve takip sorguları bu süredeki gönderilere gelir.
Duyarlılığı doğrusaldır — süre iki katına çıkarsa yoldaki gönderi sayısı iki katına çıkar ve bayat
yanıt oranı yarıya iner. Bu varsayım K01'in tablosuna eklenmez.

```js
// cogaltma/ana-kopya.mjs — okuma kopyalara bolunurken yazmanin her dugumde tekrarlanmasi,
// ve asenkron gerikligin bayat takip yanitina cevrilmesi. Hepsi aritmetiktir.
const OKUMA = 41.67;        // K01: onbellek arkasi okuma/s
const YAZMA = 194.44;       // 01. ders: ayrilmis duzende depo yazma islem/s
const SAKLAMA = 718.24;     // 01. ders: saklanan veri GB
const OLAY = 97.22;         // K01: tepe yazma istek/s (durum olayi)
const V3 = 400_000;         // K01: gunluk gonderi
const VD2 = 3;              // bu dersin varsayimi: gonderinin yolda kalma suresi (gun)
const YOLDA = V3 * VD2, GUN = 86_400;
const b = (x, n = 2) => x.toFixed(n);

console.log(`${"kopya".padStart(6)}${"kopya basina okuma/s".padStart(21)}${"dugum basina yazma/s".padStart(21)}` +
  `${"dugum yuku".padStart(12)}${"yazma/okuma".padStart(13)}${"kopya kazanci".padStart(15)}${"toplam GB".padStart(11)}`);
let onceki = null;
for (const n of [1, 2, 3, 4, 5]) {
  const okuma = OKUMA / n, yuk = YAZMA + okuma;
  console.log(`${String(n).padStart(6)}${b(okuma).padStart(21)}${b(YAZMA).padStart(21)}` +
    `${b(yuk).padStart(12)}${b(YAZMA / okuma).padStart(13)}` +
    `${(onceki === null ? "-" : b(onceki - yuk)).padStart(15)}${b(SAKLAMA * (1 + n)).padStart(11)}`);
  onceki = yuk;
}
console.log(`tek dugum (01. ders): yuk ${b(YAZMA + OKUMA)} islem/s, yazma/okuma ${b(YAZMA / OKUMA)}, ` +
  `${b(SAKLAMA)} GB`);

console.log(`\nyolda olan gonderi = ${YOLDA.toLocaleString("tr-TR")} (VD2 = ${VD2} gun)`);
console.log(`${"gerilik s".padStart(10)}${"penceredeki degisen gonderi".padStart(28)}` +
  `${"bayat okuma orani".padStart(19)}${"bayat yanit/s".padStart(15)}${"bayat yanit/gun".padStart(17)}`);
for (const L of [0.5, 1, 5, 10]) {
  const degisen = OLAY * L, oran = degisen / YOLDA, bayat = OKUMA * oran;
  console.log(`${b(L, 1).padStart(10)}${b(degisen).padStart(28)}${oran.toExponential(2).padStart(19)}` +
    `${b(bayat, 5).padStart(15)}${b(bayat * GUN, 1).padStart(17)}`);
}
```

```
 kopya kopya basina okuma/s dugum basina yazma/s  dugum yuku  yazma/okuma  kopya kazanci  toplam GB
     1                41.67               194.44      236.11         4.67              -    1436.48
     2                20.84               194.44      215.28         9.33          20.84    2154.72
     3                13.89               194.44      208.33        14.00           6.95    2872.96
     4                10.42               194.44      204.86        18.66           3.47    3591.20
     5                 8.33               194.44      202.77        23.33           2.08    4309.44
tek dugum (01. ders): yuk 236.11 islem/s, yazma/okuma 4.67, 718.24 GB

yolda olan gonderi = 1.200.000 (VD2 = 3 gun)
 gerilik s penceredeki degisen gonderi  bayat okuma orani  bayat yanit/s  bayat yanit/gun
       0.5                       48.61            4.05e-5        0.00169            145.8
       1.0                       97.22            8.10e-5        0.00338            291.7
       5.0                      486.10            4.05e-4        0.01688           1458.4
      10.0                      972.20            8.10e-4        0.03376           2916.8
```

Bu sayılar **hesap** sınıfındadır; girdileri K01'in hesapları, 01. dersin sonuçları ve VD2'dir.

## Sayıların Okunması

**Kopya eklemek yazma yükünü hiç düşürmüyor.** Düğüm başına yazma sütunu beş satırda da 194,44
işlem/s. Bu bir taban değil, tavanla ilgisi olmayan bir zemin: kopya sayısı ne olursa olsun her
düğüm her durum olayını uygular. Bölünen tek sütun okumadır ve o da 41,67'den başlıyor.

**Kazanç hızla tükeniyor.** Birinci kopyadan ikinciye geçiş düğüm yükünü 20,84 işlem/s düşürüyor;
ikinciden üçüncüye 6,95, dördüncüden beşinciye 2,08. Beşinci kopya ilk kopyanın kazandırdığının
onda birini kazandırıyor, çünkü indirilebilen tek pay okumadır ve okuma zaten yükün yüzde 18'i.
Ana–kopya çoğaltması bu yüzden **okuma ağırlıklı bir yükün aracıdır**; K01'in hesabı ise deponun
gördüğü yerde yazma ağırlıklıdır ve 01. dersin belge güncellemesi bu ağırlığı büyütmüştü.

**`depoda yazma/okuma orani` her kopyada büyüyor.** K01'de 2,33'tü, 01. dersten sonra 4,67 oldu, üç
kopyada 14,00'e çıkıyor. Oran bir bozulma göstergesi değil, düzenin tanımıdır: okuma dağıldıkça her
düğümün gördüğü karışım yazmaya kayar. Bir düğümün yazma için ayarlanması gerektiği kararı bu
sütundan okunur.

**`saklanan veri GB` doğrudan çarpılıyor.** Tek düğümde 718,24 GB olan veri, üç kopyayla 2872,96
GB, beş kopyayla 4309,44 GB oluyor. Çoğaltmanın faturası budur ve K01'in saklama satırını en çok
oynatan karardır: 712,48 GB'lik özgün hesap altı katına çıkabiliyor.

**Gerilik ikinci tabloda bir yanıt sayısına dönüşüyor.** Bir saniyelik çoğaltma gecikmesinde
penceredeki değişen gönderi 97,22'dir; yoldaki 1.200.000 gönderiye oranı 8,10e-5 ve depoya ulaşan
41,67 okumanın karşılığı günde 291,7 bayat takip yanıtıdır. Beş saniyede 1458,4. Sayı küçüktür ve
küçüklüğünün nedeni de tablodadır: bayat yanıt oranı, değişim hızının **yoldaki gönderi sayısına**
oranıdır ve yoldaki gönderi sayısı büyüktür. Aynı hesap kısa ömürlü ve çok değişen bir veri
kümesinde başka bir sonuç verirdi. Kopyadan okumanın kabul edilebilirliği bu yüzden bir ilke değil,
bu bölmenin sonucudur.

Kopyanın ikinci karşılığı hizmet erişilebilirliğidir: ana düştüğünde kopyalardan biri yükseltilir.
Devralma ve çoğunluk kuralı İlişkisel Veritabanı Yönetimi kursunda ölçüldü ve burada
tekrarlanmaz.

## Çok Ana ve Çakışma

Yazma tek düğümde kaldığı sürece yazma ölçeklenmez. **Çok ana** (multi-leader) düzeni bu kısıtı
kaldırır: birden çok düğüm yazma kabul eder ve birbirinin değişikliklerini uygular. Karşılığında
tek ananın bedava verdiği bir şey kaybolur — yazmaların tek bir sırası.

Örüntü bunu somutlaştırıyor. P2, taşıyıcıya göre durum olayı yazmasıdır ve bir gönderi aktarma
anında iki bölgenin arasındadır: çıkış bölgesi "aktarmaya verildi", varış bölgesi "aktarmadan
alındı" olayını birkaç saniye arayla yazar.

**VD3 — bir gönderinin iki bölgeden yakın zamanlı yazma alma oranı 0,02.** Gerekçe: yedi olayın
biri aktarma anına düşer ve o anda iki bölge de yazar. Duyarlılığı doğrusaldır; aşağıda 0,04 ile
verilir. K01'in tablosuna eklenmez.

```js
// cogaltma/cok-ana.mjs — iki ananin ayni gonderiye yazmasi. Bu bir MODELDIR: tur soyut bir
// adimdir, yayilma turu bir parametredir, olculmus sure degildir. Sayilan sey, yayilma
// bittikten sonra iki dugumun ayni son durumu gosterip gostermedigidir.
const OLAY = 20_000, GONDERI = 4000, YAYILMA = 3;   // model parametreleri
const VD3 = 0.02;            // varsayim: gonderinin iki bolgeden yakin zamanli yazma alma orani
let s = 20260730 % 2147483647;                       // sabit tohum: her kosumda ayni dizi
const rast = () => (s = (s * 48271) % 2147483647) / 2147483647;

const olaylar = [];
for (let t = 0; t < OLAY; t += 1) {
  const g = Math.floor(rast() * GONDERI), bolge = rast() < 0.5 ? "A" : "B";
  olaylar.push({ t, g, bolge, ad: `o${t}` });
  if (rast() < VD3) {                                // aktarma ani: karsi bolge de yaziyor
    const gecikme = 1 + Math.floor(rast() * YAYILMA);
    olaylar.push({ t: t + gecikme, g, bolge: bolge === "A" ? "B" : "A", ad: `o${t}b` });
  }
}
const gonderiOlay = new Map();
for (const o of olaylar) (gonderiOlay.get(o.g) ?? gonderiOlay.set(o.g, []).get(o.g)).push(o);
let cakisan = 0;
for (const liste of gonderiOlay.values())
  if (liste.some((a) => liste.some((c) => a.bolge !== c.bolge && Math.abs(a.t - c.t) <= YAYILMA))) cakisan += 1;

function kosum(kural) {
  const dugum = { A: new Map(), B: new Map() };
  for (const d of ["A", "B"]) {
    const gelen = olaylar.map((o) => ({ varis: o.bolge === d ? o.t : o.t + YAYILMA, yerel: o.bolge === d ? 1 : 0, o }));
    gelen.sort((x, y) => x.varis - y.varis || y.yerel - x.yerel);   // varis sirasi, yerel once
    for (const { o } of gelen) {
      if (kural === "son-yazan") { dugum[d].set(o.g, o.ad); continue; }
      const k = dugum[d].get(o.g) ?? dugum[d].set(o.g, []).get(o.g);   // ekleme: olay kumesi
      k.push(o);
    }
  }
  const durum = (d, g) => {
    const v = dugum[d].get(g);
    if (kural === "son-yazan") return v;
    return v.slice().sort((x, y) => y.t - x.t || (x.ad < y.ad ? 1 : -1))[0].ad;   // belirlenimli kural
  };
  let ayrisan = 0;
  for (const g of dugum.A.keys()) if (durum("A", g) !== durum("B", g)) ayrisan += 1;
  const kayit = kural === "son-yazan" ? dugum.A.size
    : [...dugum.A.values()].reduce((a, v) => a + v.length, 0);
  return { ayrisan, kayit, dokunulan: dugum.A.size };
}

console.log(`model: ${olaylar.length} olay, ${gonderiOlay.size} gonderi dokunuldu, ` +
  `yayilma ${YAYILMA} tur, VD3 = ${VD3}`);
console.log(`iki bolgeden yakin zamanli yazma alan gonderi = ${cakisan} ` +
  `(dokunulanlarin %${((100 * cakisan) / gonderiOlay.size).toFixed(2)}'si)`);
console.log(`\n${"birlestirme kurali".padEnd(22)}${"ayrisan gonderi".padStart(17)}` +
  `${"cakisanlarin payi".padStart(19)}${"dugumde tutulan kayit".padStart(23)}`);
for (const kural of ["son-yazan", "ekleme"]) {
  const r = kosum(kural);
  console.log(`${kural.padEnd(22)}${String(r.ayrisan).padStart(17)}` +
    `${(r.ayrisan / cakisan).toFixed(4).padStart(19)}${String(r.kayit).padStart(23)}`);
}

const GUNLUK_OLAY = 2_800_000, V4 = 7;                // K01: gunluk durum olayi, olay/gonderi
const oran = kosum("son-yazan").ayrisan / gonderiOlay.size;
console.log(`\nK01 olcegine tasima: gunde ${GUNLUK_OLAY.toLocaleString("tr-TR")} olay ve ` +
  `${(GUNLUK_OLAY / V4).toLocaleString("tr-TR")} gonderi (V4 = ${V4})`);
console.log(`son-yazan kuralinda gunde ${Math.round((GUNLUK_OLAY / V4) * oran).toLocaleString("tr-TR")} ` +
  `gonderi iki bolgede farkli son durum gosterir; VD3 = 0,04 olsaydi yaklasik iki kati`);
```

```
model: 20365 olay, 3971 gonderi dokunuldu, yayilma 3 tur, VD3 = 0.02
iki bolgeden yakin zamanli yazma alan gonderi = 363 (dokunulanlarin %9.14'si)

birlestirme kurali      ayrisan gonderi  cakisanlarin payi  dugumde tutulan kayit
son-yazan                            66             0.1818                   3971
ekleme                                0             0.0000                  20365

K01 olcegine tasima: gunde 2.800.000 olay ve 400.000 gonderi (V4 = 7)
son-yazan kuralinda gunde 6.648 gonderi iki bolgede farkli son durum gosterir; VD3 = 0,04 olsaydi yaklasik iki kati
```

Model üç şey söylüyor. Birincisi, çakışma seyrek değildir: gönderi başına ortalama beş olay
düştüğünde, olay başına yüzde ikilik bir aktarma oranı gönderilerin yüzde 9,14'ünü iki bölgeden
yazılan gönderi hâline getiriyor.

İkincisi, çakışan yazmaların hepsi ayrışma üretmiyor — 363 gönderiden 66'sı, yani beşte biri.
Ayrışma yalnız iki olayın **iki düğüme farklı sırayla ulaştığı** durumda doğuyor. Son yazanın
kazandığı kuralda düğüm A yerel olayını önce uygular, düğüm B karşıdakini; yayılma bittiğinde iki
düğümde iki farklı son durum kalır ve kendiliğinden düzelmez. K01 ölçeğine taşındığında günde 6648
gönderi, iki bölgede farklı son durum gösterir. VD3 iki katına çıkarsa sayı da yaklaşık iki katına
çıkar.

Üçüncüsü ve tasarım açısından önemlisi: **ayrışma verinin değil, saklama biçiminin sonucudur.**
Ekleme kuralında aynı olay dizisi sıfır ayrışma veriyor, çünkü birleştirme işlemi kümelerin
birleşimidir ve birleşim sıradan bağımsızdır. Son durum, kümeden belirlenimli bir kuralla türetilir
ve iki düğüm aynı kümeye sahip olduğu için aynı sonucu bulur. Bedeli son sütundadır: düğümde
tutulan kayıt 3971'den 20.365'e çıkıyor, 5,13 kat. Bu kursun akışında bedel kâğıt üzerindedir,
çünkü K01 zaten bütün olayları saklıyor (V6, V12); asıl değişen, **son durumun üzerine yazılan bir
alan olmaktan çıkıp türetilen bir değer olmasıdır.**

P2'nin biçimi bu yüzden belirleyicidir. Durum olayı ekleme olduğu için çok ana düzenine uyar;
üzerine yazılan bir alan olsaydı uymazdı. Çok ana kararı veriyi değil, **yazmanın biçimini**
sorgular. Yayılma bittikten sonra kopyaların aynı yere gelmesi sonunda tutarlılığın söz verdiği
şeydir ve tanımı Sistem Tasarımına Giriş kursunda verildi; bu ölçüm o sözün ancak birleştirme kuralı
sıradan bağımsız olduğunda tutulduğunu gösteriyor.

## Özet

- Ana–kopya düzeninde okuma bölünür, yazma bölünmez: düğüm başına yazma beş kopyada da 194,44
  işlem/s'de kalıyor, kopya başına okuma 41,67'den 8,33'e iniyor.
- Kopya eklemenin kazancı hızla tükeniyor: düğüm yükü birinci eklemede 20,84 işlem/s düşerken
  dördüncüde 2,08 düşüyor; `depoda yazma/okuma orani` 4,67'den üç kopyada 14,00'e çıkıyor.
- `saklanan veri GB` doğrudan çarpılıyor: 718,24 GB üç kopyayla 2872,96, beş kopyayla 4309,44 GB.
- Gerilik bir yanıt sayısına çevrilir: VD2 = 3 gün ile yoldaki 1.200.000 gönderide bir saniyelik
  gecikme günde 291,7, beş saniyelik gecikme 1458,4 bayat takip yanıtı üretir.
- Çok anada VD3 = 0,02 ile gönderilerin yüzde 9,14'ü iki bölgeden yazılıyor; son yazanın kazandığı
  kuralda bunların beşte biri kalıcı ayrışma veriyor, K01 ölçeğinde günde 6648 gönderi.
- Ayrışma saklama biçiminden doğuyor: ekleme kuralında sıfır ayrışma çıkıyor, bedeli düğümde
  tutulan kaydın 3971'den 20.365'e (5,13 kat) çıkmasıdır.

## Sonraki Adım

Çoğaltma okumayı böldü ama her düğüme aynı 194,44 yazmayı bıraktı ve saklanan veriyi kopya sayısıyla
çarptı. İki sınır da aynı yerden geliyor: bütün veri her yerde duruyor. Oysa deponun taşıdığı veri
tek bir bütün değil — ücretlendirmenin sorduğu sorularla teslimat operasyonunun sorduğu sorular
farklı kayıtlara dokunuyor ve bunu 01. dersin tarama ölçümü göstermişti. Sonraki ders veriyi
anahtara göre değil **işleve göre** bölmeyi ele alır: iki bağlam kendi deposuna ayrıldığında her
deponun aldığı istek ve taşıdığı veri ne oluyor, yazma yolu kaç depoya uzuyor, iki bağlama birden
dokunan sorgu kaç depoya gidiyor ve ortak alanların yinelenmesi saklanan veriye ne ekliyor.
