Ders 14 / 14
Toplu ve Akış İşleme Hattı
İki işleme modelinin aynı sistemde birlikte kullanıldığı kapanış vakası: ilerleme damgasının geç gelen veriyi nasıl kestiği, akış yolunun ilk yayımladığı sonucun toplu yolun yeniden hesabından sapması, sapmanın kapanma eğrisi ve iki yolu birden koşturmanın işlem yükü olarak bedeli.
İçindekiler
Önceki dört vakanın her biri işi ya yazıldığı anda ya da sorulduğu anda yaptı; hiçbirinde ikisi aynı sistemde birlikte gerekmedi. Bu vaka o durumu ele alır. Sistem bir olay akışını dakikalık pencerelerde sayar ve iki yol kurulur: akış işleme saniyeler içinde bir sonuç yayımlar, toplu işleme aynı pencereyi saatler sonra kütükten yeniden hesaplar. İkisi aynı girdiden farklı sonuçlar üretir, çünkü akış yolu bir pencereyi kapatmak zorundadır ve o andan sonrasını göremez.
Kapatma kararını ilerleme damgası (watermark) verir: akışın zaman ekseninde nereye kadar ilerlediğini söyleyen, olay zamanı cinsinden bir sınırdır ve bu sınırı geçen pencere kapanır. Adı benzese de Uygulama Katmanı kursunun sürüm damgasından ve Dayanıklılık ve Güvenilirlik kursunun dağıtım damgasından ayrıdır: biri kaydın sürümünü, öteki dağıtım biriminin kimliğini gösterir, bu ise zamandaki ilerlemeyi. Damga geçtikten sonra ulaşan kayıt geç gelen veridir (late arriving data) ve yayımlanan sayıya girmez.
Kısıtlar
İşlevsel gereksinim: olay kabul etme, olay zamanına göre 60 saniyelik pencerelerde sayma, sonucu yayımlama ve geç gelen veriyle düzeltme.
İşlevsel olmayan gereksinim, sayıyla: ilk sonuç pencere kapandıktan en çok 60 saniye sonra yayımlanır; sapması binde 30’u geçmez; sapma 12 saat içinde binde 0,5’in altına iner; iki yolun toplam işlem yükü ham girdinin 3 katını geçmez.
Kapsam daraltması: akışlar arası birleştirme, oturum pencereleri, tam bir kez işleme garantisi ve sorgu dili tasarlanmaz.
Varsayımlar
| Kod | Varsayım | Değer | Gerekçe |
|---|---|---|---|
| TA1 | günlük olay | 900.000.000 | uçların ürettiği toplam |
| TA2 | olay kaydı | 180 bayt | kimlik, olay zamanı, tür, alan |
| TA3 | pencere boyu | 60 s | raporlamanın en ince taneciği |
| TA4 | gecikme dağılımı | 0,94 düzgün 0–5 s; 0,055 üstel 90 s; 0,005 üstel 4 saat | çoğu uç hızlı, çok azı çevrimdışı |
| TA5 | tepe çarpanı | 3 | tepe saatin gün ortalamasına oranı |
| TA6 | toplu koşum aralığı | 6 saat | günde dört koşum |
| TA7 | kütüğün saklama süresi | 30 gün | yeniden hesabın erişebildiği geçmiş |
TA4 taşıyıcı varsayımdır: iki yol arasındaki farkın tamamı gecikme dağılımının kuyruğundan çıkar. Kuyruk yoksa iki yol aynı sonucu verir ve ikinci yola gerek kalmaz.
Ölçek
// hat-olcek.mjs — TA tablosundan cikan olcek hesabi ve iki yolu birden kosturmanin bedeli const TA = { gunlukOlay: 900_000_000, olayBayt: 180, pencereSn: 60, tepe: 3, topluAralikSaat: 6, saklamaGun: 30 }; const GUN = 86_400; const olaySn = TA.gunlukOlay / GUN; for (const [ad, d] of [ ["ortalama olay/s", olaySn], ["tepe olay/s", olaySn * TA.tepe], ["gunluk kutuk GB", (TA.gunlukOlay * TA.olayBayt) / 1e9], ["kutuk TB (saklama)", (TA.gunlukOlay * TA.olayBayt * TA.saklamaGun) / 1e12], ]) console.log(ad.padEnd(22) + d.toFixed(2).padStart(14)); console.log(`\ntoplu kosum ${TA.topluAralikSaat} saatte bir; tarama penceresi is yukunu belirliyor:`); console.log("tarama saat".padEnd(13) + "gunluk kosum".padStart(14) + "toplu is kati".padStart(15) + "akisla toplam".padStart(15)); for (const W of [6, 12, 24]) { const kosum = 24 / TA.topluAralikSaat; const kat = (kosum * W) / 24; console.log(String(W).padEnd(13) + String(kosum).padStart(14) + kat.toFixed(2).padStart(15) + (1 + kat).toFixed(2).padStart(15)); }
ortalama olay/s 10416.67 tepe olay/s 31250.00 gunluk kutuk GB 162.00 kutuk TB (saklama) 4.86 toplu kosum 6 saatte bir; tarama penceresi is yukunu belirliyor: tarama saat gunluk kosum toplu is kati akisla toplam 6 4 1.00 2.00 12 4 2.00 3.00 24 4 4.00 5.00
Bu sayılar hesap sınıfındadır. Alt tablo son kısıtı bağlıyor: toplu koşum altı saatte bir çalıştığı için tarama penceresi uzadıkça aynı olay daha çok kez okunur — altı saatte bir, on iki saatte iki, yirmi dört saatte dört kez. Akış yolunun tek geçişiyle toplam 2,00 / 3,00 / 5,00 kat oluyor ve üç kat kısıtı yirmi dört saatlik taramayı baştan eliyor.
İki Yolun Farkı
Damga gecikmesi hem yayım süresini hem sapmayı belirler ve ikisi ters yönde hareket eder. Aşağıdaki model küme kurmaz; TA4’ün karışımından gecikme çeker ve akış yolunun saydığını toplu yolun tam sayımıyla karşılaştırır.
// iki-yol.mjs — surec ici model: ayni olay kumesi uzerinde akis yolu ile toplu yolun urettigi // sonuc farki. Ag yok, kume yok; gecikme dagilimi TA4'un uc parcali karisimidir, uretec kendi // yazilmistir ve tohum gorunur. Model oldugu yazilir. const PENCERE = 60, SAYI = 120, OLAY = 2000, TOHUM = 20260803; const KARISIM = [[0.94, "duzgun", 5], [0.055, "ustel", 90], [0.005, "ustel", 14_400]]; // TA4 let durum = TOHUM; const rast = () => { durum = (durum * 1103515245 + 12345) % 2147483648; return durum / 2147483648; }; function gecikme() { let u = rast(), i = 0; while (i < KARISIM.length - 1 && u > KARISIM[i][0]) { u -= KARISIM[i][0]; i += 1; } const [, tur, p] = KARISIM[i]; return tur === "duzgun" ? rast() * p : -Math.log(1 - rast()) * p; } const S = (x) => KARISIM.reduce((a, [w, tur, p]) => // kosumdan bagimsiz: kuyruk olasiligi a + w * (tur === "duzgun" ? Math.max(0, 1 - x / p) : Math.exp(-x / p)), 0); const beklenenGec = (L) => { // pencere icinde duzgun konum uzerinden let t = 0; for (let i = 0; i < 6000; i += 1) t += S(PENCERE + L - (i + 0.5) * (PENCERE / 6000)); return t / 6000; }; const toplam = SAYI * OLAY; // pencere basindan itibaren varis ani const varis = Array.from({ length: toplam }, () => rast() * PENCERE + gecikme()); console.log(`model: ${SAYI} pencere x ${OLAY} olay = ${toplam}, pencere ${PENCERE} s, tohum ${TOHUM}`); console.log(`gecikme karisimi: ${KARISIM.map(([w, t, p]) => `${w}/${t}/${p}s`).join(" ")}\n`); console.log("damga gecikmesi".padEnd(16) + "yayim gecikmesi".padStart(16) + "gec olay binde".padStart(16) + "beklenen binde".padStart(16)); for (const L of [0, 15, 60, 120, 300]) { const gec = varis.filter((o) => o > PENCERE + L).length; console.log(`${L} s`.padEnd(16) + `${PENCERE + L} s`.padStart(16) + ((gec / toplam) * 1000).toFixed(2).padStart(16) + (beklenenGec(L) * 1000).toFixed(2).padStart(16)); } console.log(`\nsapmanin kapanmasi (damga gecikmesi 60 s ile yayimlanan sonuca gore):`); console.log("pencere kapandiktan".padEnd(21) + "hala eksik olay".padStart(17) + "kalan sapma binde".padStart(19)); for (const [ad, T] of [["1 saat sonra", 3600], ["6 saat sonra", 21_600], ["12 saat sonra", 43_200], ["24 saat sonra", 86_400]]) { const kalan = varis.filter((o) => o > PENCERE + T).length; console.log(ad.padEnd(21) + String(kalan).padStart(17) + ((kalan / toplam) * 1000).toFixed(3).padStart(19)); }
model: 120 pencere x 2000 olay = 240000, pencere 60 s, tohum 20260803 gecikme karisimi: 0.94/duzgun/5s 0.055/ustel/90s 0.005/ustel/14400s damga gecikmesi yayim gecikmesi gec olay binde beklenen binde 0 s 60 s 82.46 84.30 15 s 75 s 37.42 38.96 60 s 120 s 24.67 25.58 120 s 180 s 13.32 15.53 300 s 360 s 5.37 6.32 sapmanin kapanmasi (damga gecikmesi 60 s ile yayimlanan sonuca gore): pencere kapandiktan hala eksik olay kalan sapma binde 1 saat sonra 711 2.962 6 saat sonra 251 1.046 12 saat sonra 69 0.287 24 saat sonra 0 0.000
Ölçülen binde bu koşuma bağlı bir ölçüm, beklenen binde karışımın kuyruk olasılığından çıkan koşumdan bağımsız bir hesaptır; beş satırın hepsinde ikisi aynı mertebede.
Üst tablo iki kısıtı birden bağlıyor. Damga 0 iken sapma binde 82,46, 15 saniyede 37,42 — ikisi de binde 30 kısıtını kırıyor; 60 saniyede binde 24,67 ile karşılanıyor. Öte yandan yayım gecikmesi pencere boyu artı damgadır ve “en çok 60 saniye sonra” kısıtı damgayı 60 saniyeyle sınırlıyor. İki kısıt tek bir değerde kesişiyor: damga gecikmesi 60 saniye.
İlk satır bir yanılgıyı da düzeltiyor. Damga sıfırken kaçırılanların çoğu geç gelen veri değil, pencerenin son saniyelerine düşen ve normal hızda ulaşan olaydır; gecikmesi beş saniyenin altında olanların bir kısmı bile sınırı aşar. 15 saniyede bu pay tamamen kalkıyor ve binde 82,46’dan 37,42’ye düşüş oradan geliyor. Kalan sapmanın kaynağı gerçekten kuyruktur.
Alt tablo kapanmayı veriyor: bir saat sonra binde 2,962, altı saat sonra 1,046, on iki saat sonra 0,287. “On iki saatte binde 0,5’in altına iner” kısıtı altı saatlik taramayla karşılanmıyor, on iki saatlikle karşılanıyor. İş yükü kısıtı yirmi dört saati elemişti; kapanma kısıtı altı saati eliyor. Geriye on iki saatlik tarama penceresi kalıyor ve toplam iş ham girdinin tam 3,00 katı oluyor.
Tasarım
Tek gerçek kaynak olay kütüğüdür ve iki yol da onun izdüşümüdür (Veri Katmanı Ölçekleme kursunun Okuma–Yazma Ayrımı konusu, Olay Kaynaklı Tasarım). Yazma modeli kütük, okuma modeli pencere sayılarıdır; ikisinin ayrılması aynı konudaki komut ve sorgu sorumluluğu ayrımıdır. Toplu yolun ürettiği tablo bir somutlaştırılmış görünümdür (Veri Dağıtımı konusu) ve tazelemesi artımlı değil, on iki saatlik pencerenin yeniden hesabıdır.
Yayımlanan değerin üstüne yazma etkisiz olmalıdır (Dayanıklılık ve Güvenilirlik kursunun Dağıtık Doğruluk konusu); tekillik anahtarı pencere ile yolun ikilisidir, böylece aynı koşum iki kez çalışsa da sonuç değişmez. Alma ucu bir ileti aracısı ve rekabet eden tüketiciler üzerine oturur (Uygulama Katmanı ve Servis Etkileşimi kursunun Kuyruklar ve İş Akışları konusu); tepe 31.250 olay/s bu katmanın girdisidir ve tüketici geri kaldığında geri basınç (Arıza Yalıtımı konusu) uca kadar yayılır. Okuyucunun gördüğü değer sonunda tutarlıdır (Sistem Tasarımına Giriş kursunun Temel Nitelikler konusu) ve bayatlık penceresi burada ölçülmüş bir sayıdır: binde 0,287.
Bilerek kullanılmayan kalıp: kenar önbelleği. Trafik Katmanı kursunun Giriş Noktaları konusundaki kenar önbelleği yayımlanan sayıların önüne konmaz, çünkü aynı pencerenin değeri on iki saat boyunca düzeltiliyor; kenarda ikinci bir bayatlık penceresi açmak tasarımın tek ölçülebilir güvencesini, kapanma süresini, ölçülemez yapardı. İkincisi telafi edici işlemdir (Dağıtık Doğruluk konusu): toplu yolun yaptığı geri alma değil üzerine yazmadır, çünkü kütük değişmiyor.
Elenen Alternatifler
Yalnız akış yolu en ucuzudur: bir kat iş, 120 saniyede yayım. Ama binde 24,67’lik sapma hiçbir zaman kapanmaz; düzeltmeyi yapacak ikinci geçiş yoktur.
Yalnız toplu yol doğrulukta kusursuzdur ve iş yükü bir kattır. Bir pencerenin sonucu en kötü durumda altı saat sonra yayımlanır: yayım kısıtının üç yüz altmış katı.
Damgayı büyütmek sapmayı 300 saniyede binde 5,37’ye indirir ve tek yolla binde 30 kısıtını karşılar; yayım gecikmesi 360 saniyeye çıkıp birinci kısıtı altı kat aşar. Hangi kısıt değişirse alternatif kazanır: yayım kısıtı 6 dakikaya gevşetilirse tek akış yolu yeter ve ikinci yolun 2,00 katlık ek yükü düşer.
Arıza Davranışı ve Feda Edilen
Akış yolu tümüyle durduğunda sistem yanıt vermeyi sürdürür: toplu yol altı saatte bir doğru sonucu üretir, yayım gecikmesi 120 saniyeden altı saate çıkar ve sapma sıfırlanır. Bu, zarif bozulmanın (Arıza Yalıtımı konusu) alışılmadık bir biçimidir — bozulan boyut doğruluk değil tazeliktir. Toplu yol durduğunda tersi olur: yayım 120 saniyede kalır ama binde 24,67’lik sapma donar. İki arızada da veri kaybı yok, çünkü iki yol da otuz gün saklanan kütükten türetiliyor.
Feda edilen: aynı olay iki kez işleniyor. Toplam iş ham girdinin 3,00 katı ve aynı sayım iki ayrı kod yolunda tutuluyor; ikisinin aynı sonucu vermesi kod ortaklığıyla değil bir ölçümle güvence altına alınıyor. Okuyucuya verilen ilk sayı da hiçbir zaman nihai değildir.
Özet
- İlerleme damgası bir pencereyi kapatma kararıdır; gecikmesi yayım süresini ve sapmayı ters yönde oynattığı için iki kısıt arasında sıkışır.
- Damga 0 / 15 / 60 / 120 / 300 saniyede sapma binde 82,46 / 37,42 / 24,67 / 13,32 / 5,37; binde 30 kısıtı ile 60 saniyelik yayım kısıtı tek bir değerde, 60 saniyede kesişiyor.
- Damga sıfırken kaçırılanların çoğu geç gelen veri değil, pencerenin son saniyelerine düşen normal olaydır; 15 saniyede bu pay tamamen kalkıyor.
- Tarama penceresi iki yandan sıkışıyor: yirmi dört saat 5,00 katla iş kısıtını, altı saat binde 1,046 ile kapanma kısıtını çiğniyor; on iki saat ikisini de sınırda karşılıyor.
Kurs Kapanışı
On dört vaka aynı altı adımı yürüttü ve her biri bir sayıyla savunuldu.
| Vaka | Tasarımı belirleyen sayı | Seçilen kalıplar | Elenen alternatif | Feda edilen |
|---|---|---|---|---|
| Bağlantı Kısaltma | okuma/yazma 100; 7 karakterde 3859,3 tahmin | kenar önbelleği, yanında okuma, parçalama | sayaç tabanlı üretim: 1,0 tahmin/isabet | 300 s bayatlık penceresi |
| Haber Akışı | dağıtma 1691,87 / toplama 56.570,71 iş/s (33,44 kat) | eşikli karma dağıtım, mesaj kuyruğu, geri basınç | saf okumada toplama: 33,44 kat iş | gönderi başına 203,63 kutu yazması |
| Arama Önerisi | sorgu başına 266,67 bayt; derinlik 10’da 4,59 GB | önek ağacı, görev kuyruğu, itme tabanlı dağıtım | düz sıralı liste: p99 6593 birim | 10 karakter sınırı, 600 s tazelik |
| İçerik Dağıtım | istek oranı 3,13, bayt oranı 20,83; gereken isabet 0,7440 | içerik dağıtım ağı, kenar önbelleği, sürümlü ad | kısa ömürlü tek önbellek: 2 GB’de 0,6188 | yayımın atomikliği |
| Sohbet Sistemi | tepe teslim 22.222,22/s; 1.250.000 bağlantı, 25 düğüm | tekillik anahtarı, sıralı konvoy, çevrimdışı kutu | yoklamalı çekme: 140,63 kat istek | sohbet düzeyinde koşutluk |
| Bildirim Sistemi | tek kanalda teslim 0,9590, eşiğin 3,01 puan altı | kademeli sıra, devre kesici, bölme kalıbı | paralel dağıtım: 2,78 kat çağrı | 30–60 s teslim gecikmesi |
| Hız Sınırlayıcı | sabit pencere 1200 (x2,000), kaydırmalı dilim 600 | kaydırmalı dilim, 0,2 s gecikmeli eşitleme | merkezî sayaç: 40.000 dokunuş/s | aşımın 1,015 katta kalması |
| Bilet ve Stok | talep kontenjanın 56 katı; tükenme 0,179 s | kötümser kilitleme, kontenjan satırı | iyimser kilitleme: 2409 geçerli ret | 304.276 bekleme adımı |
| Ödeme Akışı | yalnız bildirimde binde 59,74; yoklamayla binde 9,76 | etkisizlik, 15 dk mutabakat çevrimi, denetim izi | eşzamanlı doğrulama: binde 75,77 | binde 9,76 ve 30 dk kapanma |
| Nesne Depolama | 2 MB parçada 1,0075; silme (10,4) katı 1,40 | vale anahtarı, etkisizlik, parçalama, denetçi | üç kopya: kat 3,00, yılda 438 kayıp | 697.680 GB-ay fazladan saklama |
| Video Yayın | izlenen/yüklenen 225; oynatamayan yüzde 8,91 | öncelikli kuyruk, talep fişi, kenar önbelleği | sekiz basamak: kat 2,58, 1854 işlemci | bant kullanımı yüzde 64,9 |
| Ölçüt Toplama | 240.000 örnek/s; 31,50 TB’a karşı 393,57 TB | geniş sütun deposu, zaman bölümleme, somutlaştırılmış görünüm | yalnız 5 dk özet: eşikte yüzde 100 hata | 7 günden eski yüzdelik soruları |
| Konum Tabanlı | 1 km hücrede 864 aday, isabet yüzde 51,4 | uzamsal dizin, bileşik dizin, karma parçalama | 8 km hücre: 13.611 aday | yarısı boşa giden tarama |
| Toplu ve Akış | 60 s damgada binde 24,67; 12 saatte binde 0,287 | ilerleme damgası, olay kütüğü ve izdüşüm, etkisizlik | yalnız akış: sapma kapanmaz | 3,00 kat iş, iki kod yolu |
Tablonun kuralı bu müfredatın kuralıdır: bir tasarım kararı ancak bir sayıyla ve bir alternatifle birlikte savunulabilir. Sayının sınıfı — varsayım, hesap, ölçüm — yazılmadan verilen karar tartışılamaz, çünkü karşı taraf neyin gerekçesini soracağını bilemez: varsayım gerekçesiyle ve duyarlılığıyla, hesap koşturulmuş aritmetiğiyle, ölçüm düzeneğiyle ve tohumuyla savunulur.
Yedi kurs bu kuralı parça parça kurdu. Sistem Tasarımına Giriş nitelikleri sayıya çevirdi ve kabaca büyüklük hesabını kurdu; Trafik Katmanı isteğin sisteme nasıl girdiğini, Uygulama Katmanı işin servisler arasında nasıl bölündüğünü, Veri Katmanı Ölçekleme verinin nasıl dağıtıldığını ele aldı. Dayanıklılık ve Güvenilirlik arızanın nasıl çevrelendiğini, Başarım Karşıt Kalıpları ve İzleme bunların nasıl görünür kılındığını gösterdi. Vaka Çalışmaları hepsini tek tek problemlerde birleştirdi ve her seferinde aynı şeyi istedi: kısıtı sayıya çevir, varsayımını yaz, hesabı koştur, kalıbı adıyla seç, bir alternatifi ele, neyi feda ettiğini söyle.
Bundan sonrası okurun kendi tasarım problemidir. Oradaki kısıtlar bu on dört vakanınkine benzemeyecek; benzeyen tek şey yöntem olacak. İlk soru hep aynıdır: bu kararı hangi sayı belirliyor, o sayı hangi sınıftan ve elenen alternatif hangisiydi.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.