Ders 10 / 11
Akış Motorlarında Durum
Sürekli akan bir işte düşen bir işçinin ne kadarını geri istediğinin ve denetim noktası sıklığını artırmanın bu sayıyı gerçekten indirip indirmediğinin sayılması: 2200 satırlık akan işte 2026-09 döneminde düşme olduğunda denetim noktası yokken 1600 satır yeniden hesaplanır, aralık 6'da 400, aralık 3'te yine 400, aralık 1'de 0. Aralığı yarıya indirmek kurtarmayı yarıya indirmez, çünkü düşmeden önceki son nokta yerinden oynamamıştır; aralık 4 aynı düşmede 0 verir. On bir düşme noktasının tamamı tarandığında aralık 6 ortalama 545,5, aralık 3 ise 218,2 satır yeniden hesaplatır, ama kesin bedel 400'den 800'e çıkar; en kötü duruma göre aralık 4 ile 3 beraberdir, ortalamaya göre aralık 4 kazanır. Düşme olasılığı 1'den 0,5'e indiğinde en iyi seçim denetim noktası tutmamaya döner. Bölümlü durumda düşen tek işçi 1600 yerine 408, 400 yerine 102 satır geri ister ve tam bir kez tam olarak o satır kadar durum tutmayı gerektirir.
İçindekiler
Bir önceki ders düşen bir işçiyi yalnız önbelleğin yitmesi olarak saydı: kaybolan şey saklanmış bir ara sonuçtu, yeniden hesaplanabiliyordu ve iki sorgunun toplamı 3300’den 5500’e çıkıyordu. Toplu bir işte doğru olan budur, çünkü girdi hâlâ yerinde durur.
Sürekli akan bir işte durum başkadır. İşçinin belleğinde duran şey bir ara sonuç değil, hesabın o ana kadarki durumudur: hangi abonenin hangi dönemine kadar gelindiği, hangi kısmi toplamın nerede kaldığı. Düşme olduğunda bu durum kaybolur ve iş bir yerden yeniden başlamak zorundadır. Bu ders tek bir soruyu sayar: düşen işçi geriye ne kadarını istiyor, ve o sayıyı küçültmek için ödenen bedel gerçekten karşılığını veriyor mu.
- DB47. Kaynak, hat ve dağıtık kurulum kurgudur ve ders içinde üretilir. Hiçbir akış motoru, küme yöneticisi ya da durum deposu çağrılmaz. Tohum 20260218.
- DB48. Denetim noktası, yinelemeye dayanıklılık ve tam bir kez semantiğinin yordamı Veri Mühendisliği ve MLOps müfredatındaki Veri Hatları ve Orkestrasyon kursunun Veri Alma konusunda ve Backend Geliştirme müfredatındaki Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursunda ölçüldü; tekrarlanmaz. Oradaki sayılar burada girdidir: en az bir kez 2200 satır ve 19 yinelenme, en çok bir kez 2162 satır. Buradaki tek ölçü kurtarmanın bedelidir.
- DB49. Akış işi dönem dönem ilerler ve düşme
2026-09döneminde olur; iş düşmeden önceki son denetim noktasından sürer. Koddakontrolalanı denetim noktası sayısını taşır. - DB50. Bir denetim noktası o anki durumu kalıcı kılar; durum abone başına bir giriş, yani
DURUM_SATIRI = 200satırdır. Bu bir seçimdir ve aşağıdaki bütün toplamlar ona duyarlıdır. - DB51. Ortalama alınırken düşmenin on bir dönemin herhangi birinde eşit olasılıkla olduğu varsayılır; bu da bir seçimdir. Satır bu modelin kendi birimidir, ham milisaniye değildir.
- DB52. Taban çizgisi denetim noktası tutmayan kurulumdur: nokta 0, kesin bedel 0, düşme sonrası baştan başlanır.
Kurtarmanın Bedeli
İlk blok kaynağı, hattın tüketime kadarki üç aşamasını ve kurtarma ölçüsünü kurar. kurtarma
düşme dönemine kadarki satırların kaçının yeniden hesaplanacağını sayar.
# KURGUDUR. Olcum aginin sayac okumalari , hattin ilk uc asamasi ve akan is ders # icinde uretilir; hicbir akis motoru , kume yoneticisi ya da durum deposu # cagrilmaz. Tohum 20260218. 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 cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"]))) return cikti, dusen ISCI, AG_BEDELI, GOREV_SABIT, DURUM_SATIRI = 4, 3, 50, 200 def satirlar(): v, _ = a1_ayikla(kaynak_uret()) v, _ = a2_tekille(v) v, _ = a3_tuketim(v) return v def kurtarma(kayitlar, kontrol_araligi, dusen_donem="2026-09", isci=ISCI): """Denetim noktasi yoksa bastan; varsa son noktadan.""" i = DONEM.index(dusen_donem) if kontrol_araligi is None: yeniden = sum(1 for k in kayitlar if DONEM.index(k["donem"]) <= i) return {"kontrol": 0, "yeniden": yeniden} son = (i // kontrol_araligi) * kontrol_araligi yeniden = sum(1 for k in kayitlar if son < DONEM.index(k["donem"]) <= i) return {"kontrol": len(DONEM) // kontrol_araligi, "yeniden": yeniden} AKAN = satirlar() print(f"akan is {len(AKAN)} satir , dusme 2026-09") print("aralik denetim noktasi yeniden hesaplanan satir") for a in (None, 6, 3, 1): s = kurtarma(AKAN, a) print(f"{str(a):>6} {s['kontrol']:>15} {s['yeniden']:>24}")
akan is 2200 satir , dusme 2026-09
aralik denetim noktasi yeniden hesaplanan satir
None 0 1600
6 2 400
3 4 400
1 12 0
Dört satırın üçü beklenendir. Denetim noktası tutmayan iş düşme dönemine kadarki 1600 satırın tamamını yeniden hesaplar; aralık 6 bunu 400’e indirir; aralık 1 her dönemi kaydettiği için sıfıra indirir. Üçüncü satır beklenen değildir: aralık 6’dan aralık 3’e inmek yeniden hesaplanan satırı hiç değiştirmez. Aralık ikiye bölünmüş, tutulan nokta sayısı 2’den 4’e çıkmış ve kurtarma 400’de kalmıştır. Ödenen iki katına çıkmış, alınan aynı kalmıştır.
Aralığı Yarıya İndirmek
Nedeni tek bir hesapta durur. Düşme 2026-09, yani on ikinci dizinin sekizinci sırasındadır. Aralık
6’da düşmeden önceki son nokta altıncı dönemdir; aralık 3’te de altıncı dönemdir, çünkü sekizin üçe
bölümünden kalan iki, son noktayı geriye altıya taşır. Aralık yarıya indi ama düşmeden önceki son
nokta yerinden oynamadı. İkinci blok bu davranışı on bir düşme noktasının tamamında tarar.
# Bu blok ilk bloktaki AKAN , DONEM , DURUM_SATIRI ve kurtarma tanimlarini surdurur. ARALIK = (None, 6, 4, 3, 2, 1) print("dusme " + " ".join(f"{str(a):>5}" for a in ARALIK)) for d in DONEM[1:]: print(f"{d} " + " ".join(f"{kurtarma(AKAN, a, d)['yeniden']:>5}" for a in ARALIK)) print("\naralik nokta kesin bedel en kotu en kotu toplam ortalama ortalama toplam") for a in ARALIK: y = [kurtarma(AKAN, a, d)["yeniden"] for d in DONEM[1:]] k = kurtarma(AKAN, a)["kontrol"] * DURUM_SATIRI o = sum(y) / len(y) print(f"{str(a):>6} {kurtarma(AKAN, a)['kontrol']:>5} {k:>11} {max(y):>7}" f" {max(y) + k:>14} {round(o, 1):>8} {round(o + k, 1):>15}")
dusme None 6 4 3 2 1
2026-02 200 200 200 200 200 0
2026-03 400 400 400 400 0 0
2026-04 600 600 600 0 200 0
2026-05 800 800 0 200 0 0
2026-06 1000 1000 200 400 200 0
2026-07 1200 0 400 0 0 0
2026-08 1400 200 600 200 200 0
2026-09 1600 400 0 400 0 0
2026-10 1800 600 200 0 200 0
2026-11 2000 800 400 200 0 0
2026-12 2200 1000 600 400 200 0
aralik nokta kesin bedel en kotu en kotu toplam ortalama ortalama toplam
None 0 0 2200 2200 1200.0 1200.0
6 2 400 1000 1400 545.5 945.5
4 3 600 600 1200 327.3 927.3
3 4 800 400 1200 218.2 1018.2
2 6 1200 200 1400 109.1 1309.1
1 12 2400 0 2400 0.0 2400.0
Matris kazancın nereden geldiğini adıyla gösterir: düşmenin son noktaya olan uzaklığından.
2026-07’de aralık 6 sıfır verir, çünkü düşme tam noktanın üstüne gelmiştir; aynı aralık
2026-12’de 1000 verir. Aralık 4, 2026-09’da 0 verirken aralık 3 orada 400 verir — daha sık nokta
tutan kurulum, o düşmede daha kötüdür. Altı sütunun hiçbiri öbürünü her satırda yenmez.
Ortalama sütunu bu gürültüyü siler ve düzenli davranır: 1200,0 → 545,5 → 327,3 → 218,2 → 109,1 → 0. Ortalamada aralığı yarıya indirmek kurtarmayı yaklaşık yarıya indirir; tek bir düşmede indirmez. Bir kurulum tek bir düşme yaşar, ortalama yaşamaz; kararı ortalamayla veren, gerçekleşen düşmeyle karşılaşır.
Son iki sütun bedeli ekler. Denetim noktası tutmak DURUM_SATIRI = 200 üzerinden kesin bedel öder:
aralık 6’da 400, aralık 3’te 800, aralık 1’de 2400. En kötü duruma göre en ucuz kurulum 1200 ile
aralık 4 ve aralık 3, ortalamaya göre 927,3 ile aralık 4. İki ölçüt iki farklı yanıt verir ve
“aralığı yarıya indir” kuralı ikisinde de en iyi değildir.
Kesin Bedel ve Olasılıklı Kazanç
Yukarıdaki toplamlar sessiz bir varsayım taşır: her koşumda bir düşme olduğu. Üçüncü blok bu varsayımı gevşetir ve aynı kararı dört düşme olasılığında yeniden verir. Ardından işi dört işçiye bölüp düşen tek işçinin ne kadarını geri istediğini sayar.
# Bu blok ilk iki bloktaki AKAN , DONEM , ISCI , DURUM_SATIRI , ARALIK ve # kurtarma tanimlarini surdurur. def izno(m): h = 2166136261 for c in str(m): h = ((h ^ ord(c)) * 16777619) & 0xFFFFFFFF return h def dagit(kayitlar, anahtar, isci=ISCI): kova = {i: [] for i in range(isci)} for k in kayitlar: kova[izno(k[anahtar]) % isci].append(k) return kova print("dusme olasiligi " + " ".join(f"{str(a):>6}" for a in ARALIK) + " en iyi") for p in (1.0, 0.75, 0.5, 0.25): s = [] for a in ARALIK: y = [kurtarma(AKAN, a, d)["yeniden"] for d in DONEM[1:]] s.append(p * sum(y) / len(y) + kurtarma(AKAN, a)["kontrol"] * DURUM_SATIRI) print(f"{p:>15} " + " ".join(f"{round(v, 1):>6}" for v in s) + f" {str(ARALIK[s.index(min(s))]):>6}") KOVA = dagit(AKAN, "abone") print("\naralik butun is bastan bolumlu durumda en yuklu isci tam bir kez durumu") for a in (None, 6, 3, 1): g = kurtarma(AKAN, a)["yeniden"] per = max(kurtarma(KOVA[i], a)["yeniden"] for i in range(ISCI)) print(f"{str(a):>6} {g:>16} {per:>31} {g:>19}")
dusme olasiligi None 6 4 3 2 1 en iyi
1.0 1200.0 945.5 927.3 1018.2 1309.1 2400.0 4
0.75 900.0 809.1 845.5 963.6 1281.8 2400.0 6
0.5 600.0 672.7 763.6 909.1 1254.5 2400.0 None
0.25 300.0 536.4 681.8 854.5 1227.3 2400.0 None
aralik butun is bastan bolumlu durumda en yuklu isci tam bir kez durumu
None 1600 408 1600
6 400 102 400
3 400 102 400
1 0 0 0
İlk tablo aralık kararının iş yüküne değil, düşme sıklığına bağlı olduğunu gösterir. Her koşumda düşme varsa en iyi seçim aralık 4’tür; dörtte üç olasılıkta aralık 6’ya kayar; olasılık yarıya indiğinde en iyi seçim hiç nokta tutmamaktır. Sebebi tek cümlededir: denetim noktasının bedeli kesindir, kazancı olasılıklıdır. Kesin bedel her koşumda ödenir; kazanç yalnız düşme olduğunda ve yalnız düşmenin son noktaya uzaklığı kadar gerçekleşir.
Düşen İşçi Ne Kadarını Geri İstiyor
İkinci tablo dersin açılış sorusunu yanıtlar. İş abone anahtarıyla dört işçiye bölünmüşse ve durum
her işçide kendi bölümü için tutuluyorsa, düşen tek işçi bütün işi değil yalnız kendi payını geri
ister: 1600 yerine 408, 400 yerine 102 satır. Bölümlü durum kurtarmayı dörtte bire indirir —
ama yalnız durumun bölümlü tutulması koşuluyla. Durum tek bir yerde toplanmışsa ya da motor düşme
üzerine bütün işi yeniden başlatıyorsa geri istenen sayı yine 1600 ile 400’dür. Bölüşüm kurtarmayı
ancak durum da bölünmüşse ucuzlatır.
Son sütun tam bir kez semantiğinin bedelidir ve sayısı şaşırtıcı biçimde tanıdıktır. Kurtarma sırasında yeniden hesaplanan satırlar çıkışa ikinci kez yazılır; bunu engellemenin tek yolu, son noktadan bu yana hangi satırın yazıldığını hatırlamaktır. O küme tam olarak yeniden hesaplanan satırlar kümesidir: aralık yokken 1600, aralık 6 ve 3’te 400, aralık 1’de 0. Tam bir kez, kurtarmanın yeniden hesapladığı satır kadar durum tutmaktır; aralığı sıklaştırmak kurtarmayı ucuzlatırken bu durumu da küçültür ve iki kazanç aynı sayıdan gelir.
Bu kümenin kendisi de bir durumdur ve düşen işçiyle birlikte yiter. Yazılan satırların listesi
yalnız bellekte duruyorsa, kurtarma onu da kaybeder ve hangi satırın çıkışa gittiği bilinmez hâle
gelir; tam bir kez ancak liste denetim noktasının içine alınırsa sağlanır. Bu, kesin bedeli
DURUM_SATIRI = 200‘ün ötesine taşır: nokta artık kısmi toplamları değil, son noktadan bu yana
yazılmış satırların kimliğini de tutar. Aralık 6’da bu 400 kimliktir, aralık 3’te de 400.
Bu tutulmazsa ne olduğu Veri Hatları ve Orkestrasyon kursunda ölçülmüştü: en az bir kez kurulum 2200 satırı geçirir, 19 yinelenme oluşur ve sunulan sapma boş kalır. Kursun üçüncü iddiası burada da geçerlidir: tam bir kez sağlandığı sürece dört aralığın dördü de aynı sonucu üretir. Sonuca bakarak hangi aralığın seçildiğini söylemenin yolu yoktur; fark yalnız ödenen bedeldedir.
Özet
- 2200 satırlık akan işte
2026-09düşmesinde yeniden hesaplanan satır denetim noktası yokken 1600, aralık 6’da 400, aralık 3’te yine 400, aralık 1’de 0’dır. - Aralığı yarıya indirmek kurtarmayı yarıya indirmez: düşmeden önceki son nokta yerinden oynamamıştır. Aynı düşmede aralık 4 0, aralık 3 400 verir; daha sık nokta tutan kurulum daha kötü olabilir.
- On bir düşme noktasının ortalaması düzenlidir (1200,0 → 545,5 → 327,3 → 218,2 → 109,1 → 0), ama bir kurulum ortalama değil tek bir düşme yaşar. En kötü duruma göre en ucuzu 1200 ile aralık 4 ve 3, ortalamaya göre 927,3 ile aralık 4’tür.
- Denetim noktasının bedeli kesin, kazancı olasılıklıdır: düşme olasılığı 1’de en iyi aralık 4, 0,75’te 6, 0,5 ve altında hiç nokta tutmamaktır.
- Bölümlü durumda düşen tek işçi 1600 yerine 408, 400 yerine 102 satır geri ister; bölüşüm kurtarmayı ancak durum da bölünmüşse ucuzlatır.
- Tam bir kez, kurtarmanın yeniden hesapladığı satır kadar durum tutmaktır: 1600, 400, 400 ve 0. Bu sağlandığı sürece dört aralık da aynı sonucu üretir ve fark yalnız bedeldedir.
Sonraki Adım
Beş ders bedelin beş ayrı adını yazdı: taşınan satır, kopya, çarpıklık, tutulan satır ve yeniden hesaplanan satır. Hepsinin altında aynı iki sayı duruyordu — bir işin ne kadar sürdüğü ve toplamda ne kadar iş yaptığı — ve her derste bu ikisi ayrı ayrı yazıldı. Geriye tek bir soru kalıyor: bir küme kaç işçiyle kurulmalı. Sonraki ders işçi sayısını birden on altıya kadar süpürür ve süre inerken toplam işin çıktığını gösterir; hangisinin ödendiği yazılmadan bu kararın verilemeyeceğini sayar ve kursu kapatır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.