Ders 12 / 18
Sentetik İzleme
Gerçek trafiğin görmediği durumların sayılması ve dışarıdan periyodik yoklamayla karşılanması: on arızanın gerçek trafik kuralı ile yoklama üzerinde ayrı ayrı ölçülmesi, yoklama sıklığının fark etme gecikmesi ve maliyetle birlikte taranması, yoklamanın yanlış güven verdiği durumların adlandırılması.
İçindekiler
Buraya kadar üretilen her sinyalin bir ortak yanı vardı: hepsi gerçek trafikten doğdu. Bir istek geldi, bir adım kaydı yazıldı, bir ölçüt kovası doldu, bir kural çaldı. Bu zincirin ilk halkası koparsa geri kalanı hiç çalışmaz — istek gelmiyorsa ölçülecek bir şey de yoktur.
Bu ders bölgesel ölçüm ağının (kurgu) on dört günlük trafiğini beş akış üzerinden modelleyip on arızayı iki ayrı yolla ölçer: gerçek trafikten doğan bir kural ve dışarıdan periyodik yoklama. Sayılan üç şey şudur: gerçek trafiğin hiç göremediği arıza, yoklamanın fark etme gecikmesi ile maliyeti, ve yoklamanın geçtiği hâlde kullanıcının etkilendiği durum.
Gerçek Trafiğin Kör Noktaları
// sentetik/trafik.mjs — on dort gunluk gercek trafigin ve on arizanin MODELI. IG31: bes akisin // dakikalik istek sayisi kurgudur; fatura sorgusu gunduz yogun gece bostur, yillik kapanis ayda // birkac kez cagrilir. IG32: bir ariza uc bicimden biridir — "tam" butun istekleri bozar, // "kismi" yalniz bir abone grubunu bozar, "veri" onbellekten donmeyen yolu bozar. export const TOHUM = 20260806, GUN = 14, DK = GUN * 1440; export const SAAT = [2, 1, 1, 1, 1, 4, 14, 32, 46, 52, 55, 53, 48, 51, 54, 50, 44, 34, 26, 18, 12, 8, 5, 3]; // [ad, gunduz carpani, mesai disi calisir mi, kismi bozulmanin etkiledigi oran] export const AKIS = [["fatura_sorgu", 1, true, 0.18], ["odeme_alma", 0.35, true, 0.22], ["sayac_degisim", 0.012, false, 0.30], ["yillik_kapanis", 0.00006, false, 0.5], ["dis_dogrulama", 0.12, true, 0.25]]; // [akis, gun, saat, sure dk, tip, ad] export const ARIZA = [ [0, 2, 14, 40, "tam", "gunduz fatura kesintisi"], [0, 4, 3, 120, "tam", "gece fatura kesintisi"], [0, 6, 10, 90, "kismi", "bir abone grubunda hata"], [0, 9, 11, 60, "veri", "onbellek disi yol bozuk"], [1, 3, 20, 75, "tam", "aksam odeme kesintisi"], [1, 7, 2, 180, "tam", "gece odeme kesintisi"], [2, 5, 22, 600, "tam", "hafta sonu sayac degisimi"], [3, 8, 4, 1440, "tam", "yillik kapanis akisi"], [4, 10, 1, 240, "tam", "dis bagimlilik arizasi"], [4, 12, 9, 50, "kismi", "dis dogrulama kismi"], ]; export const pencere = (i) => [ARIZA[i][1] * 1440 + ARIZA[i][2] * 60, ARIZA[i][3]]; export function trafik() { let s = TOHUM; const r = () => ((s = (s * 1664525 + 1013904223) >>> 0) / 2 ** 32); const T = AKIS.map(() => ({ istek: new Float64Array(DK), hata: new Float64Array(DK) })); for (let t = 0; t < DK; t += 1) { const saat = Math.floor(t / 60) % 24, gun = Math.floor(t / 1440) % 7; for (let a = 0; a < AKIS.length; a += 1) { const [, carpan, hepGun] = AKIS[a]; const mesai = hepGun || (saat >= 8 && saat < 18 && gun < 5); const n = SAAT[saat] * carpan * (mesai ? 1 : 0.02) * (0.85 + r() * 0.3); T[a].istek[t] = Math.max(0, Math.floor(n + (r() < n % 1 ? 1 : 0))); let bozuk = 0; for (let i = 0; i < ARIZA.length; i += 1) { const [ak, , , sr, tip] = ARIZA[i], [bas] = pencere(i); if (ak !== a || t < bas || t >= bas + sr) continue; bozuk = Math.max(bozuk, tip === "tam" ? 1 : tip === "kismi" ? AKIS[a][3] : 0.45); } T[a].hata[t] = Math.round(T[a].istek[t] * bozuk); } } return T; } if (import.meta.filename === process.argv[1]) { const T = trafik(); const topla = (a, f, b, e) => { let x = 0; for (let t = b; t < e; t += 1) x += T[a][f][t]; return x; }; console.log(`tohum ${TOHUM}, ${GUN} gun, ${AKIS.length} akis, ${ARIZA.length} ariza\n`); console.log(`${"akis".padEnd(16)}${"gunluk istek".padStart(13)}${"gece 03-05 dk".padStart(14)}` + `${"bos dakika".padStart(12)}`); AKIS.forEach(([ad], a) => { let bos = 0; for (let t = 0; t < DK; t += 1) if (T[a].istek[t] === 0) bos += 1; console.log(`${ad.padEnd(16)}${(topla(a, "istek", 0, DK) / GUN).toFixed(0).padStart(13)}` + `${((topla(a, "istek", 180, 300) + topla(a, "istek", 1620, 1740)) / 240).toFixed(2).padStart(14)}` + `${`%${(bos / DK * 100).toFixed(0)}`.padStart(12)}`); }); }
tohum 20260806, 14 gun, 5 akis, 10 ariza akis gunluk istek gece 03-05 dk bos dakika fatura_sorgu 36899 1.02 %1 odeme_alma 12936 0.35 %12 sayac_degisim 251 0.00 %83 yillik_kapanis 2 0.00 %100 dis_dogrulama 4438 0.11 %24
Tablo üç ayrı körlük gösteriyor. Boş saat: fatura sorgusu günde 36.899 istek alıyor ama gece üç ile beş arasında dakikada 1,02 istek düşüyor. Beş dakikalık bir pencerede bu beş istek eder ve hata oranı hesaplamak için beş istek yetmez; kural çalmaz, çünkü paydanın kendisi yok. Boş akış: sayaç değişimi akışının dakikalarının yüzde 83’ü, yıllık kapanış akışının yüzde 100’ü boştur — yıllık kapanış günde iki istek alıyor. Böyle bir akış aylarca bozuk kalabilir ve hiçbir ölçüt bunu göstermez. Dış bağımlılık: dış doğrulama ucu ancak biz ona istek gönderdiğimizde görünür; o ucun kendi arızası, bizim çağırmadığımız saatlerde ölçütlerimizde yer almaz.
Yoklama ile Trafik Yan Yana
Yoklama her akışa belirli aralıklarla bir istek gönderir ve yanıtı denetler. Üç seçim bu isteği tanımlar: nereden gönderildiği (kullanıcının geldiği yönden, sistemin dışından), hangi akışın koşturulduğu (tek bir uç değil, uçtan uca bir iş), ve ne bıraktığı — yazma yapan bir akış yokladığında sistemde her seferinde bir kayıt kalır, bu yüzden yoklama ya salt okuma yapan bir yol seçer ya da bıraktığını kendisi siler. Aşağıdaki karşılaştırma aynı on arızayı iki yolla ölçüyor.
// sentetik/yoklama.mjs — gercek trafikten dogan kural ile disaridan periyodik yoklama ayni on // ariza uzerinde karsilastirilir. IG33: gercek trafik kurali bes dakikalik pencerede en az 20 // istek gormeden calmaz; hata orani yuzde 5'i asip uc dakika surerse uyarir. IG34: yoklama her P // dakikada bir akis basina bir istek gonderir, ust uste iki basarisiz yoklama uyari uretir. // IG35: yoklama sabit bir sayac kimligi ve tek bir hesapla kosar; bu yuzden "kismi" ve "veri" // tipi arizalarda yoklama gecer. IG36: dis dogrulama ucuna giden her yoklama ucretlidir. import { trafik, AKIS, ARIZA, pencere, DK, GUN } from "./trafik.mjs"; const T = trafik(), MIN = 20, ORAN = 0.05, ARDISIK = 3; function gercekTespit(i) { const ak = ARIZA[i][0], sr = ARIZA[i][3], [bas] = pencere(i); let ard = 0; for (let t = bas; t < bas + sr; t += 1) { let n = 0, h = 0; for (let u = Math.max(0, t - 4); u <= t; u += 1) { n += T[ak].istek[u]; h += T[ak].hata[u]; } if (n >= MIN && h / n > ORAN) { ard += 1; if (ard >= ARDISIK) return t - bas; } else ard = 0; } return null; } // Yoklama yalniz "tam" arizada duser; sabit girdiyle kostugu icin oteki iki tipi gormez (IG35). const yoklamaDuser = (i, t) => { const [, , , sr, tip] = ARIZA[i], [bas] = pencere(i); return tip === "tam" && t >= bas && t < bas + sr; }; function sentetikTespit(i, P) { const [, , , sr] = ARIZA[i], [bas] = pencere(i); let ard = 0; for (let t = Math.ceil(bas / P) * P; t < bas + sr; t += P) { if (yoklamaDuser(i, t)) { ard += 1; if (ard >= 2) return t - bas; } else ard = 0; } return null; } const P0 = 5; console.log(`${"ariza".padEnd(28)}${"akis".padEnd(16)}${"tip".padStart(6)}` + `${"gercek trafik".padStart(15)}${"yoklama (5 dk)".padStart(16)}`); const bic = (x) => (x === null ? "-" : `${x} dk`); ARIZA.forEach(([ak, , , , tip, ad], i) => console.log(`${ad.padEnd(28)}${AKIS[ak][0].padEnd(16)}${tip.padStart(6)}` + `${bic(gercekTespit(i)).padStart(15)}${bic(sentetikTespit(i, P0)).padStart(16)}`)); const g = ARIZA.map((_, i) => gercekTespit(i)), y = ARIZA.map((_, i) => sentetikTespit(i, P0)); const gormedigi = ARIZA.filter((_, i) => g[i] === null); console.log(`\ngercek trafigin hic gormedigi ${gormedigi.length} ariza: ` + `${gormedigi.map((a) => a[5]).join(", ")}`); const yanlisGuven = ARIZA.filter((_, i) => y[i] === null && ARIZA[i][4] !== "tam"); console.log(`yoklamanin gectigi ama kullanicinin etkilendigi ${yanlisGuven.length} ariza: ` + `${yanlisGuven.map((a) => `${a[5]} (${a[4]})`).join(", ")}`); const ikisi = ARIZA.filter((_, i) => g[i] === null && y[i] === null); console.log(`gercek trafik ${g.filter((x) => x !== null).length}/${ARIZA.length}, yoklama ` + `${y.filter((x) => x !== null).length}/${ARIZA.length}, ikisi birlikte ` + `${ARIZA.length - ikisi.length}/${ARIZA.length}`); const gunlukIstek = T.reduce((x, a) => x + [...a.istek].reduce((p, q) => p + q, 0), 0) / GUN; console.log(`\n${"yoklama araligi".padEnd(17)}${"yakalanan".padStart(11)}${"ort. gecikme".padStart(14)}` + `${"yoklama/gun".padStart(13)}${"ucretli/gun".padStart(13)}${"sentetik pay".padStart(14)}` + `${"seyrek akista".padStart(15)}`); for (const P of [1, 5, 15, 60]) { const t = ARIZA.map((_, i) => sentetikTespit(i, P)).filter((x) => x !== null); const gunluk = AKIS.length * (1440 / P), seyrek = [...T[3].istek].reduce((p, q) => p + q, 0) / GUN; console.log(`${`${P} dk`.padEnd(17)}${`${t.length}/${ARIZA.length}`.padStart(11)}` + `${`${(t.reduce((a, b) => a + b, 0) / t.length).toFixed(1)} dk`.padStart(14)}` + `${String(gunluk).padStart(13)}${String(1440 / P).padStart(13)}` + `${`%${(gunluk / (gunlukIstek + gunluk) * 100).toFixed(2)}`.padStart(14)}` + `${`%${((1440 / P) / (seyrek + 1440 / P) * 100).toFixed(1)}`.padStart(15)}`); }
ariza akis tip gercek trafik yoklama (5 dk) gunduz fatura kesintisi fatura_sorgu tam 2 dk 5 dk gece fatura kesintisi fatura_sorgu tam - 5 dk bir abone grubunda hata fatura_sorgu kismi 3 dk - onbellek disi yol bozuk fatura_sorgu veri 2 dk - aksam odeme kesintisi odeme_alma tam 2 dk 5 dk gece odeme kesintisi odeme_alma tam - 5 dk hafta sonu sayac degisimi sayac_degisim tam - 5 dk yillik kapanis akisi yillik_kapanis tam - 5 dk dis bagimlilik arizasi dis_dogrulama tam - 5 dk dis dogrulama kismi dis_dogrulama kismi 2 dk - gercek trafigin hic gormedigi 5 ariza: gece fatura kesintisi, gece odeme kesintisi, hafta sonu sayac degisimi, yillik kapanis akisi, dis bagimlilik arizasi yoklamanin gectigi ama kullanicinin etkilendigi 3 ariza: bir abone grubunda hata (kismi), onbellek disi yol bozuk (veri), dis dogrulama kismi (kismi) gercek trafik 5/10, yoklama 7/10, ikisi birlikte 10/10 yoklama araligi yakalanan ort. gecikme yoklama/gun ucretli/gun sentetik pay seyrek akista 1 dk 7/10 1.0 dk 7200 1440 %11.66 %99.9 5 dk 7/10 5.0 dk 1440 288 %2.57 %99.4 15 dk 7/10 15.0 dk 480 96 %0.87 %98.3 60 dk 6/10 60.0 dk 120 24 %0.22 %93.6
Gerçek trafik on arızanın beşini yakaladı ve yakaladıklarında hızlıydı: gündüz fatura kesintisini 2. dakikada gördü, yoklama aynı arızayı 5. dakikada. Gündüz saatlerinde gerçek trafik yoklamadan üstündür, çünkü dakikada elli isteklik bir örneklem her yoklamadan büyüktür.
Kaçırdığı beş arıza da bir listeye sığıyor: iki gece kesintisi, hafta sonu bozulan sayaç değişimi, yıllık kapanış akışı ve dış bağımlılığın kendi arızası. Beşinin ortak yanı, arıza sırasında o akışa yeterli istek gelmemesidir. Yoklama bu beşinin hepsini yakaladı, çünkü yoklamanın gönderdiği istek saatten ve mevsimden bağımsızdır.
Sıklık ile Maliyet
Sıklık taraması iki eğriyi aynı tabloda tutuyor. Bir dakikalık aralıkta fark etme gecikmesi 1 dakikaya iniyor, ama günde 7.200 yoklama gönderiliyor ve bunların 1.440’ı ücretli dış çağrı. Daha ağır bir bedel sağdaki iki sütunda: sentetik istekler toplam trafiğin yüzde 11,66’sına çıkıyor, seyrek akışta ise yüzde 99,9’una. O akışın gösterge tablosunda görülen her şey artık kendi yoklamamızdır; gerçek kullanım ölçüsü yok olur.
Altmış dakikalık aralıkta maliyet yüzde 0,22’ye iniyor ama yakalanan arıza yediden altıya düşüyor: kırk dakika süren gündüz kesintisi iki ardışık yoklamaya yetişmeden kapanıyor. Yoklama aralığı, görülmek istenen en kısa arızadan küçük olmalıdır — iki ardışık başarısız yoklama koşulu, aralığı iki katına çıkarır.
On beş dakikalık aralık bu taramada dengeyi tutuyor: yedi arıza, 15 dakika gecikme, günde 480 yoklama, 96 ücretli çağrı ve toplam trafiğin yüzde 0,87’si. Seçim yoklama başına maliyetle fark etme gecikmesinin karşılaştırılmasıdır ve akış başına ayrı verilebilir: gece boş kalan akışa sık, gündüz yoğun akışa seyrek yoklama gönderilir, çünkü ikincisini zaten gerçek trafik görür.
Yanlış Güven
Yoklamanın geçtiği hâlde kullanıcının etkilendiği üç arıza var ve ikisinin adı bellidir. Sabit girdili yoklama: yoklama tek bir sayaç kimliği ve tek bir hesapla koşuyor; bir abone grubunu etkileyen bozulmada o hesap etkilenmediği için yoklama geçiyor. Aynı biçim dış doğrulamanın kısmi arızasında da tekrarlanıyor. Önbellekten dönen yoklama: yoklama hep aynı kaydı istediği için yanıt önbellekten geliyor; önbelleğin arkasındaki veri yolu bozukken yoklama yeşil kalıyor.
İki durumun ortak kökü şudur: yoklama, sistemin bir yolunu ölçer, sistemin kendisini değil. Yeşil bir yoklama panosu “her şey çalışıyor” demez, “denenen yol çalışıyor” der. Bu yüzden yoklama gerçek trafiğin yerine geçmez; ikisi birlikte on arızanın onunu kapsıyor, tek başına hiçbiri kapsamıyor.
Özet
- Gerçek trafikten doğan kural, istek gelmeyen yerde çalışmaz: gece dakikada bir isteğe düşen bir akışta beş dakikalık pencere hata oranı hesaplamaya yetmiyor.
- On arızanın beşini gerçek trafik hiç görmedi; hepsinin ortak yanı arıza sırasında o akışa yeterli istek gelmemesiydi (iki gece kesintisi, hafta sonu, yılda birkaç kez kullanılan akış, dış bağımlılığın kendi arızası).
- Yoklama bu beşini de yakaladı ama üç arızayı kaçırdı ve ikisi gündüz trafiğinde gerçek trafikten yavaş kaldı; ikisi birlikte on arızanın onunu kapsıyor.
- Sıklık taraması iki bedeli birlikte gösterdi: bir dakikalık aralık gecikmeyi 1 dakikaya indiriyor ama günde 7.200 yoklama, 1.440 ücretli çağrı ve toplam trafiğin yüzde 11,66’sı ediyor; seyrek akışta ölçütlerin yüzde 99,9’u sentetik hâle geliyor.
- Yoklama aralığı iki ardışık başarısız yoklamayla uyardığı için görülmek istenen en kısa arızanın yarısından küçük seçilir; altmış dakikada kırk dakikalık kesinti kaçıyor.
- Yanlış güvenin iki adı var: sabit girdili yoklama bir abone grubunu etkileyen bozulmayı, önbellekten dönen yoklama veri yolu bozukluğunu göstermez.
Sonraki Adım
Bu konuda sinyal üç aşamadan geçti: bir isteğin servisler arasındaki yolu iz ağacıyla görünür oldu, ortak sözleşmeyle birleştirilebilir hâle geldi, panoda soruya bağlandı, kurallarla süzüldü ve dışarıdan yoklamayla doğrulandı. Zincirin ucunda hep aynı şey duruyor: sinyal bir insanı uyandırıyor. O insanın düzeni ise hiç ele alınmadı. Kim uyanıyor, ayda kaç gece uyanıyor, uyandıktan sonra ne yapacağını nereden okuyor, sabah işi kime devrediyor, ve olay kapandıktan sonra aynı olayın bir daha yaşanmaması için açılan madde gerçekten kapanıyor mu — bunların hiçbiri bir ölçüt kovasında ya da bir panelde durmuyor. Sonraki konu sinyalin bittiği yerden, insanın başladığı yerden devam eder.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.