Ders 09 / 15
Yönlendirme Tabloları
Beş yönlendirme tablosu modellenir ve her akış için kazanan satır en uzun önek eşleşmesiyle hesaplanır: geniş yazılmış kural kaç akışı sessizce yutuyor, dar yazılmış kural aynı akışı kaç birim ücretle yutuyor, tek satırın düşmesi kaç örneği ve kaç birimi etkiliyor, aynı kural kaç tabloda tekrarlanıyor.
İçindekiler
Önceki ders beş yönlendirme tablosuyla kapandı ve beş yalnız bir sayıydı. Tabloların içinde bir alt ağdan çıkan paketin nereye gideceği yazılı: bloğun kendi içine mi, eşlenmiş bir ağa mı, özel bir bağlantıya mı, yoksa dışarı mı. Bir paket birden çok satıra uyabilir ve hangisinin kazandığı tek bir kurala bağlıdır — en uzun önek.
Bu kural iki şeyi birden yapıyor. Beklenen tarafı şu: bloğun kendi içine giden trafik, ne kadar geniş yazılmış olursa olsun başka bir satıra kapılmaz. Beklenmeyen tarafı ise satır yazmanın taşıma yeteneği vermemesidir — kazanan satır bir hedefi gösterebilir, o hedef adresi taşımıyor olabilir ve paket geri dönmez. İki taraf aynı tabloda, çoğu zaman aynı satırda durur; ayıran şey satırın yazılışı değil, gösterdiği hedefin gerçekte ne taşıdığıdır.
- BA13. Beş tablo, altı kural ve sekiz akış kurgusal bölgesel ölçüm ağına aittir. Gerçek bir
ağ yönlendirilmiyor; ölçülen şey
nodeile kurulan modeldir. Önek eşleşmesi gerçek adres aritmetiğiyle hesaplanıyor. - BA14. Bütün hedefler özel adres blokları ile belgeleme için ayrılmış bloklardan seçildi.
- BA15. Bir tablo satırı yazmak taşıma kapasitesi vermez; her hedefin gerçekten taşıdığı aralık ayrı modellendi. Gerçekte bu ayrım bağlantının kendi yapılandırmasında durur.
- BA16. Sekiz akış ve dönemlik hacimleri elle yazıldı; rastgelelik yok, her koşum aynı sayıları üretir.
- BA17. Çıkış ücreti yüz hacim birimi başına iki kurgu birim sayıldı. Para birimi değildir; yolların birbirine oranını taşır.
- BA18. Dört alanın özel tablosu birbirinin aynı varsayıldı. Gerçekte alanlar arasında fark olur; tekrar sayısını düşürür, dokunuş sayısını değiştirmez.
Yönlendirme Tablosu Modeli
Model iki şeyi ayrı tutuyor: tabloya yazılan satır ve hedefin gerçekten taşıdığı aralık. TASIR
sözlüğü ikincisidir ve modelin ana iddiası oradadır. sonuc işlevi önce kazanan satırı buluyor,
sonra o satırın gösterdiği hedefin adresi taşıyıp taşımadığına bakıp dört sonuçtan birini
döndürüyor.
// yol.mjs — yonlendirme tablosu modeli ve en uzun onek eslesmesi; gercek ag yok export const toInt = (ip) => ip.split('.').reduce((a, o) => a * 256 + Number(o), 0); export const blok = (c) => { const [ip, e] = c.split('/'); const n = Number(e), b = 2 ** (32 - n); const bas = Math.floor(toInt(ip) / b) * b; return { onek: n, bas, son: bas + b - 1 }; }; export const icinde = (c, ip) => { const b = blok(c), a = toInt(ip); return a >= b.bas && a <= b.son; }; export const OZEL = ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16']; export const ozelMi = (ip) => OZEL.some((c) => icinde(c, ip)); // Hedefin gercekten tasidigi aralik; satir yazmak tasima kapasitesi vermez (BA15). null: her yeri tasir, ucretli. export const TASIR = { 'yerel': ['10.42.0.0/20'], 'esleme-merkez': ['10.0.0.0/16'], 'esleme-yedek': ['10.44.0.0/14'], 'esleme-eski': ['10.8.0.0/14'], 'ozel-baglanti': ['172.20.0.0/14'], 'gecit': null, }; export const en = (t, ip) => t.filter(([c]) => icinde(c, ip)) .sort((a, b) => blok(b[0]).onek - blok(a[0]).onek)[0]; // en uzun onek kazanir export const sonuc = (t, ip) => { const s = en(t, ip); if (!s) return { satir: '-', hedef: '-', son: 'yol yok', ucret: false }; const tas = TASIR[s[1]]; const son = tas === null ? (ozelMi(ip) ? 'gecit-bosa' : 'gecit') : tas.some((c) => icinde(c, ip)) ? 'ulasir' : 'kara delik'; return { satir: s[0], hedef: s[1], son, ucret: son.startsWith('gecit') }; }; const ORTAK = [['10.42.0.0/20', 'yerel'], ['172.20.0.0/14', 'ozel-baglanti'], ['0.0.0.0/0', 'gecit']]; export const KUME = { genis: [...ORTAK, ['10.0.0.0/8', 'esleme-merkez']], dar: [...ORTAK, ['10.0.0.0/16', 'esleme-merkez']], tam: [...ORTAK, ['10.0.0.0/16', 'esleme-merkez'], ['10.44.0.0/14', 'esleme-yedek'], ['10.8.0.0/14', 'esleme-eski']], }; // [ad, hedef adres, donemlik akis hacmi] — kurgusal olcum aginin akislari (BA16) export const AKIS = [ ['ic olcum toplayici', '10.42.3.14', 4200], ['ic veri deposu', '10.42.9.7', 9100], ['merkez salon kaydi', '10.0.4.7', 2600], ['eski olcum arsivi', '10.8.3.1', 340], ['ortak baglanti ucu', '172.20.5.9', 780], ['yedek toplama', '10.44.2.3', 150], ['dis paket deposu', '198.51.100.9', 60], ['dis olcum hizmeti', '203.0.113.4', 1900], ]; export const UCRET = (h) => Math.round(h * 2) / 100; // 100 hacim birimi basina 2 kurgu birim (BA17) export const ALAN = 4;
Üç tablo kümesi aynı iskeletten türüyor: üç ortak satır ve üzerine eşleme kuralının bir biçimi.
genis kümesi tek satırla bütün iç adres alanını kapsamaya çalışıyor, dar kümesi yalnız
gerçekten eşlenmiş aralığı yazıyor, tam kümesi eksik kalan iki hedefi ayrıca ekliyor. Akış
listesinin sekiz satırından ikisi bloğun içine, üçü kurumun başka bloklarına, biri ortak
bağlantıya ve ikisi dışarıya gidiyor; hacimler dönemliktir ve ücreti onlar belirliyor.
Kazanan Satır
// kosum1.mjs — her akis icin kazanan satir cikarilir, sonra uc tablo kumesi karsilastirilir import { KUME, AKIS, UCRET, sonuc, icinde } from './yol.mjs'; console.log(`genis kume (${KUME.genis.length} satir), akis akis kazanan satir:`); console.log(`${'akis'.padEnd(20)} ${'hedef adres'.padEnd(14)} ${'eslesen'.padStart(7)} ` + `${'kazanan satir'.padEnd(14)} ${'yon'.padEnd(14)} sonuc`); for (const [ad, ip] of AKIS) { const es = KUME.genis.filter(([c]) => icinde(c, ip)).length, r = sonuc(KUME.genis, ip); console.log(`${ad.padEnd(20)} ${ip.padEnd(14)} ${String(es).padStart(7)} ` + `${r.satir.padEnd(14)} ${r.hedef.padEnd(14)} ${r.son}`); } console.log(`\n${'kume'.padEnd(7)} ${'satir'.padStart(6)} ${'ulasan'.padStart(7)} ${'kara delik'.padStart(11)} ` + `${'gecit-bosa'.padStart(11)} ${'ucretli hacim'.padStart(14)} ${'cikis ucreti'.padStart(13)}`); for (const [ad, t] of Object.entries(KUME)) { const r = AKIS.map(([, ip, h]) => ({ ...sonuc(t, ip), h })); const n = (s) => r.filter((x) => x.son === s).length; const hacim = r.filter((x) => x.ucret).reduce((a, x) => a + x.h, 0); console.log(`${ad.padEnd(7)} ${String(t.length).padStart(6)} ${String(n('ulasir')).padStart(7)} ` + `${String(n('kara delik')).padStart(11)} ${String(n('gecit-bosa')).padStart(11)} ` + `${String(hacim).padStart(14)} ${String(UCRET(hacim)).padStart(13)}`); }
genis kume (4 satir), akis akis kazanan satir: akis hedef adres eslesen kazanan satir yon sonuc ic olcum toplayici 10.42.3.14 3 10.42.0.0/20 yerel ulasir ic veri deposu 10.42.9.7 3 10.42.0.0/20 yerel ulasir merkez salon kaydi 10.0.4.7 2 10.0.0.0/8 esleme-merkez ulasir eski olcum arsivi 10.8.3.1 2 10.0.0.0/8 esleme-merkez kara delik ortak baglanti ucu 172.20.5.9 2 172.20.0.0/14 ozel-baglanti ulasir yedek toplama 10.44.2.3 2 10.0.0.0/8 esleme-merkez kara delik dis paket deposu 198.51.100.9 1 0.0.0.0/0 gecit gecit dis olcum hizmeti 203.0.113.4 1 0.0.0.0/0 gecit gecit kume satir ulasan kara delik gecit-bosa ucretli hacim cikis ucreti genis 4 4 2 0 1960 39.2 dar 4 4 0 2 2450 49 tam 6 6 0 0 1960 39.2
İlk iki satır kuralın beklenen tarafıdır: blok içine giden trafik üç satıra birden uyuyor ve /20
kazanıyor. 10.0.0.0/8 satırını yazan kişi bunu bozmayacağını biliyordu ve haklıydı. Dördüncü ve
altıncı satır aynı kuralın öteki tarafı. 10.8.3.1 ile 10.44.2.3 de /8 satırına uyuyor, o
satır kazanıyor ve paket eşleme bağlantısına gidiyor — ama o bağlantı yalnız 10.0.0.0/16
aralığını taşıyor. Kazanan satır doğru yazılmış, gösterdiği hedef adresi taşımıyor. Paket gidiyor,
dönmüyor, ücret üretmiyor ve faturada iz bırakmıyor.
Eşleşen sütunu kuralın işleyişini görünür kılıyor: sekiz akışın altısı iki ya da üç satıra birden uyuyor, yalnız ikisi tek satıra. Tabloda hangi satırın kazandığı yazmıyor; kazanan, önek uzunlukları sıralandığında o an belirleniyor. Bunun sonucu şudur: yeni bir satır eklemek var olan hiçbir satırı değiştirmeden bir akışın yolunu değiştirebilir.
Alttaki üç satır asıl karşılaştırmadır. Geniş kümede iki akış sessizce kayboluyor. Kuralı
daraltmak, yani /8 yerine /16 yazmak, kara deliği sıfırlıyor — ama akışları düzeltmiyor,
yalnız varsayılan yola düşürüyor. İkisi de çıkış geçidinden dışarı çıkıyor, özel bir adrese gitmeye
çalışıyor, yine ulaşmıyor ve bu kez dönemde dokuz virgül sekiz birim fazladan ödetiyor: kırk dokuz
birim, geniş kümenin otuz dokuz virgül ikisine karşı.
Dar kümenin bu farkı bir kayıp gibi görünüyor ve değil. Sessiz arıza ücretli arızaya dönüştü; ücretli arızanın bir yerde satırı var. Doğru sonuç üçüncü satırda: iki satır eklemek altı satırlık bir küme yapıyor, sekiz akışın sekizi ulaşıyor ve çıkış ücreti geniş kümenin ücretine iniyor. Kuralı daraltmak düzeltmedi, eksik iki hedefi yazmak düzeltti.
Eksik Satır ve Tekrar
// kosum2.mjs — bes tablonun tekrari, sonra alan-3 tablosundan tek satir dusurulur import { KUME, AKIS, UCRET, ALAN, sonuc } from './yol.mjs'; const GENEL = [['10.42.0.0/20', 'yerel'], ['0.0.0.0/0', 'gecit']]; const TABLO = [['genel', GENEL], ...Array.from({ length: ALAN }, (_, i) => [`ozel-alan-${i + 1}`, KUME.tam])]; const satir = TABLO.reduce((a, [, t]) => a + t.length, 0); const benzersiz = new Set(TABLO.flatMap(([, t]) => t.map((r) => r.join(' ')))); const kacTablo = (r) => TABLO.filter(([, t]) => t.some((x) => x.join(' ') === r.join(' '))).length; const ORNEK_ALAN = 141; // alan basina ozel ornek (onceki dersin dagilimindan) const taban = AKIS.map(([, ip, h]) => ({ ...sonuc(KUME.tam, ip), h })); const tabanUcret = taban.filter((x) => x.ucret).reduce((a, x) => a + x.h, 0); console.log(`${TABLO.length} tablo, ${satir} satir, ${benzersiz.size} benzersiz kural, ${satir - benzersiz.size} tekrar`); console.log(`\nalan-3 tablosundan tek satir dusurulurse (${ORNEK_ALAN} ornek etkilenir):`); console.log(`${'dusen satir'.padEnd(15)} ${'yon'.padEnd(14)} ${'tabloda'.padStart(8)} ${'bozulan'.padStart(8)} ` + `${'yeni sonuc'.padEnd(12)} ${'ucret farki'.padStart(12)}`); for (const r of KUME.tam) { const eksik = KUME.tam.filter((x) => x !== r); const yeni = AKIS.map(([, ip, h]) => ({ ...sonuc(eksik, ip), h })); const bozuk = yeni.filter((x, i) => x.son !== taban[i].son); const ucret = yeni.filter((x) => x.ucret).reduce((a, x) => a + x.h, 0); const fark = UCRET(ucret) - UCRET(tabanUcret); console.log(`${r[0].padEnd(15)} ${r[1].padEnd(14)} ${String(kacTablo(r)).padStart(8)} ` + `${String(bozuk.length).padStart(8)} ${[...new Set(bozuk.map((x) => x.son))].join(',').padEnd(12)} ` + `${String(fark > 0 ? `+${fark.toFixed(1)}` : fark.toFixed(1)).padStart(12)}`); } console.log(`\ndonemlik cikis ucreti (tam kume): ${UCRET(tabanUcret)} birim`); console.log(`yeni alt ag eklenince dokunulan tablo: 1 (iliskilendirme)`); console.log(`yeni hedef ag eklenince dokunulan tablo: ${ALAN} (${ALAN} satir, ayni satir ${ALAN} kez)`); console.log(`yeni alan eklenince: 1 yeni tablo, ${KUME.tam.length} satir, 1 gecit`);
5 tablo, 26 satir, 6 benzersiz kural, 20 tekrar alan-3 tablosundan tek satir dusurulurse (141 ornek etkilenir): dusen satir yon tabloda bozulan yeni sonuc ucret farki 10.42.0.0/20 yerel 5 2 gecit-bosa +266.0 172.20.0.0/14 ozel-baglanti 4 1 gecit-bosa +15.6 0.0.0.0/0 gecit 5 2 yol yok -39.2 10.0.0.0/16 esleme-merkez 4 1 gecit-bosa +52.0 10.44.0.0/14 esleme-yedek 4 1 gecit-bosa +3.0 10.8.0.0/14 esleme-eski 4 1 gecit-bosa +6.8 donemlik cikis ucreti (tam kume): 39.2 birim yeni alt ag eklenince dokunulan tablo: 1 (iliskilendirme) yeni hedef ag eklenince dokunulan tablo: 4 (4 satir, ayni satir 4 kez) yeni alan eklenince: 1 yeni tablo, 6 satir, 1 gecit
En sıradan görünen satır en pahalısı. Yerel yol düşerse blok içi trafik varsayılan yola kayıyor, geçitten dışarı çıkıyor ve dönemde iki yüz altmış altı birim ekliyor — tam kümenin bütün çıkış ücretinin yaklaşık yedi katı. Ölçüm toplayıcısı ile veri deposu arasındaki trafik hem duruyor hem ödeniyor. Varsayılan yolun düşmesi ise ters yönde çalışıyor: ücret otuz dokuz virgül iki birim azalıyor ve iki dış akış yolsuz kalıyor. Fatura düşerken erişim kesiliyor.
Üçüncü sütun bunun neden fark edilmediğini söylüyor. Her satır dört ya da beş tabloda yazılı ve düşürme yalnız bir alanın tablosundan yapıldı: yüz kırk bir örnek etkileniyor, öteki üç alandaki dört yüz yetmiş beş örnek etkilenmiyor. Aynı isteğin dörtte üçü çalışıp dörtte biri çalışmıyor. Bu, tek bir bozuk satırın ürettiği en zor arıza biçimidir — kesintili, tekrar denenince geçen, ve yönlendirme tablosuna değil ağın kendisine yorulan bir arıza.
Tek satırın düşmesi kâğıt üstünde uzak bir olasılık gibi durur, oysa tarama gerçek bir işi modelliyor. Dört özdeş tablo tek elden yazılmaz; biri elle düzeltilir, biri bir şablondan yeniden üretilir, biri arıza sırasında geçici olarak değiştirilip eski hâline getirilmez. Satır eklemenin gerekçesi olur, satırın dört tablonun dördünde de bulunduğunu doğrulamanın gerekçesi olmaz — çünkü hiçbir şey bozulmuş görünmez.
Son üç satır tekrarın faturasını veriyor. Yirmi altı satırın yalnız altısı benzersiz; yirmisi kopya. Yeni bir alt ağ eklemek tek dokunuş istiyor, çünkü alt ağ var olan bir tabloyla ilişkilendiriliyor. Yeni bir hedef ağ eklemek dört dokunuş ve dört özdeş satır istiyor. Dördünden üçünü yazıp birini atlamak yukarıdaki taramanın tam olarak ürettiği duruma çıkıyor.
Geri alınamayan kalem burada satırın kendisi değil. Yönlendirme satırı yazılır, silinir, düzeltilir — bu kursun en kolay geri alınan kalemi budur. Geri alınamayan şey satırın yanlış olduğu dönemde olan şeydir: sessizce yutulan dört yüz doksan hacim birimlik ölçüm bir daha toplanamaz ve ödenmiş iki yüz altmış altı birim geri gelmez. Elde kalan karar üç kalemdir — kural genişliği, tablo sayısı ve hangi alt ağın hangi tabloyla ilişkilendirileceği. Devredilen kalem ikidir: en uzun önek eşleşmesinin kendisi ve yerel yolun her tabloya kendiliğinden yazılması. İkisi de tartışmaya kapalıdır ve yukarıdaki sayıların yarısını onlar üretiyor.
Özet
- En uzun önek eşleşmesi blok içi trafiği koruyor:
10.42.3.14üç satıra uyuyor,/20kazanıyor. Aynı kural ters yönde de çalışıyor —10.0.0.0/8satırı10.8.3.1ve10.44.2.3akışlarını da kazanıyor ve eşleme bağlantısı yalnız10.0.0.0/16taşıdığı için ikisi kara deliğe düşüyor. - Kuralı
/8yerine/16yazmak kara deliği 2’den 0’a indiriyor ama akışları düzeltmiyor: varsayılan yola düşen aynı iki akış dışarı çıkıp yine ulaşmıyor ve dönemlik ücret 39,2 birimden 49 birime çıkıyor. Düzelten şey daraltmak değil, eksik iki hedefi yazmak; 6 satırlık küme sekiz akışın sekizini ulaştırıyor ve ücreti 39,2 birime döndürüyor. - Tek satırın düşmesi eşit bedelde değil: yerel yol +266,0 birim, eşleme satırları +3,0 ile +52,0 arası, varsayılan yol −39,2 birim ve iki akış yolsuz. Ücreti düşüren değişiklik erişimi kesen değişiklikle aynı satırdır.
- 5 tabloda 26 satır var, yalnız 6’sı benzersiz, 20’si kopya. Her kural 4 ya da 5 tabloda yazılı; bir alanın tablosundan düşen satır 141 örneği etkileyip 475 örneği etkilemiyor ve arıza kesintili görünüyor.
- Yeni alt ağ 1 dokunuş, yeni hedef ağ 4 dokunuş ve 4 özdeş satır, yeni alan 1 tablo artı 6 satır artı 1 geçit istiyor. Geri alınamayan kalem satır değil, satırın yanlış olduğu dönemde yutulan 490 hacim birimlik ölçüm ile ödenmiş 266 birimdir.
Sonraki Adım
Son iki koşumda geçit hem çözüm hem fatura olarak geçti: dışarıya çıkan her akış oradan çıktı, yanlış yola düşen her akış oraya düştü ve her yeni alan bir tane daha istedi. Geçidin kendisi hiç ölçülmedi. Sonraki dersin sorusu özel alt ağdaki örneklerin dışarıyla ilişkisini üç düzende sayar: hiç geçit koymamak neyi adıyla engelliyor, tek bir dönüştürme geçidi kaç örneğin trafiğini tek bir noktadan geçirip hangi darboğazı ve hangi arıza noktasını doğuruyor, alan başına geçit koymak bunu kaça bölüp bedeli kaç birime çıkarıyor — ve her örneğe genel adres vermek dışarıdan erişilebilir yüzeyi kaç kaleme çıkarıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.