Ders 20 / 20
Boğucu İncir Geçişi
Eski sistemin yol yol değiştirilmesi: sekiz yolun iki farklı sırayla taşınması, hacim sırasının trafiği 3,89 kat hızlı taşıyıp çift yazma yükünü 1,52 kat büyütmesi, geçiş cephesinin zaman aşımı bütçesinden pay alması ve geri alınabilirliğin çift yazma kesildiği anda bir turdan 3360 saniyeye çıkması.
İçindekiler
Önceki beş ders yeni düzenin parçalarını kurdu: tekillik defteri, telafi zinciri, talep fişi, vale anahtarı ve dış yapılandırma deposu. Hepsi tek bir varsayımın üstünde duruyor — gönderi takip ve ücretlendirme servisinin bu tasarımdan ibaret olduğu. Oysa servis sıfırdan doğmadı: eski sistem hâlâ ayakta ve yeni düzenin yanında duruyor.
Boğucu incir geçişi (strangler fig), eski sistemi bir kerede değiştirmek yerine yollarını tek tek taşıyan ve ikisinin önüne bir yönlendirme katmanı koyan geçiş biçimidir. O katman geçiş cephesidir: her isteği alır, o yolun taşınıp taşınmadığına bakar ve eski ya da yeni sisteme gönderir. Ölçüler dörttür: taşınan yol sayısı ve sırası, iki sistemde birden tutulan durumun büyüklüğü, cephenin arızasız gündeki bedeli ve bir yolu geri çevirmenin turu.
Sıra Bir Durum Kararıdır
Servisin sekiz yolu ve beş durum varlığı vardır. Bir yol taşındığında, dokunduğu bir durum varlığı taşınmamış yollar tarafından da kullanılıyorsa o varlık bölünür: iki depoda birden tutulmak ve her yazmada ikisine birden yazılmak zorundadır. Bölünmüş durum geçişin asıl maliyetidir ve taşıma sırası onu doğrudan belirler.
DD18 — satıcı başına günde bir fatura okuması, yani günde 4000; gerekçesi K01’in 4000 satıcısıdır. Tarife hacmi Veri Katmanı Ölçekleme kursunun D5 varsayımından, kanıt hacimleri bu konunun DD8 ve DD12 varsayımlarından gelir; kalanı K01’in hesabıdır.
// incir/gecis.mjs — yol yol tasimanin surec ici modeli. Gercek sistem, ag ve depo yoktur: // yollar ve durum varliklari birer nesne, bolunmus durum bir kume islemidir. // [yol adi, gunluk istek hacmi (K01 hesaplari ve DD18), okudugu durum, yazdigi durum] export const YOL = [ ["takip-sorgu", 12_000_000, "gonderi olay", ""], ["durum-olayi", 2_800_000, "gonderi", "olay"], ["gonderi-olustur", 400_000, "", "gonderi"], ["kanit-yukleme", 400_000, "olay", "kanit"], ["kanit-okuma", 8_000, "kanit", ""], ["ucret-donem", 4_000, "gonderi olay tarife", "fatura"], ["fatura-okuma", 4_000, "fatura", ""], ["tarife-yonetim", 1, "", "tarife"], ].map(([ad, hacim, o, y]) => ({ ad, hacim, dokunur: `${o} ${y}`.split(" ").filter(Boolean) })); // Durum varliginin gunluk yazma hacmi (K01 hesaplari; tarife M19/K04'un D5 varsayimi) export const YAZMA = { gonderi: 400_000, olay: 2_800_000, kanit: 400_000, fatura: 4_000, tarife: 1 }; export const GUN = 86_400; // Tasinmis yol kumesi verildiginde bolunmus durum varliklari ve cift yazma hizi export function bolunmus(tasinan) { const ad = new Set(tasinan.map((y) => y.ad)), kalan = YOL.filter((y) => !ad.has(y.ad)); const b = Object.keys(YAZMA).filter((d) => tasinan.some((y) => y.dokunur.includes(d)) && kalan.some((y) => y.dokunur.includes(d))); return { varlik: b, ciftYazma: b.reduce((t, d) => t + YAZMA[d], 0) / GUN }; } // Sira: "hacim" = en cok istek alan yol once; "durum" = bolunmus yazmayi en aza indiren yol once export function sirala(kip) { if (kip === "hacim") return [...YOL].sort((a, b) => b.hacim - a.hacim); const kalan = [...YOL], sira = []; while (kalan.length > 0) { let en = 0; for (let i = 1; i < kalan.length; i += 1) { const a = bolunmus([...sira, kalan[i]]).ciftYazma, e = bolunmus([...sira, kalan[en]]).ciftYazma; if (a < e || (a === e && kalan[i].hacim > kalan[en].hacim)) en = i; } sira.push(...kalan.splice(en, 1)); } return sira; }
// incir/olc.mjs — iki tasima sirasinin cift yazma yuku, tasinan trafik, geri alma ve arizali gun import { YOL, YAZMA, GUN, bolunmus, sirala } from "./gecis.mjs"; const TOPLAM = YOL.reduce((t, y) => t + y.hacim, 0); const UC_TEPE = 513.89, TARAMA = 833.33, BUTCE = 28.2 * 60; // K01 hesaplari; aylik ariza payi console.log(`${YOL.length} yol, ${Object.keys(YAZMA).length} durum varligi, ` + `gunluk ${TOPLAM.toLocaleString("tr-TR")} istek`); const izle = (kip) => { const tasinan = [], satir = []; let ciftAlan = 0, trafikAlan = 0; for (const y of sirala(kip)) { tasinan.push(y); const b = bolunmus(tasinan), pay = tasinan.reduce((t, x) => t + x.hacim, 0) / TOPLAM; ciftAlan += b.ciftYazma; trafikAlan += pay; satir.push([y.ad, pay, b.varlik.length, b.ciftYazma]); } return { satir, ciftAlan, trafikAlan }; }; const R = {}; for (const kip of ["hacim", "durum"]) { R[kip] = izle(kip); console.log(`\n${kip} sirasi`); console.log(`${"adim".padStart(5)}${"tasinan yol".padStart(21)}${"tasinan trafik".padStart(16)}${"bolunmus varlik".padStart(17)}${"cift yazma/s".padStart(14)}`); R[kip].satir.forEach(([ad, pay, n, c], i) => console.log(`${String(i + 1).padStart(5)}${ad.padStart(21)}${`%${(100 * pay).toFixed(2)}`.padStart(16)}${String(n).padStart(17)}${c.toFixed(2).padStart(14)}`)); console.log(`cift yazma alani ${R[kip].ciftAlan.toFixed(2)} yazma/s-adim, tasinan trafik alani ${R[kip].trafikAlan.toFixed(4)} adim`); } console.log(`\nhacim / durum: cift yazma ${(R.hacim.ciftAlan / R.durum.ciftAlan).toFixed(2)} kat, tasinan trafik ${(R.hacim.trafikAlan / R.durum.trafikAlan).toFixed(2)} kat`); // Geri alma: cift yazma surerken yonlendirme degisimi 1 tur; kesildikten sonra geri doldurma gerekir. console.log(`\n${"cift yazma kesildikten sonra".padEnd(28)}${"geri doldurulacak olay".padStart(24)}${"geri alma s".padStart(13)}${"ariza payinin".padStart(15)}`); for (const [ad, sn] of [["0 (cift yazma suruyor)", 0], ["1 saat", 3600], ["1 gun", 86_400]]) { const kayit = (YAZMA.olay / GUN) * sn, s = kayit / TARAMA; console.log(`${ad.padEnd(28)}${Math.round(kayit).toLocaleString("tr-TR").padStart(24)}${s.toFixed(2).padStart(13)}${`%${((100 * s) / BUTCE).toFixed(2)}`.padStart(15)}`); } // Arizali gun: her sirada tasinan trafik yuzde 50'yi ilk gectigi adimda yeni sistem duruyor. const DD20 = 60; // cephesiz yerlesimde yonlendirme yasam suresi, s console.log(`\n${"sira".padEnd(8)}${"adim".padStart(6)}${"tasinan trafik".padStart(16)}${"cephe: dusen".padStart(14)}${"DD20: dusen".padStart(13)}${"esdeger kesinti s".padStart(19)}${"ariza payinin".padStart(15)}`); for (const kip of ["hacim", "durum"]) { const i = R[kip].satir.findIndex(([, p]) => p >= 0.5), pay = R[kip].satir[i][1]; const d = UC_TEPE * pay * DD20; console.log(`${kip.padEnd(8)}${String(i + 1).padStart(6)}${`%${(100 * pay).toFixed(2)}`.padStart(16)}${(UC_TEPE * pay).toFixed(0).padStart(14)}${d.toFixed(0).padStart(13)}${(d / UC_TEPE).toFixed(2).padStart(19)}${`%${((100 * d) / UC_TEPE / BUTCE).toFixed(2)}`.padStart(15)}`); }
8 yol, 5 durum varligi, gunluk 15.616.001 istek
hacim sirasi
adim tasinan yol tasinan trafik bolunmus varlik cift yazma/s
1 takip-sorgu %76.84 2 37.04
2 durum-olayi %94.77 2 37.04
3 gonderi-olustur %97.34 2 37.04
4 kanit-yukleme %99.90 3 41.67
5 kanit-okuma %99.95 2 37.04
6 ucret-donem %99.97 2 0.05
7 fatura-okuma %100.00 1 0.00
8 tarife-yonetim %100.00 0 0.00
cift yazma alani 189.86 yazma/s-adim, tasinan trafik alani 7.6878 adim
durum sirasi
adim tasinan yol tasinan trafik bolunmus varlik cift yazma/s
1 tarife-yonetim %0.00 1 0.00
2 fatura-okuma %0.03 2 0.05
3 gonderi-olustur %2.59 3 4.68
4 kanit-okuma %2.64 4 9.31
5 kanit-yukleme %5.20 4 37.08
6 ucret-donem %5.23 2 37.04
7 takip-sorgu %82.07 2 37.04
8 durum-olayi %100.00 0 0.00
cift yazma alani 125.19 yazma/s-adim, tasinan trafik alani 1.9775 adim
hacim / durum: cift yazma 1.52 kat, tasinan trafik 3.89 kat
cift yazma kesildikten sonra geri doldurulacak olay geri alma s ariza payinin
0 (cift yazma suruyor) 0 0.00 %0.00
1 saat 116.667 140.00 %8.27
1 gun 2.800.000 3360.01 %198.58
sira adim tasinan trafik cephe: dusen DD20: dusen esdeger kesinti s ariza payinin
hacim 1 %76.84 395 23694 46.11 %2.72
durum 7 %82.07 422 25305 49.24 %2.91
Bu sayılar ölçüm sınıfındadır; süreç içi bir modelden gelirler ve girdileri K01’in hesapları ile bu konunun varsayımlarıdır.
İki Sıra, İki Ayrı Şey İyileştiriyor
Hacim sırası ilk adımda trafiğin yüzde 76,84’ünü taşıyor. Bedeli hemen başlıyor: gonderi ve
olay ilk adımdan itibaren bölünüyor ve
çift yazma geçiş boyunca 37,04 yazma/s’de kalıyor. Bu ortalama bir hızdır ve bölünmüş varlıkların
yazması ikinci depoya yeniden uygulandığı için yazma yolunu 74,08 yazma/s’ye, tam iki katına
çıkarır.
Durum sırası tersini yapıyor: ilk altı adımda çift yazma neredeyse yok, ama taşınan trafik yüzde 5,23’te kalıyor ve eski sistem geçişin büyük bölümünde yükünün tamamını taşıyor. İki integral ödünleşimi tek satırda veriyor — hacim sırası trafiği 3,89 kat hızlı taşıyor, çift yazma yükünü 1,52 kat büyütüyor.
Bölünmüş varlık sayısı üçüncü bir ayrım açıyor: durum sırası çift yazma hızını düşürürken bölünmüş varlık sayısını 4’e çıkarıyor (hacim sırasında en fazla 3) — daha çok kod yolu, daha az bayt. Geçiş sırasının tek bir en iyisi yoktur; seçim, eski sistemin yükü mü çift yazmanın riski mi daha pahalı sorusuna verilen yanıttır.
Cephenin Bedeli ve Geri Alınabilirlik
Cephe bütün trafiğin önünde durur ve arızasız gündeki bedeli üç kalemdir. Birincisi bir ek duraktır: günde 15.616.001 isteğin tamamı, tepe uçta 513,89 istek/s, fazladan bir yönlendirme kararından geçer. İkincisi zaman aşımı bütçesindeki paydır. Zaman Aşımı Bütçeleri dersi 200 milisaniyelik eşiği bölüştürmüştü: ağ geçidi payı 20 ms, kola kalan 180 ms, dağıtım 90/90. Cephe de ağ geçidi kadar pay alırsa (DD19) kola kalan 160 ms’ye iner ve dağıtım 80/80 olur — her adımın payı yüzde 11,1 daralır. Üçüncüsü çift yazmadır. Cephe ayrıca yeni bir tekil noktadır: Dağıtım Damgaları dersi yönlendirme eşlemesinin bulaşma kapsamını yüzde 90,9 ölçmüştü, cephenin kapsamı yüzde 100’dür.
Karşılığında aldığı şey geri alınabilirliktir. Alt tablo geçişin ortasında yeni sistemin durduğu durumu sayıyor. Cephe varken bir yolu geri çevirmek bir yönlendirme kararının değişmesidir: hacim sırasında 395, durum sırasında 422 istek düşer. İstemcilerin doğrudan yönlendirildiği bir yerleşimde geri çevirme yönlendirme kaydının yaşam süresi kadar sürer (DD20 — 60 saniye) ve düşen istek 23.694 ile 25.305’e çıkar: 46–49 saniyelik eşdeğer kesinti, K01’in aylık arıza payının yüzde 2,72–2,91’i.
Geri alınabilirliğin bir son kullanma tarihi var. Çift yazma sürerken eski sistemin verisi günceldir ve geri alma bir turdur. Kesildikten bir saat sonra eski sisteme 116.667 olay geri doldurulmalıdır: K01’in 833,33 kayıt/s tarama hızıyla 140,00 saniye, arıza payının yüzde 8,27’si. Bir gün sonra 2.800.000 olay ve 3360,01 saniye — payın yüzde 198,58’i. Çift yazmanın kesilmesi bir tasarruf kararı değil, geri dönüşün kapatılmasıdır.
Özet
- Taşınan bir yolun dokunduğu durum varlığı taşınmamış bir yol tarafından da kullanılıyorsa bölünür ve iki depoya birden yazılır; çift yazma yazma yolunu 37,04’ten 74,08 yazma/s’ye çıkarır.
- Hacim sırası ilk adımda trafiğin yüzde 76,84’ünü taşıyor ama çift yazmayı hemen 37,04 yazma/s’ye çıkarıyor; durum sırası ilk altı adımı çift yazmasız geçiriyor, trafiği yüzde 5,23’te tutuyor.
- İki integral ödünleşimi veriyor: hacim sırası trafiği 3,89 kat hızlı taşıyor, çift yazma yükünü 1,52 kat büyütüyor. Tek bir en iyi sıra yoktur.
- Cephenin arızasız gündeki bedeli: günde 15.616.001 isteğe bir ek durak, bütçeden ağ geçidi kadar pay (kol payı 180 → 160 ms, dağıtım 90/90 → 80/80) ve yüzde 100 bulaşma kapsamlı tekil nokta.
- Cephenin arızalı gündeki kazancı geri çevirme hızıdır: düşen istek 25.305 yerine 422.
- Geri alma ancak çift yazma sürerken bir turdur; kesildikten bir gün sonra 3360,01 saniyeye (arıza payının yüzde 198,58’i) çıkar.
Kurs Kapanışı
Kurs, dört kursun tasarladığı sistemi arıza altında ele aldı ve her derste aynı iki soruyu sordu: bu kalıp arızasız günde neye mal oluyor, arızalı günde neyi kaç birim kurtarıyor.
| Ders | Arıza kipi | Arızasız günün bedeli | Arızalı günün kazancı |
|---|---|---|---|
| Arıza Kipleri | durma, yavaşlama, kısmi arıza, bayat içerik, ağ bölünmesi | yanıta 8 bayt damga (4111,12 bayt/s); adlandırma için 20 çağrılık pencere | durma 97,22 istek/s ve 1 bileşen, yavaşlama 513,89 istek/s ve 2 bileşen — 5,29 kat |
| Devre Kesici | bağımlılığın yavaşlaması ve durması | 1166 çağrıda denetim, bağımlılık başına 20 kayıt; 0,10 eşiği sağlıklı günde 386 geçerli olayı reddediyor | yuvasız takip isteği 671 → 0; olay bacağının yuva-turu 19.312 → 1646 (%91,48) |
| Bölme Kalıbı | bir bağımlılığın yavaşlaması | düşen istek 105 → 578 (5,5 kat), doluluk 0,541 → 0,524; 4239 kez komşuda boş yuva varken red | komşu akışta düşen istek 2654 → 172 (%93,5), algılamaya bağlı değil |
| Yeniden Deneme ve Fırtına Riski | tam kesinti ve kısmi bozulma | izin 1 → 27’de çağrı değişmiyor, çarpan 1,03 | deneme bütçesi 0,30 fırtınayı 6,24 → 2,88 çağrı/tura indiriyor; bedeli 103 düşen istek |
| Zaman Aşımı Bütçeleri | bağımlılığın yavaşlaması (AY10) | son tarih alanı 40 bayt (yanıtın %8,3’ü); 48 isteğin 2’si kesiliyor | ağırlıklı dağıtım ortancayı 200 → 93 ms, tutulan yuvayı 82,4 → 40,2 (iptal sinyaliyle) |
| Geri Basınç | aşırı yük (AY11) | 4164 geçerli olay reddi (%3,57), saniyede 291,66 sinyal denetimi | 44.399 olay kayıptan redde dönüyor; dar açıkta kayıp 34.064 → 8579 (3,971 kat) |
| Kısıtlama ve Yük Boşaltma | toplu iş tepeye taşıyor (AY13a); uç düğümü düşüyor (AY13b) | kısıtlama 15.630 geçerli sorguyu reddediyor (%6,25); boşaltmanın bedeli yok | boşaltma AY13b’de tepenin 0,9348’ini koruyor; kapısız düzen arıza payının %56,7’sini yerdi |
| Zarif Bozulma | isteğe bağlı bağımlılık (AY14a); çekirdek (AY14b) düştü | 24 baytlık tazelik göstergesi (%5,0), 2,29 MiB yedek defteri, 1666,68 yazma/s | AY14a’da kesinti 15,00 → 0,00 dakika; AY14b’de yalnız 15,00 → 14,02 |
| Devralma Tasarımı | etkin kopyanın durması | eşik 1’de ayda 120 s yanlış devralma; eşik 3’te sıfır, geçiş penceresi 4 → 8 s | kesinti 20,0 dakikadan 16 saniyeye (75 kat); arıza payının %70,9’u yerine %0,95’i |
| Sağlık Ucu İzleme | yarı düşmüş kopya; paylaşılan bağımlılığın düşmesi | derin denetim depoya %1,08 yük (48 kopyada %17,28); yanlış çıkarma ayda 13,3 kez yükü 1,50 katına | sessiz kayıp 17 → 0; hazır olma denetimi 40 okuma ve 10 yazma kurtardı |
| Kurtarma Hedefleri | veri kaybı ve kurtarma süresi eşiklerinin aşılması | veri kaybını sıfırlamak günde 2.800.000 onay turu, ayda 1555,52 reddedilen yazma | ayda 194,44 kalıcı kayıp kalkıyor (oran 8,00); 8 saniyelik pencere payına 211,50 arıza sığdırıyor |
| Yedeklilik Bölgeleri | makine, alan ve bölge kaybı | boşta kapasite : iki alanda %100, altı alanda %20; iki bölgeli düzen makine kaybında 1 yazma kaybediyor | alan kaybında düşen yazma 126 → 0, kayıp 114 → 2 |
| Dağıtım Damgaları ve Coğrafi Kopyalar | damga içi bileşen arızası | bileşen 9 → 33 (coğrafi kopyayla 65); gün sonu işi damga sayısı kadar yere gidiyor | durum deposunun bulaşma kapsamı %100 → %25; damgayı geçen bağ 6 → 2 |
| Felaket Kurtarma Tatbikatı | denetimli arıza denemesi | ayda bir tatbikat 0,63 dakika (planlı payın %4,22’si), tepe yükte 19.527,82 uç isteği | planda 6 turluk kurtarma 19 tur ölçüldü (3,17 kat); 30 s hedef 38 saniyede kırılıyor |
| Etkisiz İşlemler | devralma ve yeniden denemede yinelenen istek | defter 3.200.000 kayıt / 230,40 MB (günlük artışın %23,61’i); yazma satırı ×2,00, okuma ×3,33 | ayda 8002 önlenen yan etki: 902 yinelenen ücret kalemi, 902 bildirim |
| Telafi Edici İşlemler | iş akışının yarıda kesilmesi | 8000 yazılmış telafi yolu, günde 60 koşan çağrı; sona taşınamayan geri alınamaz adım | telafisiz adım 80 → 60/gün; ikinci deneme askıda işi 2,979 → 0,171/gün |
| Talep Fişi Kalıbı | üretici ve tüketici çökmesi; kuyruk birikmesi | depoda 112,00 GB (saklamanın %15,72’si); günde 1968 yetim yük, 3948 sarkan fiş | kuyruk 4,4689 → 0,0316 Mbit/s; birikmede 3016,5 → 21,3 MB (141,6 kat) |
| Vale Anahtarı Kalıbı | kanıt deposunun yavaşlaması | günde 400.000 imzalama (tepede K01 ucunun %2,703’ü); 4166,7 anahtarlık açık pencere | düşen aktarım 28 → 0, tutulan yuva 64 → 0; kapsam daraltması 730 kat |
| Dış Yapılandırma Deposu | deponun düşmesi; yanlış değerin yazılması | depo okuma 0,1000/s; yayılma 25 s, karışık pencere 40 s | düşen istek 20.556 → 0 (arıza payının %2,36’sı); kademeli yaymada hatalı yanıt 61.668 → 20.556 |
| Boğucu İncir Geçişi | geçişin ortasında yeni sistemin durması | çift yazma yazma yolunu 37,04 → 74,08 yazma/s’ye çıkarıyor; cephe bütçeden 20 ms alıyor (180 → 160 ms) | düşen istek 25.305 → 422; geri alma çift yazmayla 1 tur, kesildikten bir gün sonra 3360,01 s |
Tablonun kuralı adıyla anılmalı: bir kalıp iki sayı olmadan savunulamaz. “Dayanıklılık sağlar” cümlesi bu kursta karar taşımadı. İki sütun birbirinin yerine de geçmez — arızasız günün bedeli her gün ödenir, arızalı günün kazancı yılda birkaç kez tahsil edilir; bir kalıbı seçmek bu iki sıklığın çarpımını karşılaştırmaktır. Kursun kendi varsayımları (AY, KU, DD dizileri) K01’in tablosuna karışmadı; her biri kendi adı ve duyarlılığıyla yazıldı.
Kursun bıraktığı soru bütün tablonun altındadır. Devre kesici bir eşiğin aşıldığını, devralma bir kopyanın düştüğünü, geri basınç bir kuyruğun dolduğunu, dış yapılandırma deposu bir değerin yanlış olduğunu fark edildiğinde çalışır. Farkın nasıl edileceği hiç tasarlanmadı: hangi ölçütün toplanacağı, hangi eşiğin uyarı doğuracağı, yavaşlamanın hangi ölçümle görüneceği ve bir tasarımın taşıyabileceği yükün nasıl sınanacağı hep varsayıldı. Sonraki kurs Başarım Karşıt Kalıpları ve İzleme o katmanı ele alır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.