Ders 08 / 15
Yalıtım
Aynı ağ yedi ayrı bölme şemasıyla kurulur ve bir düğüm düştüğünde erişilen kalem sayılır. Geçit sayısı, geçitten geçen günlük meşru istek ve bölme sayısının erişilen varlığı ne kadar daralttığı birlikte ölçülür; sınırın nereye çizildiğinin bölme sayısından daha belirleyici olduğu gösterilir.
İçindekiler
Önceki ders izin kalemlerini tek tek kaldırdı ve kırk üç yolu günde on bir isteğin bedeliyle kapattı. Ölçümün tamamı bir varsayım üzerinde durdu: kapanan şey bir adımdır, düğümler yerinde kalır. Gerçek bir olayda kapanan şey adım değil düğümdür — bir servis ele geçirilir ve o andan sonra saldırgan o servisin durduğu yerden hareket eder. O yerden nereye gidilebileceği izin kümesiyle değil, ağın şekliyle belirlenir.
Yalıtım, düğümleri bölmelere ayırıp (compartmentalization) bölmeler arasındaki geçişi kısıtlamaktır. Konteynerler kursunda aynı kavram çalışma zamanı sınırları üzerinden ele alınmıştı; burada ölçülen şey mekanizma değil, sonuçtur: bir bölme düştüğünde kaç kaleme erişiliyor. Bu dersin üç sütunu erişilen kalem, geçit sayısı ve geçitten geçen günlük meşru istektir.
- SI12. Bir bölmenin içinde serbest dolaşılır. Düşen düğüm kendi bölmesindeki bütün düğümlere ulaşır; bu, düz bir ağda düğümler arasında ilan edilmemiş bağlantıların da bulunduğu gerçeğini modeller.
- SI13. Bölmeler arasında yalnız geçit üzerinden geçilir. Geçit kümesi meşru akışlardan türetilir: bir akışın adımı bölme sınırını geçiyorsa o adım geçit olarak açılır.
- SI14. Geçit, açıldığı yönde düşen düğüm için de açıktır. Geçidin kendisi bir denetim taşımıyor; taşısaydı bu, önceki iki dersin ölçtüğü şey olurdu.
- SI15. Erişilen kalem, düşen düğümün ulaşabildiği düğüm sayısıdır; düğümün kendisi sayılmaz. Varlık sütunu bunların içinden korunan dört kalemi ayrı sayar.
- SI16. Bölme şemaları seçilmiş model kararlarıdır. Gerçekte bölme sınırı ağ topolojisi, yerleşim ve işletim sınırlarıyla birlikte çizilir; bu ders yalnız sınırın sonucunu ölçer.
Bölme Şemaları ve Geçitler
Dört şema aynı düğüm kümesini farklı biçimde gruplar: tek bölme, dış ile iç ayrımı, dört katmanlı ayrım ve her düğümün kendi bölmesi. Şemaların hiçbiri grafiği değiştirmiyor; değişen tek şey hangi geçişin bir sınırı kestiğidir. Sınırı kesen bir adım meşru bir akışa aitse geçit olarak açık kalır, değilse kapanır — yani bölmeleme kararı, meşru akış listesi tarafından belirlenir. Bu bağımlılık dersin sonunda karşımıza çıkacak sonucun da kaynağıdır.
// ag.mjs — kurgusal bolgesel olcum aginin erisim grafigi ve mesru akislari (model) export const GIRIS = ['saha-uc', 'sube-agi', 'genel-uc', 'bakim-uc']; export const VARLIK = ['olcum-deposu', 'fatura-vt', 'abone-kayit', 'yapilandirma']; export const KENAR = [ ['saha-uc', 'toplayici'], ['saha-uc', 'is-emri'], ['sube-agi', 'toplayici'], ['sube-agi', 'is-emri'], ['sube-agi', 'yonetim'], ['genel-uc', 'toplayici'], ['bakim-uc', 'yonetim'], ['bakim-uc', 'kuyruk'], ['toplayici', 'kuyruk'], ['toplayici', 'olcum-deposu'], ['kuyruk', 'dogrulayici'], ['kuyruk', 'faturalama'], ['dogrulayici', 'olcum-deposu'], ['dogrulayici', 'fatura-vt'], ['faturalama', 'fatura-vt'], ['faturalama', 'abone-kayit'], ['is-emri', 'kuyruk'], ['is-emri', 'abone-kayit'], ['yonetim', 'toplayici'], ['yonetim', 'dogrulayici'], ['yonetim', 'is-emri'], ['yonetim', 'yapilandirma'], ]; // Mesru akis: gunluk kosan is; adim dizisi ayni grafigin kenarlarindan gecer. export const AKIS = [ ['saha-okuma', ['saha-uc', 'toplayici', 'kuyruk'], 1440], ['dogrulama', ['kuyruk', 'dogrulayici', 'olcum-deposu'], 1440], ['genel-okuma', ['genel-uc', 'toplayici', 'olcum-deposu'], 300], ['sube-sorgu', ['sube-agi', 'toplayici', 'olcum-deposu'], 210], ['fatura-yazimi', ['kuyruk', 'faturalama', 'fatura-vt'], 48], ['is-emri-acma', ['sube-agi', 'is-emri', 'abone-kayit'], 32], ['is-emri-kuyruk', ['sube-agi', 'is-emri', 'kuyruk'], 32], ['abone-guncelleme', ['faturalama', 'abone-kayit'], 6], ['yapilandirma-degisikligi', ['sube-agi', 'yonetim', 'yapilandirma'], 2], ['bakim-oturumu', ['bakim-uc', 'yonetim', 'toplayici'], 1], ['kuyruk-bakimi', ['bakim-uc', 'kuyruk'], 1], ['mutabakat', ['yonetim', 'dogrulayici', 'fatura-vt'], 1], ]; export const ad = (a, b) => `${a}>${b}`; export const adimlar = (d) => d.slice(0, -1).map((x, i) => ad(x, d[i + 1])); export function yollar(kapali = new Set()) { const komsu = new Map(); for (const [a, b] of KENAR) if (!kapali.has(ad(a, b))) komsu.set(a, [...(komsu.get(a) || []), b]); const s = []; const yuru = (d, y) => { if (VARLIK.includes(d)) return void s.push(y); for (const k of komsu.get(d) || []) if (!y.includes(k)) yuru(k, [...y, k]); }; for (const g of GIRIS) yuru(g, [g]); return s; } export const kesilen = (kapali) => AKIS.filter(([, d]) => adimlar(d).some((k) => kapali.has(k)));
// bolme.mjs — bolme semalari ve bir dugum dustugunde erisilen kalemin hesabi import { KENAR, AKIS, GIRIS, VARLIK, ad, adimlar } from './ag.mjs'; export const DUGUM = [...new Set(KENAR.flat())]; export const ARA = DUGUM.filter((d) => !GIRIS.includes(d) && !VARLIK.includes(d)); const SERVIS = ['toplayici', 'kuyruk', 'dogrulayici', 'faturalama', 'is-emri']; const kur = (f) => Object.fromEntries(DUGUM.map((d) => [d, f(d)])); export const SEMA = [ ['tek-bolme', kur(() => 'ag')], ['iki-bolme', kur((d) => (GIRIS.includes(d) ? 'dis' : 'ic'))], ['dort-bolme', kur((d) => (GIRIS.includes(d) ? 'dis' : SERVIS.includes(d) ? 'servis' : d === 'yonetim' ? 'yonetim' : 'veri'))], ['dugum-basina', kur((d) => d)], ]; const MESRU = new Set(AKIS.flatMap(([, d]) => adimlar(d))); // Bir bolmenin icinde serbest dolasilir; bolmeler arasi yalniz acik gecitten gecilir. export function cozumle(harita) { const capraz = KENAR.map(([a, b]) => ad(a, b)).filter((k) => harita[k.split('>')[0]] !== harita[k.split('>')[1]]); const gecit = capraz.filter((k) => MESRU.has(k)), uye = {}, komsu = new Map(); for (const d of DUGUM) (uye[harita[d]] ||= []).push(d); for (const g of gecit) { const [a, b] = g.split('>'); komsu.set(harita[a], [...(komsu.get(harita[a]) || []), harita[b]]); } const erisilen = (d) => { const gor = new Set([harita[d]]), yig = [harita[d]]; while (yig.length) for (const x of komsu.get(yig.pop()) || []) if (!gor.has(x)) { gor.add(x); yig.push(x); } return [...gor].flatMap((b) => uye[b]).filter((x) => x !== d); }; return { gecit, kapali: capraz.filter((k) => !MESRU.has(k)), erisilen }; }
// kosum1.mjs — sema sema: gecit sayisi, erisilen kalem ve gecitten gecen mesru istek import { AKIS, VARLIK, adimlar } from './ag.mjs'; import { SEMA, ARA, cozumle } from './bolme.mjs'; const ort = (a) => (a.reduce((s, x) => s + x, 0) / a.length).toFixed(1); console.log('sema bolme gecit kapali ort kalem en kotu ort varlik gecit istek'); for (const [nm, harita] of SEMA) { const { gecit, kapali, erisilen } = cozumle(harita); const er = ARA.map(erisilen); const gi = AKIS.filter(([, d]) => adimlar(d).some((k) => gecit.includes(k))).reduce((s, [, , n]) => s + n, 0); console.log(`${nm.padEnd(14)}${String(new Set(Object.values(harita)).size).padEnd(7)}${String(gecit.length).padEnd(7)}` + `${String(kapali.length).padEnd(8)}${ort(er.map((s) => s.length)).padEnd(11)}` + `${String(Math.max(...er.map((s) => s.length))).padEnd(9)}` + `${ort(er.map((s) => s.filter((x) => VARLIK.includes(x)).length)).padEnd(12)}${gi}`); }
sema bolme gecit kapali ort kalem en kotu ort varlik gecit istek tek-bolme 1 0 0 13.0 13 4.0 0 iki-bolme 2 7 1 9.0 9 4.0 2018 dort-bolme 4 16 2 8.2 9 4.0 3513 dugum-basina 14 20 2 4.8 8 2.8 3513
Birinci satır bölmesiz ağın ölçüsüdür. Hangi servis düşerse düşsün diğer on üç düğümün tamamına ve dört varlığın dördüne erişiliyor. Düz ağda “hangi servis ele geçirildi” sorusunun cevabı sonucu değiştirmez; ele geçirilen her düğüm aynı yarıçapı açar.
İkinci satır ilk bölme sınırını çiziyor ve ortalama erişilen kalem on üçten dokuza iniyor — yüzde otuz bir daralma. Ancak varlık sütunu kıpırdamıyor: hâlâ dört. Sınır giriş noktalarını içeriden ayırdı, ama bütün varlıklar içeride kaldı. Yedi geçit açıldı ve günde iki bin on sekiz istek bu geçitlerden geçer oldu. Yalıtımın bedeli ödendi, korunan kalem sayısı değişmedi.
Üçüncü satır bu dersin en pahalı satırıdır. Dört bölme on altı geçit gerektiriyor ve günlük meşru isteğin tamamı, üç bin beş yüz on üçü, en az bir geçitten geçiyor. Karşılığında ortalama erişilen kalem dokuzdan sekiz virgül ikiye iniyor ve varlık sayısı yine dört. Dokuz ek geçit sıfır virgül sekiz kalem satın aldı. Bölme sayısını artırmak tek başına yalıtım üretmiyor.
Son satır neyin işe yaradığını gösteriyor. Her düğüm kendi bölmesindeyken ortalama erişilen kalem dört virgül sekize, erişilen varlık iki virgül sekize iniyor. Varlık sütunu ancak burada kıpırdıyor. Fark bölme sayısından değil, geçitlerin taneciğinden geliyor: dört bölmede servis bölmesinden veri bölmesine açılan bir geçit, o bölmedeki bütün varlıkları açıyordu; düğüm başına şemada aynı geçit yalnız bir varlığa açılıyor.
Düşen Düğüm Başına Yarıçap
Ortalama tek başına yanıltıcıdır. Aynı ölçüm düğüm düğüm yapıldığında hangi düğümün daraldığı ve hangisinin daralmadığı görünür.
// kosum2.mjs — dusen dugum basina erisilen kalem; sema degistikce nasil daraliyor import { VARLIK } from './ag.mjs'; import { SEMA, ARA, cozumle } from './bolme.mjs'; const c = SEMA.map(([nm, h]) => [nm, cozumle(h)]); console.log(`dusen dugum ${c.map(([nm]) => nm.split('-')[0].padEnd(9)).join('')}`); for (const d of ARA) console.log(`${d.padEnd(14)}${c.map(([, x]) => String(x.erisilen(d).length).padEnd(9)).join('')}`); console.log('\nayni satirlar yalniz varlik sayilarak:'); for (const d of ARA) console.log(`${d.padEnd(14)}${c.map(([, x]) => String(x.erisilen(d).filter((y) => VARLIK.includes(y)).length).padEnd(9)).join('')}`); const son = c[3][1]; console.log(`\ndugum basina semada en genis yaricap: ${ARA.map((d) => [d, son.erisilen(d).length]).sort((a, b) => b[1] - a[1])[0].join(' -> ')} kalem`);
dusen dugum tek iki dort dugum toplayici 13 9 8 6 is-emri 13 9 8 6 yonetim 13 9 9 8 kuyruk 13 9 8 5 dogrulayici 13 9 8 2 faturalama 13 9 8 2 ayni satirlar yalniz varlik sayilarak: toplayici 4 4 4 3 is-emri 4 4 4 3 yonetim 4 4 4 4 kuyruk 4 4 4 3 dogrulayici 4 4 4 2 faturalama 4 4 4 2 dugum basina semada en genis yaricap: yonetim -> 8 kalem
İlk iki sütun tamamen düzdür: bölmesiz ve iki bölmeli şemada hangi düğümün düştüğü fark etmiyor. Ayrım ancak son sütunda açılıyor. Doğrulayıcı ve faturalama düştüğünde erişilen kalem on üçten ikiye iniyor; bu iki servis grafiğin sonuna yakın durur ve arkalarında yalnız yazdıkları varlıklar vardır. Ölçüm toplayıcısı ve iş emri servisi altıya, kuyruk beşe iniyor.
Yönetim istasyonu inmiyor. Dört bölmeli şemada dokuz, düğüm başına şemada sekiz kalem — ve varlık sütununda dört, yani şema ne olursa olsun bütün varlıklara erişiliyor. Nedeni geçit kümesinin nereden türediğidir: yönetim istasyonunun meşru işi zaten toplayıcıya, doğrulayıcıya, iş emri servisine ve yapılandırma deposuna dokunmaktır. Geçitler meşru akışlardan türediği için, meşru işi geniş olan düğümün geçitleri de geniştir.
Bu, yalıtımın yapısal sınırıdır: bölmelere ayırma, meşru işi dar olan düğümleri daraltır, geniş olanları daraltmaz. Ele geçirilmesi en pahalıya mal olacak düğüm, yalıtımdan en az yararlanan düğümdür. Aynı gözlem bir karara da çevrilebilir — yönetim düğümünün yarıçapını daraltmanın yolu bölme eklemek değil, o düğümün meşru işini bölmektir: bakım işini yapan özne ile yapılandırma değiştiren öznenin ayrı düğümlere konması, sekiz kalemi iki ayrı ve daha küçük kümeye böler.
Şemaların bedeli de bu tabloyla birlikte okunmalıdır. Düğüm başına şema yirmi geçit gerektiriyor ve bu geçitlerin her biri elle yazılan, meşru akış değiştikçe güncellenmesi gereken bir kalemdir. Günlük üç bin beş yüz on üç isteğin tamamı en az bir geçitten geçiyor; her geçit hem bir işletim kalemi hem de bir arıza noktasıdır. Ortalama erişilen kalemi on üçten dört virgül sekize indirmenin fiyatı budur ve bu fiyat, bir olay yaşanmadığı sürece hiçbir yerde görünmez.
Sınırın Yeri
Bölme sayısı tek başına belirleyici değilse sınırın nereye çizildiği belirleyicidir. Üç şema aynı soruyu farklı yanıtlıyor: sınır varlıkların etrafına mı, varlıkların arasına mı, yoksa servislerin arasına mı çizilmeli?
// kosum3.mjs — sinirin yeri: ayni sayida bolme farkli yerlere konursa ne degisiyor import { AKIS, GIRIS, VARLIK, adimlar } from './ag.mjs'; import { DUGUM, ARA, cozumle } from './bolme.mjs'; const kur = (f) => Object.fromEntries(DUGUM.map((d) => [d, f(d)])); const ort = (a) => (a.reduce((s, x) => s + x, 0) / a.length).toFixed(1); const YER = [ ['varlik-etrafinda', kur((d) => (VARLIK.includes(d) ? 'veri' : 'geri'))], ['varlik-basina', kur((d) => (VARLIK.includes(d) ? d : 'geri'))], ['servis-basina', kur((d) => (VARLIK.includes(d) ? 'veri' : GIRIS.includes(d) ? 'dis' : d))], ]; console.log('sema bolme gecit ort kalem ort varlik gecit istek'); for (const [nm, harita] of YER) { const { gecit, erisilen } = cozumle(harita), er = ARA.map(erisilen); const gi = AKIS.filter(([, d]) => adimlar(d).some((k) => gecit.includes(k))).reduce((s, [, , n]) => s + n, 0); console.log(`${nm.padEnd(18)}${String(new Set(Object.values(harita)).size).padEnd(7)}${String(gecit.length).padEnd(7)}` + `${ort(er.map((s) => s.length)).padEnd(11)}${ort(er.map((s) => s.filter((x) => VARLIK.includes(x)).length)).padEnd(12)}${gi}`); }
sema bolme gecit ort kalem ort varlik gecit istek varlik-etrafinda 2 7 13.0 4.0 2039 varlik-basina 5 7 13.0 4.0 2039 servis-basina 8 20 6.0 4.0 3513
İlk iki satır sıfır kazanç veriyor. Bütün varlıkları tek bir bölmeye koymak da her varlığa ayrı bölme vermek de ortalama erişilen kalemi on üçte, erişilen varlığı dörtte bırakıyor. Neden geçit kuralından çıkıyor: servislerin hepsi aynı bölmede kaldığı için biri düştüğünde hepsine erişiliyor, ve her varlığa giden geçit o ortak bölmeden açık olduğu için varlıkların hepsine de erişiliyor. Beş bölmeli şema iki bölmeli şemadan farksızdır — üç ek sınır çizildi, hiçbir yol daralmadı. Yalıtımı bölme sayısıyla raporlamak burada tamamen yanıltıcıdır.
Üçüncü satır bir kazanç gösteriyor ama beklenen kazancı değil. Servisleri ayırmak ortalama erişilen kalemi on üçten altıya indiriyor; yan hareket gerçekten daraldı. Erişilen varlık yine dört, çünkü her servis kendi meşru işi için ortak veri bölmesine geçit alıyor ve o bölmenin içinde serbest dolaşılıyor. Yirmi geçit ve günlük isteğin tamamı ödendi, korunan varlık sayısı değişmedi.
Üç satır birlikte okunduğunda kural görünür oluyor: yan hareketi servis sınırı daraltır, varlık erişimini varlık sınırı daraltır ve ikisi birbirinin yerine geçmez. Düğüm başına şemanın erişilen varlığı iki virgül sekize indirmesinin nedeni ikisini birden yapmasıdır. Bir yalıtım kararının ölçüsü kaç bölme kurulduğu değil, hangi iki kalem çiftinin arasına sınır konduğudur.
Özet
- Düz ağda hangi servis düşerse düşsün diğer 13 düğüme ve 4 varlığın tamamına erişiliyor. Bölmesiz bir ağda “hangi düğüm ele geçirildi” sorusu sonucu değiştirmez.
- İki bölme ortalama erişilen kalemi 13’ten 9’a indiriyor (%31) ama erişilen varlık 4’te kalıyor; 7 geçit ve günde 2.018 istek karşılığında korunan varlık sayısı değişmedi.
- Dört bölme 16 geçit ve günlük isteğin tamamı karşılığında ortalamayı yalnız 9’dan 8,2’ye indiriyor. Bölme sayısını artırmak tek başına yalıtım üretmiyor.
- Erişilen varlık ancak düğüm başına bölmede kıpırdıyor: ortalama 4’ten 2,8’e. Belirleyici olan bölme sayısı değil, geçidin taneciğidir.
- Yönetim istasyonu hiçbir şemada daralmıyor: 8 kalem ve 4 varlık. Geçitler meşru akıştan türediği için meşru işi geniş olan düğüm yalıtımdan yararlanamaz.
- Düğüm başına şemanın bedeli 20 elle yönetilen geçit ve günde 3.513 isteğin geçitten geçmesidir; bu bedel bir olay yaşanmadığı sürece görünmez.
Sonraki Adım
Bu ders ağı bölmelere ayırdı ve bir bölmenin düşmesinin kaç kaleme eriştiğini saydı. Bölmelerin tamamı aynı sessiz kuralla çalıştı: bir bölmenin içinde serbest dolaşılır. Erişilen kalem sayısının on üçten başlamasının nedeni de buydu — düz ağda içeride olmak, geçmek için yeterli sayılıyordu. Bölme eklemek bu kuralı kaldırmadı, yalnız kuralın geçerli olduğu alanı küçülttü; her şemada içeride olmak hâlâ bir ayrıcalıktı ve geçitler o ayrıcalığı bölmeden bölmeye taşıdı. Sonraki dersin sorusu bu kuralın kendisidir: konuma bakarak verilen güven tamamen kaldırılır ve her adım, nereden geldiğine bakılmaksızın ayrı ayrı doğrulanırsa yol sayısı ne oluyor, erişilen kalem nereye iniyor ve her isteğin ayrı doğrulanması günlük istek başına kaç ek adım ediyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.