Ders 07 / 16
DNS Yönetimi
Bölge dosyasını bir envanter olarak saymak, öksüz kayıtların bıraktığı devralma yüzeyi ve yaşam süresini bir karar olarak ölçmek: yayılma penceresi, geri alma hızı ve sorgu yükü.
İçindekiler
İsteğin yolu kuruldu: bağlantı bir noktada sonlandırıldı, başlıklar arkaya aktarıldı, yanıt önbellekten döndü. Bütün bu zincir boyunca hiç sorulmayan bir soru var — istek hangi ada geldi ve o ad kime ait?
Ad, makineden önce gelir. Bir istemci adresi değil adı bilir; adresi bir başkasından öğrenir ve öğrendiği yanıtı bir süre saklar. Bu iki cümle, alan adı kayıtlarını bir yapılandırma ayrıntısı olmaktan çıkarıp ölçülecek bir yüzey haline getirir. Bu ders o yüzeyi iki eksende sayar: bölge dosyası bir envanterdir ve envanterin gerçeklikten kayması sayılabilir bir açıklık bırakır; yaşam süresi ise kurulumdan kalma bir varsayılan değil, üç değeri aynı anda belirleyen bir karardır.
Kayıt türlerinin ne olduğu — adres, takma ad, posta, ad sunucusu, metin — Bilgisayar Ağları kursunda kuruldu. Burada türler adıyla anılır, yeniden tanımlanmaz; ölçülen şey türün tanımı değil, kaydın bakım durumu ve süresidir.
Bölge Bir Envanterdir
Bir bölge, yetkili sunucunun sorumlu olduğu kayıtlar bütünüdür. İşletme tarafında ise bir şeyden daha fazlasıdır: bölgede yazılı her hedef, bir zamanlar var olduğu varsayılan bir şeye işaret eder. Sistemler taşınır, denemeler kapatılır, dış hizmetlerle sözleşme biter — kayıt kalır.
Aşağıdaki program bölgesel ölçüm ağının bölgesini model olarak kurar. Ağ kurgudur: su sayacı okumalarını toplayan bir toplayıcı, bir doğrulayıcı, faturalama ve iş emri servisleri. Model iki listeyi ayrı tutar; bölgede yazan hedefler ve gerçekten ayakta olan adresler.
AK1. Bölge tek bir yetkili küme altındadır ve kayıtlar elle yönetilir. AK2. Canlı envanter bölgeden bağımsız tutulur; iki listeyi eşleyen bir süreç yoktur.
// Model: bölgesel ölçüm ağının kurgu bölgesi. Gerçek bir bölge değil; kayıtların // ad, tür, yaşam süresi ve hedef alanlarını taşıyan bir veri yapısı. const BOLGE = [ { ad: 'olcumag.gecersiz', tur: 'NS', ttl: 86400, hedef: 'ad1.olcumag.gecersiz' }, { ad: 'olcumag.gecersiz', tur: 'NS', ttl: 86400, hedef: 'ad2.olcumag.gecersiz' }, { ad: 'olcumag.gecersiz', tur: 'A', ttl: 3600, hedef: '198.51.100.10' }, { ad: 'olcumag.gecersiz', tur: 'MX', ttl: 3600, hedef: 'posta.olcumag.gecersiz' }, { ad: 'olcumag.gecersiz', tur: 'TXT', ttl: 3600, hedef: '(metin)' }, { ad: 'www.olcumag.gecersiz', tur: 'CNAME', ttl: 3600, hedef: 'olcumag.gecersiz' }, { ad: 'posta.olcumag.gecersiz', tur: 'A', ttl: 3600, hedef: '198.51.100.20' }, { ad: 'ad1.olcumag.gecersiz', tur: 'A', ttl: 86400, hedef: '198.51.100.2' }, { ad: 'ad2.olcumag.gecersiz', tur: 'A', ttl: 86400, hedef: '198.51.100.3' }, { ad: 'toplayici.olcumag.gecersiz', tur: 'A', ttl: 300, hedef: '198.51.100.11' }, { ad: 'dogrulayici.olcumag.gecersiz', tur: 'A', ttl: 300, hedef: '198.51.100.12' }, { ad: 'faturalama.olcumag.gecersiz', tur: 'A', ttl: 3600, hedef: '198.51.100.13' }, { ad: 'isemri.olcumag.gecersiz', tur: 'A', ttl: 3600, hedef: '198.51.100.14' }, { ad: 'saha.olcumag.gecersiz', tur: 'CNAME', ttl: 300, hedef: 'isemri.olcumag.gecersiz' }, { ad: 'pano.olcumag.gecersiz', tur: 'CNAME', ttl: 3600, hedef: 'eski-pano.olcumag.gecersiz' }, { ad: 'prova.olcumag.gecersiz', tur: 'A', ttl: 86400, hedef: '198.51.100.71' }, { ad: 'deneme.olcumag.gecersiz', tur: 'A', ttl: 86400, hedef: '198.51.100.72' }, { ad: 'rapor.olcumag.gecersiz', tur: 'CNAME', ttl: 3600, hedef: 'gecici.disarisi.gecersiz' }, ]; // Canlı envanter: şu an gerçekten ayakta olan adresler. const CANLI_ADRES = new Set([ '198.51.100.2', '198.51.100.3', '198.51.100.10', '198.51.100.11', '198.51.100.12', '198.51.100.13', '198.51.100.14', '198.51.100.20', ]); const ICBOLGE = 'olcumag.gecersiz'; function cozumle(ad, derinlik = 0) { if (derinlik > 8) return { durum: 'dongu' }; if (!ad.endsWith(ICBOLGE)) return { durum: 'bolge-disi' }; const adres = BOLGE.find((k) => k.ad === ad && k.tur === 'A'); if (adres) { return CANLI_ADRES.has(adres.hedef) ? { durum: 'canli', adres: adres.hedef } : { durum: 'olu-adres', adres: adres.hedef }; } const takma = BOLGE.find((k) => k.ad === ad && k.tur === 'CNAME'); if (takma) return cozumle(takma.hedef, derinlik + 1); return { durum: 'kayit-yok' }; } const turDagilimi = {}; const ttlDagilimi = {}; for (const k of BOLGE) { turDagilimi[k.tur] = (turDagilimi[k.tur] || 0) + 1; ttlDagilimi[k.ttl] = (ttlDagilimi[k.ttl] || 0) + 1; } console.log('toplam kayit:', BOLGE.length); console.log('gorunur ad :', new Set(BOLGE.map((k) => k.ad)).size); console.log('tur dagilimi:', Object.entries(turDagilimi).map(([t, n]) => `${t}=${n}`).join(' ')); console.log('ttl dagilimi:', Object.keys(ttlDagilimi).map(Number).sort((a, b) => a - b) .map((t) => `${t}s=${ttlDagilimi[t]}`).join(' ')); const hedefli = BOLGE.filter((k) => k.tur !== 'TXT'); const oksuz = []; for (const k of hedefli) { const s = /^\d/.test(k.hedef) ? (CANLI_ADRES.has(k.hedef) ? { durum: 'canli' } : { durum: 'olu-adres' }) : cozumle(k.hedef); if (s.durum !== 'canli') oksuz.push({ ...k, durum: s.durum }); } console.log('\noksuz kayit:', oksuz.length, '/', hedefli.length); for (const k of oksuz) { console.log(` ${k.ad.padEnd(26)} ${k.tur.padEnd(5)} -> ${k.hedef.padEnd(26)} ${k.durum}`); } const devralinabilir = oksuz.filter((k) => k.durum === 'kayit-yok' || k.durum === 'bolge-disi'); console.log('\nbaskasinin talep edebilecegi bos hedef:', devralinabilir.length); console.log('bu hedeflerden bolge disinda olan :', oksuz.filter((k) => k.durum === 'bolge-disi').length);
toplam kayit: 18 gorunur ad : 14 tur dagilimi: NS=2 A=10 MX=1 TXT=1 CNAME=4 ttl dagilimi: 300s=3 3600s=9 86400s=6 oksuz kayit: 4 / 17 pano.olcumag.gecersiz CNAME -> eski-pano.olcumag.gecersiz kayit-yok prova.olcumag.gecersiz A -> 198.51.100.71 olu-adres deneme.olcumag.gecersiz A -> 198.51.100.72 olu-adres rapor.olcumag.gecersiz CNAME -> gecici.disarisi.gecersiz bolge-disi baskasinin talep edebilecegi bos hedef: 2 bu hedeflerden bolge disinda olan : 1
Varsayılanın bıraktığı ilk kalem burada: on yedi hedefli kaydın dördü artık var olmayan bir
şeyi gösteriyor. İki tanesi ölü adrese işaret ediyor; bunlar yalnızca gürültü, çözümleme sonunda
bağlantı kurulamaz. Diğer ikisi farklıdır ve öksüz kayıt adını asıl bunlar hak eder: kayıt
boş bir ada işaret eder, o ad da kimseye ait değildir. Adı kim önce alırsa, olcumag.gecersiz
altındaki bir alt ad onun sunduğu içeriği göstermeye başlar. Bu, kaydın devralınmasıdır;
tarayıcı açısından içerik hâlâ ölçüm ağının adı altındadır. Bölge dışına işaret eden kayıt daha
ağırdır, çünkü o adı almak için ölçüm ağının hiçbir sistemine dokunmak gerekmez.
Bölgenin kendisinin ikinci bir yüzeyi de sayıda görünüyor: on dört görünür ad. Bölgede yazılı her ad, ağın iç yapısını okunabilir kılar — hangi servisler var, hangi ortam ayrı duruyor. Kayıt adları bir keşif kaynağıdır ve bu kalem kapatılamaz; bölge yayınlanmak için vardır.
Yaşam Süresi Bir Karardır
Her kaydın bir yaşam süresi vardır ve kurulum sırasında çoğu kayda dokunulmaz. Oysa bu tek sayı üç ayrı şeyi birden belirler: bir değişikliğin yayılma penceresi (eski yanıt ne kadar dolaşımda kalır), hatalı bir değişikliğin geri alma hızı ve yetkili sunucuya düşen sorgu yükü. Üçü aynı yönde iyileşmez; süre düşürüldüğünde ilk ikisi kazanır, üçüncüsü kaybeder.
AK3. Kaydı 240 çözümleyici önbelleği sürekli talep eder; değişiklik anında her önbellekteki kopyanın yaşı süre içinde düzgün dağılmıştır. AK4. Yetkili sunucuya düşen yük yalnız önbellek yenilemesinden gelir.
// Model: yaşam süresi taraması. Değişiklik anında her önbellekteki kopyanın yaşı // [0, ttl) aralığındadır; kalan süre boyunca eski yanıt dolaşımda kalır. const ONBELLEK = 240; // kurgu çözümleyici önbelleği sayısı const TOHUM = 4242; // üreteç tohumu görünürdür function uretec(tohum) { let x = tohum % 2147483647; return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; }; } function pencere(ttl) { const rast = uretec(TOHUM); const kalan = []; for (let i = 0; i < ONBELLEK; i++) kalan.push(Math.round(ttl * (1 - rast()))); kalan.sort((a, b) => a - b); const y = (p) => kalan[Math.min(kalan.length - 1, Math.floor(kalan.length * p))]; const eskiKalan = (t) => kalan.filter((k) => k > t).length; return { p50: y(0.50), p95: y(0.95), enUzun: kalan[kalan.length - 1], besDakika: eskiKalan(300), birSaat: eskiKalan(3600), gunlukSorgu: Math.round(ONBELLEK * (86400 / ttl)), }; } const sure = (s) => (s < 90 ? `${s}s` : s < 5400 ? `${(s / 60).toFixed(0)}dk` : `${(s / 3600).toFixed(1)}sa`); console.log('onbellek sayisi:', ONBELLEK, '| tohum:', TOHUM); console.log('ttl yayilma p50 yayilma p95 en uzun 5dk sonra eski 1sa sonra eski gunluk sorgu'); for (const ttl of [60, 300, 900, 3600, 21600, 86400]) { const o = pencere(ttl); console.log( sure(ttl).padEnd(9) + sure(o.p50).padEnd(13) + sure(o.p95).padEnd(13) + sure(o.enUzun).padEnd(10) + `${o.besDakika}/${ONBELLEK}`.padEnd(16) + `${o.birSaat}/${ONBELLEK}`.padEnd(16) + String(o.gunlukSorgu), ); }
onbellek sayisi: 240 | tohum: 4242 ttl yayilma p50 yayilma p95 en uzun 5dk sonra eski 1sa sonra eski gunluk sorgu 60s 29s 55s 60s 0/240 0/240 345600 5dk 2dk 5dk 5dk 0/240 0/240 69120 15dk 7dk 14dk 15dk 156/240 0/240 23040 60dk 29dk 55dk 60dk 215/240 0/240 5760 6.0sa 2.9sa 5.5sa 6.0sa 233/240 202/240 960 24.0sa 11.6sa 22.0sa 23.9sa 239/240 230/240 240
Tabloda ödünleşim tek satırda okunur. Bir günlük sürede bir adres değişikliği yapıldığında önbelleklerin 230’u bir saat sonra hâlâ eski yanıtı verir; en uzun bekleyen yaklaşık yirmi dört saat sürer. Beş dakikalık sürede aynı değişiklik beş dakikada tamamlanır, bedeli günde 240 yerine 69.120 sorgudur — 288 kat. Aradaki değerler doğrusaldır: süre yarıya inince pencere yarıya iner, sorgu iki katına çıkar.
Buradan çıkan kural sürenin kendisi değil, kaydın değişme olasılığıdır. Ad sunucusu kayıtları yıllarca değişmez; onlarda uzun süre doğru karardır ve sorgu yükünü düşürür. Adres kayıtları taşınmaya konudur. Modeldeki bölgede yaşam süresi dağılımı bu ayrımı hiç yansıtmıyor: dokuz kayıt bir saatte, altı kayıt bir günde duruyor ve bunların arasında hem hiç değişmeyen ad sunucusu kayıtları hem de taşınabilir deneme adresleri var.
Planlı Değişiklikten Önce
Yaşam süresi bir değişiklikten önce düşürülür. Bunun neden işe yaradığı ve neden yarım yapıldığında işe yaramadığı sayılabilir.
AK5. Saha isteği hızı saniyede 8’dir ve önbelleklere eşit dağılır. AK6. Değişiklik anında yeni yanıt tüm yetkili sunuculardan aynı anda verilir; yetkili sunucular arası kopyalama gecikmesi bu modelde sayılmaz.
// Model: planlı bir adres değişikliğinden önce süreyi düşürmenin bedeli. Zaman // ekseninde 0 anı değişiklik anıdır; onPencere, süreyi kaç saniye önce düşürdüğümüzdür. const ONBELLEK = 240, TOHUM = 4242, ESKI_TTL = 3600, DUSUK_TTL = 300, ISTEK_HIZI = 8; function uretec(tohum) { let x = tohum % 2147483647; return () => { x = (x * 48271) % 2147483647; return (x - 1) / 2147483646; }; } function senaryo(ad, onPencere, ttlDusuruldu) { const rast = uretec(TOHUM); const kalanlar = []; for (let i = 0; i < ONBELLEK; i++) { let bitis = -onPencere + rast() * ESKI_TTL; while (bitis <= 0) bitis += ttlDusuruldu ? DUSUK_TTL : ESKI_TTL; kalanlar.push(Math.round(bitis)); } kalanlar.sort((a, b) => a - b); const y = (p) => kalanlar[Math.floor(kalanlar.length * p)] ?? kalanlar[kalanlar.length - 1]; return { ad, onPencere, p50: y(0.5), p95: y(0.95), yanlis: Math.round(kalanlar.reduce((a, b) => a + b, 0) * (ISTEK_HIZI / ONBELLEK)), ekstra: ttlDusuruldu ? Math.round(ONBELLEK * onPencere * (1 / DUSUK_TTL - 1 / ESKI_TTL)) : 0, geriAl: ttlDusuruldu ? DUSUK_TTL : ESKI_TTL, }; } const sure = (s) => (s < 90 ? `${s}s` : s < 5400 ? `${Math.round(s / 60)}dk` : `${(s / 3600).toFixed(1)}sa`); const senaryolar = [ senaryo('sureye dokunulmadi', 0, false), senaryo('30dk once dusuruldu', 1800, true), senaryo('24sa once dusuruldu', 86400, true), ]; console.log('istek hizi:', ISTEK_HIZI, 'istek/sn | onbellek:', ONBELLEK, '| tohum:', TOHUM); console.log('senaryo on pencere ekstra sorgu yayilma p50 yayilma p95 yanlis yonlenen geri alma'); for (const s of senaryolar) { console.log( s.ad.padEnd(22) + (s.onPencere ? sure(s.onPencere) : '-').padEnd(12) + (s.ekstra ? String(s.ekstra) : '-').padEnd(14) + sure(s.p50).padEnd(13) + sure(s.p95).padEnd(13) + String(s.yanlis).padEnd(17) + sure(s.geriAl), ); } const unutulan = Math.round(ONBELLEK * 86400 * (1 / DUSUK_TTL - 1 / ESKI_TTL)); console.log('\nsure geri yukseltilmezse gunluk ekstra yetkili sorgu:', unutulan); console.log('sure dusurulmesi unutulursa plansiz geri alma penceresi (p95):', sure(senaryolar[0].p95));
istek hizi: 8 istek/sn | onbellek: 240 | tohum: 4242 senaryo on pencere ekstra sorgu yayilma p50 yayilma p95 yanlis yonlenen geri alma sureye dokunulmadi - - 32dk 57dk 14812 60dk 30dk once dusuruldu 30dk 1320 5dk 27dk 4292 5dk 24sa once dusuruldu 24.0sa 63360 2dk 5dk 1142 5dk sure geri yukseltilmezse gunluk ekstra yetkili sorgu: 63360 sure dusurulmesi unutulursa plansiz geri alma penceresi (p95): 57dk
Ortadaki satır asıl derstir. Süre otuz dakika önce düşürüldüğünde işin yarısı yapılmış olur: önbelleklerin bir bölümü bu otuz dakika içinde yenilenip kısa süreyi almıştır, geri kalanı hâlâ bir saatlik kopyayı tutmaktadır. Sonuç, p50’de kazanç ama p95’te yirmi yedi dakikalık bir kuyruktur. Kısa süre, ancak eski sürenin bir tam dönemi geçtikten sonra her yere yerleşir; ön pencere eski süreden kısa olursa düşürme kâğıt üstünde kalır.
Bedel iki kalemdir. Yirmi dört saatlik ön pencere 63.360 fazladan yetkili sorgu getirir ve bu sorgular değişiklik olsun olmasın ödenir. İkincisi daha sinsidir: süre değişiklikten sonra geri yükseltilmezse aynı 63.360 sorgu her gün ödenmeye devam eder — ve kimse bunu bir olay olarak görmez, çünkü bir şey bozulmaz.
Düşürmenin unutulmasının bedeli ise plansız durumda ortaya çıkar. Bir yanlış kayıt yayınlandığında geri alma hızı, o an yürürlükte olan süredir: bir saatlik kayıtta yanlış adrese giden istek sayısı 14.812, beş dakikalık kayıtta 1.142. Aradaki 13.670 istek, bir alan adı ayarının değil, kimsenin vermediği bir kararın sonucudur.
Kapatmanın Getirdiği Yeni Yüzey
Her iki adımın da kendi yüzeyi var. Öksüz kayıt temizliği dört kalemi kapatır, ama prova ve
deneme adlarını hâlâ bir yerden çağıran bir iş varsa iki meşru akışı durdurur; bu yüzden
temizlik silmeden önce sorgu sayımı ister ve o sayım bölgede değil, çözümleyici günlüklerindedir.
Envanteri sürekli eşlemek için bölgeye yazabilen bir otomasyon kurulursa, ortaya yeni bir
ayrıcalıklı kimlik çıkar: bölgeye kayıt yazabilen, o adın yetkilisidir.
Süre düşürmenin yüzeyi de ölçülebilir. Beş dakikalık süre, yetkili sunucu erişilemez olduğunda beş dakikalık bir tampon bırakır; bir günlük sürede aynı arıza saatlerce fark edilmezdi. Yayılma penceresini kapatmak, yetkili sunucunun erişilebilirliğini kritik hale getirir.
Özet
- Bölge dosyası bir envanterdir; modeldeki on yedi hedefli kaydın dördü var olmayan bir hedefi gösteriyor ve ikisi boş bir ada işaret ettiği için devralınmaya açıktır.
- Bölgede yazılı on dört görünür ad bir keşif yüzeyidir ve bu kalem kapatılamaz; bölge yayınlanmak için vardır.
- Yaşam süresi tek başına üç şeyi belirler: yayılma penceresi, geri alma hızı ve sorgu yükü. Bir günden beş dakikaya inmek pencereyi 22 saatten 5 dakikaya çeker, sorguyu 288 katına çıkarır.
- Ön pencere eski süreden kısa olduğunda düşürme yarım kalır: otuz dakikalık ön pencerede p95 hâlâ 27 dakikadır.
- Süreyi geri yükseltmeyi unutmak günde 63.360 fazladan sorgu, düşürmeyi unutmak ise plansız geri almada 14.812 yanlış yönlenen istek demektir.
- Kapatmanın yüzeyi vardır: envanter otomasyonu bölgeye yazma yetkisi olan yeni bir kimlik, kısa süre ise yetkili sunucu arızasına karşı yalnızca beş dakikalık tampon getirir.
Sonraki Adım
Bu ders adın nereyi gösterdiğini ölçtü. Aynı ad, gösterdiği yerin dışında bir iş daha yapar:
o adın altından ileti gönderilir. Bölgesel ölçüm ağı saha ekiplerine bildirim e-postaları
yolluyor ve bu iletiler olcumag.gecersiz adını taşıyor. Adı taşıyan iletinin gerçekten o addan
çıktığını hiçbir şey söylemiyor — varsayılan durumda o adın adına ileti göndermek için o ada
sahip olmak gerekmez. Sonraki ders gönderen doğrulamasını bir yüzey olarak ölçer: yetkili gönderen
listesi ve imza kaydı kurgu bir ileti kümesinde koşturulur, kaç sahte iletinin yakalandığı, kaçının
geçtiği ve kaç meşru iletinin yanlışlıkla düştüğü sayılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.