---
title: 'Yinelemeye Dayanıklılık ve Yeniden İşleme'
source: 'https://academia.sh/tr/kurslar/veri-muhendisligine-giris/etkisizlik-ve-yeniden-isleme'
course: 'Veri Mühendisliğine Giriş'
language: tr
updated: '2026-08-17T18:08:52+00:00'
license: 'CC BY-SA 4.0'
---

# Yinelemeye Dayanıklılık ve Yeniden İşleme

Aynı yükün ikinci kez işlenmesinin satırı çoğalttığının ve sunulan sayının bunu göstermediğinin ölçülmesi: ekleyen depoda bir dönemin geri doldurulması ham satırı 2400'den 2600'e, tam yeniden koşum 4800'e çıkarıyor, üç koşumda 7200'e ulaşıyor, ama tekilleştirme aşaması fazlalığı yuttuğu için sunulan değer üç koşumda da 1212,55 kalıyor; aynı aşama yeniden verilen yük bir düzeltme taşıdığında düzeltmeyi çöpe atıp değeri 794,36'da bırakıyor; tekilleştirme anahtar yerine satırın tamamına baktığında ise aynı yeniden koşumlar değeri 2425,09'a ve 3637,64'e taşıyor.

Önceki ders sözleşmenin bozulmayı aşama 0'da yakaladığını gösterdi, ama yakalamak düzeltmek
değildir: engellenen 200 satır bir yerde bekler, üretici düzeltir ve o dönem hatta **yeniden**
verilir. Buraya kadarki hiçbir ölçümde hat aynı veriyi iki kez görmedi.

İkinci koşum bir istisna değil, hattın en sık yaptığı iştir. Üretici bir yükü düzeltir, bir aşama
hata verip yeniden denenir, geçmiş bir dönem **geri doldurulur**. Bu ders aynı yükü iki kez işleyen
bir hattın satır sayısına ne olduğunu, hangi aşamanın fazlalığı yuttuğunu ve sunulan değerin bunu
gösterip göstermediğini sayar. Yanıt kursun üçüncü iddiasının en temiz örneğidir.

- **VK14.** Kaynak, hat ve depo **kurgudur**; gerçek bir depo, dosya biçimi ya da orkestratör
  çağrılmaz. Tohum **20260218**, ölçü koşumdan bağımsızdır.
- **VK15.** `idempotent` karşılığı bu müfredatta **yinelemeye dayanıklıdır**. Kavramın kendisi
  Kabuk Programlama kursunda, yeniden deneme ile kuyruk yordamı Önbellekleme, Kuyruklar ve
  Eşzamansız İşleme kursunda ölçüldü ve **tekrarlanmaz**. Buradaki soru yalnızca **yeniden
  işlemenin satırı çoğaltıp çoğaltmadığıdır**.
- **VK16.** Yeniden işleme bir kaza değildir: düzeltilmiş yük, yeniden denenen aşama ve geri
  doldurulan dönem sıradan işlerdir.
- **VK17.** Yeniden verilen satırın **değeri aynı kalır**, yalnızca yükleme damgası değişir; tek
  istisna düzeltme taşıyan yüktür. Bu ayrıntı son iki ölçümün tamamını belirler.
- **VK18.** Taban çizgisi **tek koşumdur**: ham satır 2400, çoğalan satır **0**.
- **VK19.** Sayılan birimler: yeniden işlenen satır, çoğalan satır, tekilleştirmenin düşürdüğü
  satır ve sunumdaki fark. **Ham süre yazılmaz**, ölçü **koşum** olarak yazılır.
- **VK20.** Çözünürlük: satır oranının adımı **0,0004**, özet hücresinin **0,0182**, sunum
  değerinin **0,2000**. **Sunum üzerinde oran basılmaz.**

## İki Yazma Biçimi

Bir hattın yinelemeye dayanıklı olup olmadığı tek bir kararla belirlenir: gelen satır depoya
**nasıl** yazılıyor. **Ekleyen** yazma satırı deponun sonuna koyar; aynı satır iki kez geldiğinde
depoda iki kez durur. **Anahtarlayan** yazma satırı bir anahtarın üzerine yazar; aynı anahtar iki
kez geldiğinde depoda bir kez durur. Anahtar burada abone ile dönemin çiftidir, yani hattın zaten
tekillik ölçütü olarak kullandığı şey.

İkinci parça yeniden işlemenin nasıl göründüğüdür. Düzeltilmiş yük geldiğinde satırın **değeri
aynıdır**; değişen tek şey yükleme damgasıdır. Bu, kolay gözden kaçan bir ayrıntıdır ve son ölçümün
tamamı buna dayanır.

```python
# KURGUDUR. Sayac okumalari, bes asamali hat ve depo ders icinde tanimlanir;
# gercek bir depo, dosya bicimi ya da orkestrator cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
DONEM = [f"2026-{a:02d}" for a in range(1, 13)]
ABONE = {}
for i in range(200):
    r = uretec(TOHUM + 37 * i)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "baslangic": 10000 + int(r() * 60000)}


def kaynak_uret():
    kayit = []
    for i, (ab, a) in enumerate(ABONE.items()):
        e = a["baslangic"]
        for d in DONEM:
            r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d))
            e += 4 + int(r() * 46)
            kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"],
                          "endeks": e, "birim": "m3"})
    return kayit


# ---- HAT: bes asama, her biri kendi dusurdugu satiri sayar
def a1_ayikla(kayit):
    ZOR = ("abone", "donem", "bolge", "endeks", "birim")
    tut = [k for k in kayit if all(a in k for a in ZOR)]
    return tut, len(kayit) - len(tut)


def a2_tekille(kayit):
    gor, tut = set(), []
    for k in kayit:
        ad = (k["abone"], k["donem"])
        if ad in gor:
            continue
        gor.add(ad)
        tut.append(k)
    return tut, len(kayit) - len(tut)


def a3_tuketim(kayit):
    tablo = {(k["abone"], k["donem"]): k for k in kayit}
    cikti, dusen = [], 0
    for k in kayit:
        i = DONEM.index(k["donem"])
        if i == 0:
            continue
        onceki = tablo.get((k["abone"], DONEM[i - 1]))
        if onceki is None:
            dusen += 1
            continue
        try:
            f = int(k["endeks"]) - int(onceki["endeks"])
        except (TypeError, ValueError):
            dusen += 1
            continue
        cikti.append(dict(k, m3=f))
    return cikti, dusen


def a4_ozet(kayit):
    top = {}
    for k in kayit:
        ad = (k["bolge"], k["donem"])
        top[ad] = top.get(ad, 0) + k["m3"]
    return top, 0


def a5_sun(ozet):
    bolge = {}
    for (b, d), v in ozet.items():
        bolge.setdefault(b, []).append(v)
    return {b: round(sum(v) / len(v), 2) for b, v in bolge.items()}, 0


ASAMA = [("ayikla", a1_ayikla), ("tekille", a2_tekille), ("tuketim", a3_tuketim),
         ("ozet", a4_ozet), ("sun", a5_sun)]


def hat(kayit, asamalar=None):
    iz, veri = [], kayit
    for ad, f in (asamalar or ASAMA):
        veri, dusen = f(veri)
        iz.append({"asama": ad, "kalan": len(veri), "dusen": dusen})
    return veri, iz


# ---- VERI ALMA ve YENIDEN ISLEME
def al(kayit, yukleme):
    """Veri alma asamasi: her yuke bir damga dusulur."""
    return [dict(k, yukleme=yukleme) for k in kayit]


def yeniden_ver(kayit, donemler, yukleme):
    """Duzeltilen yuk yeniden gonderiliyor ; damga degisir, deger degismez."""
    return [dict(k, yukleme=yukleme) for k in kayit if k["donem"] in donemler]


def depo_ekle(depo, yeni):
    """Yinelemeye DAYANIKSIZ yazma: gelen satir deponun sonuna eklenir."""
    return depo + yeni


def depo_anahtarla(depo, yeni):
    """Yinelemeye DAYANIKLI yazma: (abone , donem) anahtarinin uzerine yazilir."""
    tablo = {(k["abone"], k["donem"]): k for k in depo}
    for k in yeni:
        tablo[(k["abone"], k["donem"])] = k
    return list(tablo.values())


def a2_tekille_tam(kayit):
    """KUSURLU TEKILLESTIRME: anahtara degil satirin tamamina bakar."""
    gor, tut = set(), []
    for k in kayit:
        im = tuple(sorted((a, str(v)) for a, v in k.items()))
        if im in gor:
            continue
        gor.add(im)
        tut.append(k)
    return tut, len(kayit) - len(tut)


KUSURLU = [("ayikla", a1_ayikla), ("tekille", a2_tekille_tam), ("tuketim", a3_tuketim),
           ("ozet", a4_ozet), ("sun", a5_sun)]


def d_tekillik(veri):
    return len(veri) != len(set((k["abone"], k["donem"]) for k in veri))


def d_satir_sayisi(veri, beklenen=2400, pay=0.05):
    return abs(len(veri) - beklenen) / beklenen > pay
```

## Çoğalan Satır ve Değişmeyen Sunum

İkinci blok beş kurulumu aynı kaynağa uygular. `ham` sütunu depodaki satır sayısını, `tekille` o
aşamanın düşürdüğü satırı, `ozet` dördüncü aşamanın hücre sayısını, `kuzey` sunulan beş değerden
birini verir.

```python
KAYNAK_KAYIT = kaynak_uret()
ILK = al(KAYNAK_KAYIT, 1)
TABAN, _ = hat(ILK)


def yaz(ad, depo, asamalar=None):
    sunum, iz = hat(depo, asamalar)
    print(f"{ad:<30}{len(depo):>6}{iz[1]['dusen']:>9}{iz[3]['kalan']:>6}"
          f"{sunum['kuzey']:>11.2f}{'ayni' if sunum == TABAN else 'degisti':>9}")


bir_donem = yeniden_ver(KAYNAK_KAYIT, {"2026-07"}, 2)
tam = yeniden_ver(KAYNAK_KAYIT, set(DONEM), 2)
print("taban sunum:", TABAN)
print("yeniden verilen satir: bir donem", len(bir_donem), " tam kosum", len(tam))
print()
print(f"{'kurulum':<30}{'ham':>6}{'tekille':>9}{'ozet':>6}{'kuzey':>11}{'sunum':>9}")
yaz("tek kosum", ILK)
yaz("ekleyen depo , bir donem", depo_ekle(ILK, bir_donem))
yaz("ekleyen depo , tam kosum", depo_ekle(ILK, tam))
yaz("anahtarlayan depo , tam kosum", depo_anahtarla(ILK, tam))
yaz("kusurlu tekillestirme , tam", depo_ekle(ILK, tam), KUSURLU)
print()
d = depo_ekle(ILK, tam)
print("tekillik denetimi:", d_tekillik(d), " satir sayisi denetimi:", d_satir_sayisi(d))
```

```
taban sunum: {'merkez': 1321.45, 'kuzey': 1212.55, 'dogu': 881.36, 'bati': 833.09, 'guney': 1065.55}
yeniden verilen satir: bir donem 200  tam kosum 2400

kurulum                          ham  tekille  ozet      kuzey    sunum
tek kosum                       2400        0    55    1212.55     ayni
ekleyen depo , bir donem        2600      200    55    1212.55     ayni
ekleyen depo , tam kosum        4800     2400    55    1212.55     ayni
anahtarlayan depo , tam kosum   2400        0    55    1212.55     ayni
kusurlu tekillestirme , tam     4800        0    55    2425.09  degisti

tekillik denetimi: True  satir sayisi denetimi: True
```

İkinci satır dersin başlığıdır: bir dönem geri doldurulduğunda ekleyen depo **2600** satır taşıyor,
yani **200 satır çoğaldı**. Tekilleştirme aşaması tam olarak o 200 satırı düşürüyor ve sunulan değer
**1212,55**'te kalıyor. Üçüncü satır aynı şeyi büyük ölçekte gösterir: tam yeniden koşum deposu
**4800** satıra çıkarıyor, tekilleştirme **2400** satır düşürüyor, sunum yine aynı.

Bu, kursun üçüncü iddiasının en temiz örneğidir. Deponun boyutu iki katına çıkmış, hat aynı işi iki
kez yapmış, ama **sunulan beş değerin hiçbiri kımıldamamıştır**. Çıktıya bakan bir gözlem hattın
yinelemeye dayanıklı olduğunu düşünür. Oysa dayanıklı olan hat değil, **hattın içindeki tek bir
aşamadır**: tekilleştirme fazlalığı yutuyor ve yutarken kimseye haber vermiyor.

Dördüncü satır gerçek dayanıklılığın ne olduğunu gösterir. Anahtarlayan depo ikinci koşumdan sonra
da **2400** satır taşıyor: çoğalan satır **0**, tekilleştirmenin düşürdüğü satır **0**. Fark
depoda değil, hattın ötesindedir; ekleyen depo doğru sayıyı üretirken **iki kat yer** tutar ve
tekilleştirme aşaması olmadan kullanılamaz.

Son iki satır denetimin ne dediğidir. Tekillik denetimi ekleyen depoda ateşliyor, satır sayısı
denetimi de ateşliyor — 4800, beklenen 2400'ün yüzde beşlik bandının çok dışındadır. Yani
bozulmanın yakalama gecikmesi **0**'dır ve bunu yakalayan denetim **sunuma bakan denetim değildir.**

## Yutulan Düzeltme

Buraya kadar yeniden verilen satırın değeri ilkiyle aynıydı, bu yüzden tekilleştirmenin hangisini
tuttuğu önemsizdi. Gerçek geri doldurmalarda durum tersidir: yük **düzeltildiği için** yeniden
gönderilir. Tekilleştirme aşaması ilk gördüğü satırı tutar, yani **eskisini**. Aşağıdaki kurulumda
üretici son dönemi eksik okumuş, sonra düzeltip yeniden göndermiştir. Bozulmanın son döneme
konması bilinçlidir: dizinin ortasındaki bir kayma izleyen dönemde ters işaretle geri gelir ve
ortalamada birbirini götürür.

```python
def eksik_okuma(kayit, donem="2026-12", fark=100):
    """Uretici son donemi eksik okudu ; sonra duzeltip yeniden gonderecek."""
    return [dict(k, endeks=k["endeks"] - fark) if k["donem"] == donem else k
            for k in kayit]


EKSIK = al(eksik_okuma(KAYNAK_KAYIT), 1)
DUZELTME = yeniden_ver(KAYNAK_KAYIT, {"2026-12"}, 2)
print("duzeltilmis satir:", len(DUZELTME))
print(f"{'kurulum':<32}{'ham':>6}{'tekille':>9}{'kuzey':>10}{'taban':>10}")
for ad, depo in (("eksik yuk , duzeltme yok", EKSIK),
                 ("ekleyen depo , duzeltme geldi", depo_ekle(EKSIK, DUZELTME)),
                 ("anahtarlayan depo , duzeltme", depo_anahtarla(EKSIK, DUZELTME))):
    sunum, iz = hat(depo)
    print(f"{ad:<32}{len(depo):>6}{iz[1]['dusen']:>9}{sunum['kuzey']:>10.2f}"
          f"{TABAN['kuzey']:>10.2f}")
```

```
duzeltilmis satir: 200
kurulum                            ham  tekille     kuzey     taban
eksik yuk , duzeltme yok          2400        0    794.36   1212.55
ekleyen depo , duzeltme geldi     2600      200    794.36   1212.55
anahtarlayan depo , duzeltme      2400        0   1212.55   1212.55
```

İkinci satır dersin en pahalı bulgusudur. Düzeltme hatta geldi, 200 satır yeniden işlendi, depo
2600 satıra çıktı, tekilleştirme 200 satır düşürdü — ve sunulan değer **794,36**'da kaldı, yani
düzeltme öncesiyle **birebir aynı**. Düşürülen 200 satır düzeltilmiş olanlardı. Tekilleştirme
aşaması ikinci koşumu yuttu; burada yutmak **kaybetmektir**.

Bu, önceki bölümün tam tersi bir okumadır ve ikisi aynı davranıştan çıkar. Yeniden verilen satır
ilkiyle aynı olduğunda tekilleştirme hattı kurtarıyor; düzeltilmiş olduğunda aynı tekilleştirme
düzeltmeyi çöpe atıyor. Aşama ikisini ayırt edemez, çünkü elinde yalnızca anahtar vardır ve iki
satırın anahtarı aynıdır. Üçüncü satır çözümü gösterir: anahtarlayan depo yeni satırı eskisinin
üzerine yazdığı için sunum **1212,55**'e, yani tabana döner.

Bir hattın yinelemeye dayanıklı sayılması için aynı yükün iki kez işlenmesinin sonucu
değiştirmemesi yetmez; **düzeltilmiş bir yükün ikinci kez işlenmesinin sonucu düzeltmesi** de
gerekir. Ekleyen depo birinci koşulu sağlıyor, ikincisini sağlamıyor.

## Anahtar Yanlış Seçildiğinde

Tablonun son satırı hattın en kırılgan varsayımını açar. Tekilleştirme aşaması `(abone, donem)`
anahtarına bakar. Aynı aşama **satırın tamamına** bakacak biçimde yazılsaydı, yeniden verilen satır
yükleme damgası yüzünden farklı görünür ve elenmezdi. Bu, uydurma bir kusur değildir: bir yükün
tümüyle aynı olup olmadığını sormak sezgisel olarak daha güvenli görünür ve tam da bu yüzden yazılır.

```python
ekleyen, anahtarlayan = ILK, ILK
print(f"{'kosum':<6}{'ekleyen ham':>12}{'kuzey':>9}{'kusurlu kuzey':>15}"
      f"{'anahtarlayan ham':>18}{'kuzey':>9}")
for kosum in range(1, 4):
    if kosum > 1:
        yeni = yeniden_ver(KAYNAK_KAYIT, set(DONEM), kosum)
        ekleyen = depo_ekle(ekleyen, yeni)
        anahtarlayan = depo_anahtarla(anahtarlayan, yeni)
    sun_ekle, _ = hat(ekleyen)
    sun_kusur, _ = hat(ekleyen, KUSURLU)
    sun_anahtar, _ = hat(anahtarlayan)
    print(f"{kosum:<6}{len(ekleyen):>12}{sun_ekle['kuzey']:>9.2f}"
          f"{sun_kusur['kuzey']:>15.2f}{len(anahtarlayan):>18}"
          f"{sun_anahtar['kuzey']:>9.2f}")
print()
oz, _ = a4_ozet(a3_tuketim(a2_tekille_tam(a1_ayikla(ekleyen)[0])[0])[0])
ozt, _ = a4_ozet(a3_tuketim(a2_tekille(a1_ayikla(ILK)[0])[0])[0])
print("ozet ('kuzey', '2026-07') taban:", ozt[("kuzey", "2026-07")],
      " kusurlu tekillestirme:", oz[("kuzey", "2026-07")])
print("tekillestirmenin tuttugu anahtar:", len(set((k["abone"], k["donem"]) for k in ILK)))
```

```
kosum  ekleyen ham    kuzey  kusurlu kuzey  anahtarlayan ham    kuzey
1             2400  1212.55        1212.55              2400  1212.55
2             4800  1212.55        2425.09              2400  1212.55
3             7200  1212.55        3637.64              2400  1212.55

ozet ('kuzey', '2026-07') taban: 1251  kusurlu tekillestirme: 3753
tekillestirmenin tuttugu anahtar: 2400
```

Üç koşumluk tablo iki cümleyi yan yana koyar. Doğru anahtarla çalışan hatta ham depo 2400'den
4800'e, 7200'e çıkıyor ve sunulan değer **üç koşumda da 1212,55**. Kusurlu anahtarla çalışan hatta
aynı ham depo, aynı yeniden koşumlar, ama sunulan değer **1212,55 → 2425,09 → 3637,64** diye
büyüyor: koşum sayısıyla doğru orantılı. Özet katmanında aynı şey görünür, kuzeyin `2026-07` hücresi
tabanda 1251 iken üçüncü koşumdan sonra **3753**'tür.

İki hat arasındaki tek fark bir aşamanın anahtar seçimidir. Hiçbir bozulma sınıfı yok, hiçbir alan
adı değişmedi, hiçbir tür kaymadı; üretici tarafında olan tek şey aynı doğru yükün ikinci kez
gönderilmesidir. Bu, kursun ikinci iddiasının bu derse düşen biçimidir: **hattın kendi aşaması,
kusurlu bir anahtarla, hiçbir kaynak bozulması olmadan sunulan sayıyı üç katına çıkarabilir.**

Anahtarlayan deponun sütunu bedelin nerede durduğunu söyler. Yinelemeye dayanıklılık ücretsiz
değildir: yazma anında **2400 girişlik** bir anahtar tablosu tutulur ve her satır yazılmadan önce
aranır. Tekilleştirme aşaması da aynı büyüklükte bir küme taşır. Bunun karşılığında depo koşum
sayısından bağımsız olarak 2400 satırda kalır ve hattın doğruluğu tek bir aşamanın anahtarına
bağımlı olmaktan çıkar.

## Özet

- Yeniden işleme sıradan bir iştir; ekleyen depoda bir dönemin geri doldurulması ham satırı
  2400'den 2600'e, tam yeniden koşum 4800'e, üçüncü koşum 7200'e çıkarır.
- Sunulan beş değer bu büyümenin hiçbirini göstermez: kuzey üç koşumda da 1212,55'tir, çünkü
  tekilleştirme aşaması fazlalığı yutar ve yutarken haber vermez.
- Yinelemeye dayanıklı olan hat değil, hattın içindeki tek bir aşamadır; anahtarlayan yazma
  kullanıldığında çoğalan satır 0'a iner ve depo koşum sayısından bağımsız kalır.
- Yeniden verilen yük bir **düzeltme** taşıdığında aynı tekilleştirme onu çöpe atar: sunulan değer
  794,36'da kalır, oysa anahtarlayan depo aynı düzeltmeyle 1212,55'e döner. Dayanıklılık, ikinci
  koşumun sonucu değiştirmemesi değil, **düzeltmesi gerektiğinde düzeltmesidir**.
- Tekilleştirme `(abone, donem)` yerine satırın tamamına baktığında aynı yeniden koşumlar sunulan
  değeri 1212,55'ten 2425,09'a, sonra 3637,64'e taşır; özet hücresi 1251'den 3753'e çıkar.
- Çoğalmayı yakalayan denetimler tekillik ile satır sayısıdır ve ikisi de aşama 0'da ateşler;
  sunuma bakan hiçbir denetim bunu göremez.

## Sonraki Adım

Üç derste denetim hep aynı yere baktı: **satırın kendisine**. Alanları var mı, türü doğru mu,
anahtarı benzersiz mi, değeri önceki dönemlerin düzeninde mi. Bu sorular bir sunum değeri
bozulduğunda yanıt vermez, çünkü hiçbiri satırın **nereden geldiğini** söylemez. Kusurlu
tekilleştirmeyle üretilen 3753 rakamına bakan biri, o hücreye hangi yüklerin katkı verdiğini ve
zincirin hangi halkasında hata olduğunu bulmak için hattın tamamını baştan okumak zorundadır.
Sonraki ders bu aramayı sayar: bozulmuş bir sunum değerinden kaynağa gitmek için kaç aşamaya ve kaç
satıra bakmak gerekiyor, kayıt tutulduğunda ve tutulmadığında.
