Ders 16 / 17
İş Sürekliliği ve Felaket Kurtarma
On iki kurtarma kalemi hem planla hem tatbikatla koşturuluyor: plan kritik yolu 260 dakikayla ilan edilen 300 dakikalık hedefin altında kalıyor, tatbikatta ölçülen 421 dakika hedefi 121 dakika aşıyor ve tatbikat raporundaki 293 dakikalık gecikmenin yalnız 161 dakikası kurtarma süresine yansıyor. Altı adam-günlük bütçe rapordaki gecikmeye göre harcandığında kazanç sıfır, kritik yol kazancına göre harcandığında 40 dakika; hedefin altına inmenin bedeli sıralama ölçüsüne göre 32 ile 21 adam-gün arasında değişiyor.
İçindekiler
Önceki üç ders sürekli akan bir şeyi ölçtü ve üçünde de ölçüm olağan işleyiş sürerken yapıldı. Bu dersin konusu olağan işleyişin durduğu andır. Orada elde ölçüm yoktur, plan vardır: hangi hizmetin kaç dakikada ayağa kalkacağı, hangi sıraya göre ve kimin hangi adımı yapacağı yazılıdır. Yazılı olmak doğrulanmış olmak değildir.
Yedek türleri, geri yükleme mekaniği ve kurtarma hedeflerinin tanımı Bilgi Teknolojileri ve Sistem Temelleri kursunda ölçüldü; burada girdi olarak alınır. Bu dersin ölçüsü tek bir farktır: plan ile gerçek arasındaki fark. Üç sayıyla yazılır — tatbikatta kaç kalemin varsayımı tutmuyor, hedef süre ile ölçülen süre arasında kaç dakika var ve o dakikaların hangi kalemden geldiği. Üçüncü soru ilk ikisinden bağımsızdır, çünkü bir kalemin gecikmesi kurtarma süresine yansımayabilir.
- GP19. On iki kurtarma kalemi, bağımlılık grafı, plan süreleri ve tatbikatta tutmayan varsayımlar kurgusal bölgesel ölçüm ağına aittir ve modeldir. Gerçek bir kurtarma yapılmıyor.
- GP20. Bir kalem bütün bağımlılıkları bittikten sonra başlar ve ekipler paralel çalışabilir. Kurtarma ekibinin kişi sayısı sınırlı sayılmadı; sınırlı olsaydı ölçülen süre daha uzun çıkardı.
- GP21. Tutmayan varsayımın eklediği dakika varsayım türüne bağlıdır ve kaleme göre değişmez. Gerçekte aynı varsayım bir kalemde on dakikaya, ötekinde bir saate mal olabilir.
- GP22. Tatbikat bütün kalemleri gerçekten çalıştırır. Masabaşı tatbikatlar bazı varsayımları hiç sınamaz; o durumda tutmayan kalem sayısı olduğundan düşük görünür.
- GP23. Düzeltme maliyeti adam-gün cinsindendir ve kurgudur; düzeltmeler birbirini ucuzlatmaz.
- GP24. Veri kaybı hedefi bu derste ölçülmedi; ölçülen tek şey süredir.
// sureklilik/model.mjs — kurtarma planinin MODELIDIR: kurgu bolgesel olcum aginda on iki // kurtarma kalemi, bagimlilik grafi, plan suresi ve tatbikatta tutmayan varsayimlar. // Gercek bir kurtarma yapilmiyor; yedek turleri ve kurtarma mekanigi girdi olarak alinir. export const HEDEF_DK = 300; // planin ilan ettigi kurtarma hedefi (dakika) // Varsayim turu: tatbikatta tutmadiginda kalemin suresine eklenen dakika ve duzeltme maliyeti export const VARSAYIM = { 'yetkili erisim': { dk: 25, gun: 2 }, 'guncel yordam': { dk: 18, gun: 3 }, 'okunabilir yedek': { dk: 40, gun: 5 }, 'iletisim listesi': { dk: 12, gun: 1 }, 'yedek kapasite': { dk: 30, gun: 8 }, }; // kalem: ad, plan suresi (dk), bagimliliklar, tatbikatta TUTMAYAN varsayimlar export const KALEM = [ { ad: 'yedek guc', plan: 25, dep: [], tutmayan: [] }, { ad: 'ag omurgasi', plan: 35, dep: ['yedek guc'], tutmayan: ['guncel yordam'] }, { ad: 'kimlik hizmeti', plan: 40, dep: ['ag omurgasi'], tutmayan: ['yetkili erisim'] }, { ad: 'veritabani birincil', plan: 60, dep: ['ag omurgasi'], tutmayan: ['okunabilir yedek', 'yetkili erisim'] }, { ad: 'alim hizmeti', plan: 30, dep: ['kimlik hizmeti', 'veritabani birincil'], tutmayan: ['guncel yordam'] }, { ad: 'dogrulama hizmeti', plan: 25, dep: ['alim hizmeti'], tutmayan: [] }, { ad: 'faturalama', plan: 45, dep: ['veritabani birincil', 'dogrulama hizmeti'], tutmayan: ['yedek kapasite'] }, { ad: 'is emri hizmeti', plan: 30, dep: ['kimlik hizmeti', 'veritabani birincil'], tutmayan: ['iletisim listesi', 'guncel yordam'] }, { ad: 'saha uygulamasi', plan: 20, dep: ['is emri hizmeti'], tutmayan: ['okunabilir yedek', 'iletisim listesi'] }, { ad: 'abone portali', plan: 35, dep: ['kimlik hizmeti', 'faturalama'], tutmayan: [] }, { ad: 'gozetim ve gunluk', plan: 20, dep: ['ag omurgasi'], tutmayan: ['yetkili erisim'] }, { ad: 'rapor uretimi', plan: 40, dep: ['faturalama'], tutmayan: ['yedek kapasite'] }, ]; export const gecikme = (t) => t.reduce((a, v) => a + VARSAYIM[v].dk, 0); // Bagimlilik grafinde en gec bitis: sure islevi kalem -> dakika export function bitis(sure) { const b = new Map(); const hesap = (ad) => { if (b.has(ad)) return b.get(ad); const k = KALEM.find((x) => x.ad === ad); const bas = k.dep.reduce((a, d) => Math.max(a, hesap(d)), 0); b.set(ad, bas + sure(k)); return b.get(ad); }; for (const k of KALEM) hesap(k.ad); return b; } export const toplam = (sure) => Math.max(...bitis(sure).values()); export const planSure = (k) => k.plan; export const olculenSure = (kapali = new Set()) => (k) => k.plan + gecikme(k.tutmayan.filter((v) => !kapali.has(`${k.ad}|${v}`))); // Kritik yol: bitis suresi toplama esit olan kalemden geriye dogru export function kritikYol(sure) { const b = bitis(sure), son = Math.max(...b.values()); const yol = []; let ad = [...b.keys()].find((x) => b.get(x) === son); while (ad) { yol.unshift(ad); const k = KALEM.find((x) => x.ad === ad); ad = k.dep.slice().sort((p, q) => b.get(q) - b.get(p))[0]; } return yol; } // Bosluk: kalemin kritik yola girmeden gecikebilecegi dakika export function bosluk(sure) { const b = bitis(sure), son = Math.max(...b.values()); const ardil = new Map(KALEM.map((k) => [k.ad, []])); for (const k of KALEM) for (const d of k.dep) ardil.get(d).push(k.ad); const gec = new Map(); const hesap = (ad) => { if (gec.has(ad)) return gec.get(ad); const a = ardil.get(ad); gec.set(ad, a.length ? Math.min(...a.map((x) => hesap(x) - sure(KALEM.find((z) => z.ad === x)))) : son); return gec.get(ad); }; return new Map(KALEM.map((k) => [k.ad, hesap(k.ad) - b.get(k.ad)])); } export const ADAY = KALEM.flatMap((k) => k.tutmayan.map((v) => ({ kalem: k.ad, varsayim: v, anahtar: `${k.ad}|${v}`, dk: VARSAYIM[v].dk, gun: VARSAYIM[v].gun })));
Rapordaki Gecikme ile Yansıyan Gecikme
// sureklilik/tatbikat.mjs — plan ile gercek arasindaki fark: tutmayan kalem, hedef ile // olculen sure farki ve gecikmenin ne kadarinin kurtarma suresine yansidigi import { KALEM, HEDEF_DK, ADAY, gecikme, toplam, kritikYol, bosluk, planSure, olculenSure } from './model.mjs'; const y = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join('').trimEnd()); const P = toplam(planSure), O = toplam(olculenSure()); const yolP = kritikYol(planSure), yolO = new Set(kritikYol(olculenSure())); const bos = bosluk(olculenSure()); console.log(`${KALEM.length} kurtarma kalemi, ilan edilen hedef ${HEDEF_DK} dk`); console.log(`plan kritik yolu ${P} dk (hedefin ${HEDEF_DK - P} dk altinda), ` + `tatbikatta olculen ${O} dk (hedefi ${O - HEDEF_DK} dk asiyor); fark ${O - P} dk`); console.log(`tutmayan varsayim tasiyan kalem: ` + `${KALEM.filter((k) => k.tutmayan.length).length}/${KALEM.length}, ` + `toplam ${ADAY.length} varsayim, rapordaki gecikme toplami ` + `${KALEM.reduce((a, k) => a + gecikme(k.tutmayan), 0)} dk`); const A = [-20, 7, 9, 10, 10, 9, 9]; console.log('\n1. kalem basina plan, olculen ve bosluk'); y(A, 'kalem', 'plan', 'olculen', 'gecikme', 'kritik', 'bosluk', 'yansiyan'); for (const k of KALEM) { const g = gecikme(k.tutmayan); const tek = toplam(olculenSure(new Set(k.tutmayan.map((v) => `${k.ad}|${v}`)))); y(A, k.ad, k.plan, k.plan + g, g, yolO.has(k.ad) ? 'evet' : 'hayir', bos.get(k.ad), O - tek); } console.log(`\nkritik yol (plan ve tatbikatta ayni): ${yolP.join(' -> ')}`); console.log(`kritik yol disindaki kalemlerin tasidigi gecikme: ` + `${KALEM.filter((k) => !yolO.has(k.ad)).reduce((a, k) => a + gecikme(k.tutmayan), 0)} dk`);
12 kurtarma kalemi, ilan edilen hedef 300 dk plan kritik yolu 260 dk (hedefin 40 dk altinda), tatbikatta olculen 421 dk (hedefi 121 dk asiyor); fark 161 dk tutmayan varsayim tasiyan kalem: 9/12, toplam 12 varsayim, rapordaki gecikme toplami 293 dk 1. kalem basina plan, olculen ve bosluk kalem plan olculen gecikme kritik bosluk yansiyan yedek guc 25 25 0 evet 0 0 ag omurgasi 35 53 18 evet 0 18 kimlik hizmeti 40 65 25 hayir 60 0 veritabani birincil 60 125 65 evet 0 60 alim hizmeti 30 48 18 evet 0 18 dogrulama hizmeti 25 25 0 evet 0 0 faturalama 45 75 30 evet 0 30 is emri hizmeti 30 60 30 hayir 86 0 saha uygulamasi 20 72 52 hayir 86 0 abone portali 35 35 0 hayir 35 0 gozetim ve gunluk 20 45 25 hayir 298 0 rapor uretimi 40 70 30 evet 0 30 kritik yol (plan ve tatbikatta ayni): yedek guc -> ag omurgasi -> veritabani birincil -> alim hizmeti -> dogrulama hizmeti -> faturalama -> rapor uretimi kritik yol disindaki kalemlerin tasidigi gecikme: 132 dk
Üst satırlar planın kâğıt üzerinde hedefini tutturduğunu gösteriyor: kritik yol 260 dakika, ilan edilen hedef 300 dakika, kırk dakika pay var. Tatbikat aynı grafı gerçek sürelerle koşturunca 421 dakika çıkıyor — hedefin 121 dakika üzerinde. On iki kalemin dokuzunda en az bir varsayım tutmuyor.
Asıl ayrım son iki sütunda. Tatbikat raporu 293 dakikalık gecikme yazıyor, ama kurtarma süresine yansıyan gecikme 161 dakikadır. Aradaki 132 dakika, kritik yol dışındaki kalemlerde durur. Gözetim ve günlük kaleminde 298 dakikalık boşluk var; oradaki 25 dakikalık gecikme kurtarma süresini bir dakika bile uzatmaz. Saha uygulamasında 52 dakikalık gecikme ve 86 dakikalık boşluk var; yansıması yine sıfırdır. Bir tatbikat raporunun toplam gecikme satırı, kurtarma süresinin ne kadar uzadığını söylemez.
Yansıyan sütunun kendi içinde de bir tuzak var. Kritik yoldaki beş kalemin tek tek yansıması 18, 60, 18, 30 ve 30 dakikadır; toplamı 156. Oysa hepsi birden düzeltildiğinde kazanç 161 dakikadır. Her tekil ölçüm, o kalem düzeltilince devreye giren ikinci en uzun yol tarafından sınırlanır; dolayısıyla kalemleri tek tek değerlendiren bir liste toplam kazancı olduğundan küçük gösterir.
Kritik yolun plan ile tatbikatta aynı kalması da kayda değer. Gecikmeler büyüktü ama sırayı değiştirecek kadar büyük değildi; planın hangi kalemin darboğaz olduğuna dair varsayımı tuttu, sürelere dair varsayımı tutmadı. İki varsayım ayrı ayrı sınanır ve tatbikat raporunda ayrı ayrı yazılmalıdır.
Aynı Bütçe, Üç Ayrı Sıra
// sureklilik/duzeltme.mjs — tatbikat bulgularini uc ayri olcuyle siralayip ayni butcede kosturur import { HEDEF_DK, ADAY, toplam, planSure, olculenSure } from './model.mjs'; const y = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join('').trimEnd()); const O = toplam(olculenSure()); const marj = (a, k) => toplam(olculenSure(k)) - toplam(olculenSure(new Set([...k, a.anahtar]))); const KURAL = { 'rapor gecikmesi': (a) => a.dk, 'kritik yol kazanci': (a, k) => marj(a, k), 'kazanc/gun': (a, k) => marj(a, k) / a.gun, }; function kosum(ad, butce) { const kural = KURAL[ad], kapali = new Set(); let kalan = butce, n = 0, liste = [...ADAY]; while (kalan > 0 && liste.length) { liste.sort((p, q) => kural(q, kapali) - kural(p, kapali) || p.kalem.localeCompare(q.kalem)); const a = liste.find((x) => x.gun <= kalan); if (!a) break; kalan -= a.gun; kapali.add(a.anahtar); n += 1; liste = liste.filter((x) => x !== a); } return { n, gun: butce - kalan, sure: toplam(olculenSure(kapali)) }; } console.log(`tatbikatta olculen ${O} dk, plan ${toplam(planSure)} dk, hedef ${HEDEF_DK} dk; ` + `${ADAY.length} duzeltme adayi, hepsini kapatmak ${ADAY.reduce((a, x) => a + x.gun, 0)} adam-gun`); const A = [-8, 20, 10, 7, 10, 11]; console.log('\n1. ayni butce, uc ayri siralama olcusu'); y(A, 'butce', 'olcu', 'duzeltme', 'gun', 'sure dk', 'kazanc dk'); for (const B of [6, 12, 20]) for (const ad of Object.keys(KURAL)) { const r = kosum(ad, B); y(A, B, ad, r.n, r.gun, r.sure, O - r.sure); } console.log('\n2. hedefin altina inmek icin gereken en kucuk butce'); for (const ad of Object.keys(KURAL)) { let g = 1; while (g <= 43 && kosum(ad, g).sure > HEDEF_DK) g += 1; console.log(` ${ad.padEnd(20)} ${g} adam-gun`); } console.log('\n3. raporda en buyuk iki gecikme'); for (const a of [...ADAY].sort((p, q) => q.dk - p.dk || p.kalem.localeCompare(q.kalem)).slice(0, 2)) console.log(` ${a.kalem} / ${a.varsayim}: raporda ${a.dk} dk, ${a.gun} adam-gun, ` + `kurtarma suresine yansiyan ${marj(a, new Set())} dk`);
tatbikatta olculen 421 dk, plan 260 dk, hedef 300 dk; 12 duzeltme adayi, hepsini kapatmak 43 adam-gun 1. ayni butce, uc ayri siralama olcusu butce olcu duzeltme gun sure dk kazanc dk 6 rapor gecikmesi 2 6 421 0 6 kritik yol kazanci 2 6 381 40 6 kazanc/gun 3 6 378 43 12 rapor gecikmesi 3 12 381 40 12 kritik yol kazanci 4 12 338 83 12 kazanc/gun 4 12 338 83 20 rapor gecikmesi 4 20 351 70 20 kritik yol kazanci 5 20 308 113 20 kazanc/gun 8 19 320 101 2. hedefin altina inmek icin gereken en kucuk butce rapor gecikmesi 32 adam-gun kritik yol kazanci 25 adam-gun kazanc/gun 21 adam-gun 3. raporda en buyuk iki gecikme saha uygulamasi / okunabilir yedek: raporda 40 dk, 5 adam-gun, kurtarma suresine yansiyan 0 dk veritabani birincil / okunabilir yedek: raporda 40 dk, 5 adam-gun, kurtarma suresine yansiyan 40 dk
İlk satır üçlüsü bu dersin en sert sonucunu taşıyor. Altı adam-günlük bütçe rapordaki gecikme sırasına göre harcandığında iki düzeltme yapılıyor, bütçenin tamamı gidiyor ve kurtarma süresi 421 dakikada kalıyor: kazanç sıfır. Aynı bütçe kritik yol kazancına göre harcandığında 40, kazancı güne bölen sıraya göre 43 dakika kazandırıyor. Üç sıra da aynı on iki adayı, aynı raporu ve aynı bütçeyi kullanıyor.
Nedeni üçüncü blokta yazılı. Raporun en büyük iki gecikmesi de kırk dakikadır ve ikisi de beş adam-güne mal olur; birincisinin kurtarma süresine yansıması 40 dakika, ikincisininki sıfırdır. Rapordaki sayı düzeltmenin değerini vermez; değer ancak kalem bağımlılık grafına konduğunda çıkar.
Yirmi adam-günlük satırda iki akıllı ölçü yer değiştiriyor. On iki adam-güne kadar kritik yol kazancı ile kazanç/gün aynı sonucu verir (338 dakika); yirmi adam-günde kazanç/gün 320 dakikada kalırken kritik yol kazancı 308’e iner. Sıralamanın değiştiği nokta budur: bütçe büyüdükçe ucuz kalemleri öne alan ölçü, pahalı ama tek başına daha çok kazandıran kalemi almaya sıra gelmeden bütçeyi tüketir. Dar bütçede verim ölçüsü, geniş bütçede doğrudan kazanç ölçüsü öndedir.
Son blok kararı tek bir sayıya bağlıyor. Hedefin altına inmek rapordaki gecikme sırasıyla 32, kritik yol kazancıyla 25, kazanç/gün sırasıyla 21 adam-gün tutuyor. Bulgular aynı, plan aynı, ekip aynı — aradaki 11 adam-gün yalnız sıralama ölçüsünden geliyor.
Özet
- Plan kritik yolu 260 dk ile ilan edilen 300 dk’lık hedefin altında kalıyor; tatbikatta ölçülen süre 421 dk ve hedefi 121 dk aşıyor. On iki kalemin dokuzunda en az bir varsayım tutmuyor.
- Tatbikat raporundaki 293 dk’lık gecikmenin yalnız 161 dk’sı kurtarma süresine yansıyor; kalan 132 dk boşluğu olan kalemlerde durur (gözetim ve günlük kaleminde boşluk 298 dk).
- Kritik yoldaki kalemlerin tek tek yansıması toplamda 156 dk, hepsi birden düzeltildiğinde 161 dk: tekil değerlendirme, devreye giren ikinci yol yüzünden kazancı küçük gösterir.
- Kritik yol plan ile tatbikatta aynı kaldı: darboğaz varsayımı tuttu, süre varsayımı tutmadı. İki varsayım ayrı sınanır ve ayrı yazılır.
- Altı adam-gün rapordaki gecikme sırasına göre harcandığında kazanç sıfırdır; kritik yol kazancına göre 40, kazanç/gün sırasına göre 43 dakikadır. Raporun en büyük iki gecikmesi de 40 dk ve 5 adam-gündür; birinin yansıması 40, ötekininki 0 dakikadır.
- Yirmi adam-günde iki ölçü yer değiştiriyor (308’e karşı 320 dk); hedefin altına inmek 32, 25 ve 21 adam-gün tutuyor — 11 adam-günlük fark yalnız sıralama ölçüsünden geliyor.
Sonraki Adım
Dört ders dört ayrı sıralama üretti ve her birinde aynı biçim tekrarlandı: bir kalem kümesi, bir ölçü ve ölçü değiştiğinde değişen bir sıra. Bu dersteki rapor gecikmesi sütunu bunun uç örneğiydi — gerçek bir sayıydı, doğru ölçülmüştü, tatbikat raporunda yazıyordu ve altı adam-günlük bir bütçeyi sıfır kazançla harcattı. Böyle bir sütun yanlış değildir; karar taşımaz. Son ders program ölçütlerinin tamamını bu gözle ayırır: hangi ölçüt bir karara bağlı ve eşiği aşınca ne oluyor, hangisi yalnız rapora giriyor, ve ölçütü toplamanın bedeli ile tetiklediği karar sayısı yan yana yazıldığında liste nasıl kısalıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.