Ders 14 / 16
Yeniden Deneme ve Uyarı
Bir görevin ortasında düşmesinin sunuma ne yaptığının ve yeniden denemenin hattı onarıp onarmadığının ölçülmesi: yedinci dönemin bölümü 120 satırda yarım yazıldığında ham satır 2320'de kalıyor, satır sayısı ile dönem duyarlı bütünlük denetimlerinin ikisi de yeşil kalıyor ama sunum her bölgede yanlışlıyor (−49,09 ile −121,82 arası), atomik yazımda aynı görev hiçbir satır bırakmıyor, tüketim 2200'den 1800'e iniyor, sapma −2,89 ile +12,80 arasında kalıyor ve iki denetim de ateşliyor, üç denemeli yeniden deneme ekleyen yazımda 240 satır çoğaltıp deponun ham sayısını 2640'a çıkarıyor, anahtarlı yazımda çoğalma sıfır oluyor, ve yeniden deneme başarılı olduğunda görev uyarısı susuyor.
İçindekiler
Önceki dersteki bütün koşumların ortak bir yanı vardı: hiçbiri başarısız olmadı. Görev ya koştu ya hiç tetiklenmedi, koştuğunda gördüğü satırların tamamını yazdı. Yarım koşum orada zararsızdı, çünkü yazım anahtarlıydı ve eksik parça bir sonraki koşumda tamamlanıyordu. Bu ders o güvenceyi kaldırır.
Gerçek bir hatta üçüncü bir sonuç vardır: görev koşar, yazmaya başlar ve ortasında düşer. Geriye kalan şey ne boş bir bölümdür ne tam bir bölüm. Bu ders iki soruyu ölçer — yarım yazılan bir bölüm sunuma ne yapıyor, ve düşen görevi yeniden denemek hattı onarıyor mu yoksa satır mı çoğaltıyor. İlk sorunun yanıtı kursun üçüncü iddiasının en güçlü örneğidir.
- OR17. Kaynak, hat ve görev koşumu kurgudur; gerçek bir orkestratör, depo ya da uyarı servisi çağrılmaz. Tohum 20260218, ölçü koşumdan bağımsızdır.
- OR18. Atomik yazım (atomic write), bir görevin ya bütün satırlarını yazması ya hiçbirini bırakmaması demektir. Atomik olmayan yazımda yarım kalan satırlar okunabilir durumda kalır.
- OR19. Görev
2026-07bölümünü yazarken 120. satırda düşüyor. Bu sayı bir yer seçimidir; ölçülen şey sayının kendisi değil, yarım ile hiçin farkıdır. - OR20. Yeniden deneme, geri çekilme, devre kesici ve zarif bozulma yordamı Önbellekleme, Kuyruklar ve Eşzamansız İşleme ile Dayanıklılık ve Güvenilirlik kurslarında ölçüldü ve tekrarlanmaz. Buradaki soru yalnız yeniden denemenin satır çoğaltıp çoğaltmadığıdır.
- OR21.
idempotentkarşılığı yinelemeye dayanıklıdır. Yeniden işlemenin satır çoğaltması Veri Mühendisliğine Giriş kursunda ölçüldü; buradaki ölçüm aynı olguyu görev düzeyinde yapar. - OR22. İki uyarı kaynağı ayrılır: görev uyarısı son denemeden sonra görev hâlâ düşükse gider, veri uyarısı denetimlerden gelir.
- OR23. Taban çizgisi orkestrasyonsuz koşumdur: atomik yazım yok, yeniden deneme yok, uyarı yok.
- OR24. Sayılan birimler: yazılan satır, çoğalan satır, tüketim satırı, sunum sapması, deneme. Ham süre yazılmaz. Sunum üzerinde oran basılmaz, değerin kendisi yazılır.
Görevin Ortasında Düşmek
Bir bölümü yazan görev tek bir işlem değildir; satırları sırayla yazar ve her satırdan sonra düşebilir. Ne bıraktığı yazımın atomik olup olmadığına bağlıdır. Atomik yazımda yarım kalan iş hiç görünmez — görev düşer, bölüm boş kalır, hat o dönemi yokmuş gibi okur. Atomik olmayan yazımda ilk 120 satır orada durur ve hattan geçerken tam satırlardan ayırt edilemez.
Ölçüm iki denetimle yapılır. Satır sayısı denetimi ham satır sayısının beklenenden yüzde beşten fazla sapıp sapmadığına bakar. Dönem duyarlı bütünlük denetimi her bölge ile her dönemin çiftinin veride bulunup bulunmadığına bakar; K01 bu denetimi kusurlu kardeşinden ayırmıştı ve burada doğru olan kullanılır.
# KURGUDUR. Sayac okumalari, bes asamali hat ve gorev kosumu ders icinde # tanimlanir; gercek bir depo, orkestrator ya da uyari servisi 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 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 def okuma_sonucu(kayitlar): v, _ = a1_ayikla(kayitlar) v, _ = a2_tekille(v) v, _ = a3_tuketim(v) oz, _ = a4_ozet(v) sun, _ = a5_sun(oz) return sun, len(v) def bolum_yaz(kayitlar, donem, kesme=None, atomik=False): """kesme: bu satir sayisindan sonra gorev duser. atomik: yarim yazim gorunmez.""" hedef = [k for k in kayitlar if k["donem"] == donem] if kesme is None or kesme >= len(hedef): return hedef, False yarim = hedef[:kesme] return ([], True) if atomik else (yarim, True) def d_satir_sayisi(veri, beklenen=2400, pay=0.05): return abs(len(veri) - beklenen) / beklenen > pay def d_bolum_tamligi_donem(veri): """Her donemde her bolge var mi.""" gor = set((k["bolge"], k["donem"]) for k in veri) return gor != set((b, d) for b in BOLGE for d in DONEM)
Yarım ile Hiç
İkinci blok aynı düşmeyi iki yazım biçiminde koşturur ve dört şeyi yan yana koyar: bölüme yazılan satır, deponun ham satırı, tüketim satırı ve sunumun tabandan sapması.
KAYNAK = kaynak_uret() TABAN_SUN, TABAN_N = okuma_sonucu(KAYNAK) OTEKI = [k for k in KAYNAK if k["donem"] != "2026-07"] print("taban tuketim:", TABAN_N) print("taban sunum:", TABAN_SUN) print(f"{'kurulum':<16}{'yazilan':>8}{'ham':>6}{'tuketim':>9}{'satir':>7}{'butunluk':>10}") for ad, atomik in (("atomik degil", False), ("atomik", True)): yaz, dustu = bolum_yaz(KAYNAK, "2026-07", 120, atomik) depo = OTEKI + yaz sun, n = okuma_sonucu(depo) print(f"{ad:<16}{len(yaz):>8}{len(depo):>6}{n:>9}" f"{str(d_satir_sayisi(depo)):>7}{str(d_bolum_tamligi_donem(depo)):>10}") print(" sapma:", {b: round(sun[b] - TABAN_SUN[b], 2) for b in TABAN_SUN})
taban tuketim: 2200
taban sunum: {'merkez': 1321.45, 'kuzey': 1212.55, 'dogu': 881.36, 'bati': 833.09, 'guney': 1065.55}
kurulum yazilan ham tuketim satir butunluk
atomik degil 120 2320 2040 False False
sapma: {'merkez': -92.63, 'kuzey': -121.82, 'dogu': -49.09, 'bati': -49.27, 'guney': -61.55}
atomik 0 2200 1800 True True
sapma: {'merkez': -2.89, 'kuzey': 6.12, 'dogu': -3.25, 'bati': 12.8, 'guney': 7.01}
Birinci satır kursun üçüncü iddiasının en güçlü örneğidir. Yarım yazılan bölüm sunumu beş
bölgenin hepsinde yanlışlar: sapma −49,09 ile −121,82 arasındadır ve hiçbiri küçük değildir.
Buna karşılık her iki denetim de yeşildir. Ham satır 2320’dir, beklenen 2400’den yüzde 3,33
sapar ve yüzde beşlik bandın içinde kalır. Dönem duyarlı bütünlük denetimi de geçer, çünkü yazılan
ilk 120 satır beş bölgenin hepsinden abone taşır — 2026-07 dönemi her bölge için veride vardır,
yalnızca eksiktir. Sayı makul görünür, sunum yanlıştır ve hiçbir denetim bunu söylemez.
Bandı daraltmak ilk akla gelen çözümdür ve kendi bedelini getirir. Bu yarım yazımı görmek için bandın yüzde 3,33’ün altına inmesi gerekir. Önceki derste dört abone aboneliğini sonlandırmıştı ve bu, dört dönemde 16 satır, yani ham satırın yüzde 0,67’si demektir; yüzde bir düzeyine çekilmiş bir band o değişikliğe de ateşler. Aynı eşik hem yarım yazımı yakalayacak hem abone hareketini görmezden gelecek biçimde ayarlanamaz.
İkinci satır ilk bakışta daha kötü görünür. Atomik yazımda bölüm hiç yazılmaz; depo 2200 satıra
iner ve tüketim 2040 yerine 1800’e düşer, yani yarım yazımdan 240 satır daha az hesaplanır.
Kaybın büyümesinin nedeni önceki dersin çizgesidir: 2026-07 hiç yoksa 2026-08’in tüketimi de
hesaplanamaz, çünkü bir önceki dönemin endeksi yoktur.
Ama sunuma bakıldığında sıralama tersine döner. Daha çok satır kaybeden kurulumun sapması −2,89 ile +12,80 arasındadır; daha az satır kaybedenin sapması −121,82’ye kadar iner. Neden şudur: sunum bölge başına dönem ortalamasıdır. Bölüm hiç yazılmadığında o dönemin hücresi ortalamaya hiç girmez ve kalan on bir dönem doğru ortalamayı verir. Yarım yazıldığında hücre ortalamaya girer, ama içinde iki yüz abonenin yerine yüz yirmisi vardır — düşük bir sayı doğru bir sayı gibi ortalamaya katılır.
Üstelik atomik kurulumda iki denetim de ateşler. Ham satır 2200’dür ve yüzde beşlik bandı aşar;
2026-07 dönemi hiçbir bölge için veride olmadığı için dönem duyarlı bütünlük denetimi de
bozulmayı görür. Buradan çıkan cümle bu dersin omurgasıdır: atomiklik cevabı doğru yapmaz;
başarısızlığı görünür ve sınırlı kılar. Sonuç hâlâ eksiktir, sapma hâlâ sıfır değildir; kazanılan
şey, eksikliğin yakalanabilir olması ve etkisinin bir dönemin ötesine geçmemesidir.
Yeniden Deneme ve Uyarı
Düşen görev yeniden denenir. Üçüncü blok görevi üç kez dener — ilk iki deneme yine 120. satırda
düşer, üçüncüsü tamamlanır — ve yazımın ekleyen ya da anahtarlı olmasının ne değiştirdiğini sayar.
gorev sütunu görev uyarısını taşır: son denemeden sonra görev hâlâ düşükse ateşler.
def gorev_kosumu(kayitlar, donem, kesmeler, atomik=False, anahtarli=False): """Gorev sirayla denenir; kesmeler her denemenin kac satirda dustugunu verir. None = deneme basarili. Yazim ya ekleyendir ya anahtarli.""" depo, yazilan, deneme, dustu = [k for k in kayitlar if k["donem"] != donem], [], 0, False for kesme in kesmeler: deneme += 1 parca, dustu = bolum_yaz(kayitlar, donem, kesme, atomik) if anahtarli: tablo = {(k["abone"], k["donem"]): k for k in yazilan} for k in parca: tablo[(k["abone"], k["donem"])] = k yazilan = list(tablo.values()) else: yazilan = yazilan + parca if not dustu: break return depo + yazilan, deneme, len(yazilan), dustu print(f"{'kurulum':<24}{'deneme':>7}{'yazilan':>8}{'ham':>6}{'tuketim':>9}{'kuzey':>9}" f"{'gorev':>7}{'satir':>7}{'butunluk':>10}") for ad, kesmeler, atomik, anahtarli in ( ("deneme yok , atomik degil", (120,), False, False), ("deneme yok , atomik", (120,), True, False), ("uc deneme , ekleyen", (120, 120, None), False, False), ("uc deneme , anahtarli", (120, 120, None), False, True)): depo, deneme, yaz, dustu = gorev_kosumu(KAYNAK, "2026-07", kesmeler, atomik, anahtarli) sun, n = okuma_sonucu(depo) print(f"{ad:<24}{deneme:>7}{yaz:>8}{len(depo):>6}{n:>9}" f"{round(sun['kuzey'] - TABAN_SUN['kuzey'], 2):>9}{str(dustu):>7}" f"{str(d_satir_sayisi(depo)):>7}{str(d_bolum_tamligi_donem(depo)):>10}") def tekillestirmesiz(kayitlar): """Tekillestirme asamasi olmayan hat.""" v, _ = a1_ayikla(kayitlar) v, _ = a3_tuketim(v) oz, _ = a4_ozet(v) return a5_sun(oz)[0], len(v) depo, _, _, _ = gorev_kosumu(KAYNAK, "2026-07", (120, 120, None)) print() print("uc deneme , ekleyen , tekillestirmesiz hat:", tekillestirmesiz(depo))
kurulum deneme yazilan ham tuketim kuzey gorev satir butunluk
deneme yok , atomik degil 1 120 2320 2040 -121.82 True False False
deneme yok , atomik 1 0 2200 1800 6.12 True True True
uc deneme , ekleyen 3 440 2640 2200 0.0 False True False
uc deneme , anahtarli 3 200 2400 2200 0.0 False False False
uc deneme , ekleyen , tekillestirmesiz hat: ({'merkez': 1470.73, 'kuzey': 1320.73, 'dogu': 1002.64, 'bati': 928.55, 'guney': 1189.73}, 2440)
Üçüncü satır yeniden denemenin bedelini verir. Görev üç kez denendi, iki başarısız deneme bölüme 120’şer satır bıraktı, başarılı deneme 200 satırı daha ekledi: bölümde 200 yerine 440 satır var, yani 240 satır çoğaldı. Sunum yine de doğrudur ve kuzeyin sapması sıfırdır, çünkü tekilleştirme aşaması fazlalığı yutar. Bu davranışın kendisi Veri Mühendisliğine Giriş kursunda ölçülmüştü; buradaki yeni bilgi, çoğalmanın kaynağının bir bozulma değil orkestrasyonun kendi düzeneği olmasıdır. Yeniden deneme hattı onarırken depoyu bozar.
Son satır o düzeneğin sağlamını gösterir. Anahtarlı yazımda her deneme aynı anahtarların üzerine yazar; üç denemeden sonra bölümde 200 satır vardır, çoğalan satır sıfırdır ve ham satır 2400’de kalır. Yeniden denemeyi güvenli kılan şey denemenin kendisi değil, yazımın yinelemeye dayanıklı olmasıdır.
Son çıktı satırı tekilleştirmenin ne kadar yük taşıdığını söyler. Aynı ekleyen depo, tekilleştirme aşaması olmayan bir hattan geçirildiğinde tüketim 2200 yerine 2440 satır olur ve sunum her bölgede yükselir: kuzey 1212,55 yerine 1320,73, merkez 1321,45 yerine 1470,73. Yani üçüncü satırın sıfır sapması hattın doğruluğundan değil, tek bir aşamanın varlığından gelir.
gorev sütunu uyarının nerede sustuğunu gösterir. İlk iki satırda son deneme başarısızdır ve görev
uyarısı gider — ama o uyarı yalnızca “görev düştü” der; birinci satırdaki −121,82’lik sapmadan söz
etmez, çünkü uyarıyı üreten şey verinin kendisi değil görevin durumudur. Son iki satırda yeniden
deneme başarılı olduğu için görev uyarısı hiç gitmez. Üçüncü satırda geriye tek bir işaret
kalır: satır sayısı denetimi 2640 satırı görüp ateşler. Yinelenme gürültülüdür ve onarılabilir;
yarım yazım sessizdir. En tehlikeli kurulum, uyarı veren değil, uyarı vermeyi bırakan
kurulumdur.
Özet
- Yarım yazılan bölüm sunumu beş bölgenin hepsinde yanlışlar (−49,09 ile −121,82 arası) ama ham satır 2320’de kalır: satır sayısı denetimi de dönem duyarlı bütünlük denetimi de yeşildir.
- Atomik yazımda bölüm hiç yazılmaz, tüketim 2040 yerine 1800’e iner, ama sapma −2,89 ile +12,80 arasında kalır ve iki denetim de ateşler. Atomiklik cevabı doğru yapmaz; başarısızlığı görünür ve sınırlı kılar.
- Sıralamanın tersine dönmesinin nedeni sunumun dönem ortalaması olmasıdır: yazılmayan hücre ortalamaya girmez, yarım yazılan hücre düşük bir sayıyla girer.
- Üç denemeli yeniden deneme ekleyen yazımda bölüme 200 yerine 440 satır bırakır, yani 240 satır çoğaltır; anahtarlı yazımda çoğalan satır sıfırdır. Yeniden denemeyi güvenli kılan şey deneme değil, yazımın yinelemeye dayanıklı olmasıdır.
- Çoğalan satırın sunumu bozmaması tekilleştirme aşamasının eseridir: aynı depo o aşama olmadan tüketimi 2440 satıra, kuzeyi 1320,73’e taşır.
- Yeniden deneme başarılı olduğunda görev uyarısı susar; geriye yalnız veri uyarıları kalır ve onlar yarım yazımı hiç görmez. Uyarının sustuğu yer, hattın en az ölçülmüş yeridir.
Sonraki Adım
Üç derste hat çalıştırıldı: sırası çizgeden okundu, tetikleyicisi seçildi, düşen görevi yeniden denendi ve düşmenin sunuma ne yaptığı sayıldı. Bu üç dersin ortak boşluğu şudur — her ölçüm sonradan yapıldı. Yarım yazımı gösteren tablo, koşumun bittiği ve sonucun okunduğu andan sonra kuruldu; hattın kendisi o an hiçbir şey söylemiyordu. Bir hat çalışırken neyin izlendiği, hangi göstergenin bir bozulmayı kaç dönem sonra gösterdiği ve hangi bozulmayı hiçbir göstergenin görmediği hiç sorulmadı. Sonraki ders tazelik, hacim ve şema değişimi göstergelerini K01’in altı bozulma sınıfı üzerinde koşturur ve her birinin yakalama gecikmesini dönem olarak sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.