Ders 05 / 13
Katmanlı Tanı Yöntemi
Sekiz aday neden ve sekiz sınama üzerinde tanı sırasının ölçülmesi: katmanlı sıra 33, ters sıra 38, her adımda kâhine bakan açgözlü sıra 10 adım harcıyor; açgözlü sıra cevabı bilmeyi gerektirdiği için uygulanabilir bir yordam değil, ulaşılamaz bir alt sınırdır.
İçindekiler
Önceki ders yerel servis envanterini çıkardı ve iki sınamanın eleme gücünü yan yana koydu: dinleyen soket listesi yalnız bir aday nedeni eliyordu, uzaktan yapılan bir bağlantı denemesi yedi. Elde artık sekiz ayrı sınama var ve hepsi çalıştırılabilir durumda. Bu dersin sorusu hangi sınamanın yapılacağı değil, hangi sırayla yapılacağıdır.
Soru boş bir soru değildir. Bir arıza karşısında akla ilk geleni denemek, en tanıdık aracı açmak ya da geçen seferki nedeni varsaymak birer sıradır ve her birinin bir bedeli vardır. Bedelin birimi de bellidir: kaç sınama yapıldığı. Bu ders üç sırayı aynı sekiz arıza üzerinde koşturur ve aralarındaki farkı sayar. Sayılardan biri şaşırtıcı derecede küçük çıkacak; o sayının neden bir yönteme dönüştürülemediği dersin asıl konusudur.
Aday Neden Kümesi
Tanı, bir kümeyi daraltma işidir. Başlangıçta elde bir belirti vardır — “sunucuya bağlanılamıyor” — ve bu belirtiyi üretebilecek birden çok neden. Kursun ortak kurgusu bu kümeyi sekiz aday neden olarak sabitler: arayüzün kapalı olması, adresin atanmamış olması, varsayılan ağ geçidinin yanlış olması, rotanın eksik olması, çözücünün yanıt vermemesi, servisin dinlememesi, güvenlik duvarının paketi düşürmesi ve büyük paketin yolda kaybolması.
Sekiz sınama da bu kümenin üzerinde çalışır. Her sınama bir araca karşılık gelir, bir yanıt döndürür ve o yanıt aday kümesini böler. Kâhin, gerçek arızadır: kurguyu biz seçtiğimiz için hangi arızanın etkin olduğunu biliriz. Operatör bilmez; operatörün elinde yalnız yanıtlar vardır.
Kurgunun varsayımları: bir istemci, bir sunucu ve tek bir hedef servis vardır ve aday neden kümesi bu sekizle sınırlıdır (SG1); her arıza sağlam durumun tek bir alanını bozar, iki arıza aynı anda bulunmaz (SG2); bir sınama kararlı tek bir yanıt döndürür ve aday sayısı bire indiğinde durulur (SG3); açgözlü sıra her adımda gerçek arızayı bilerek en çok eleyen sınamayı seçer (SG4); her sınamanın maliyeti eşittir ve bir adım sayılır (SG5).
Listenin nereden geldiği ayrı bir sorudur ve tanının en az konuşulan adımıdır. Aday neden kümesi belirtiden türetilir: hangi bileşenler bu belirtiyi üretebilir, hangileri üretemez. Kümeyi dar tutmak sınama sayısını düşürür ama gerçek nedeni dışarıda bırakma riskini büyütür; geniş tutmak tersini yapar. Sekiz adaylı kurgu bir kapalı dünya varsayımıdır: gerçek arızanın listede olduğu kabul edilir. Kapalı dünya bozulduğunda ölçünün kendisi değil, ölçünün yorumu bozulur — bütün sınamalar biter, tek aday kalır ve o aday yanlıştır. Bir tanı sırasının bitmesi, doğru bitirdiği anlamına gelmez.
Kümenin daralmasının bir başka kaynağı da sistem yönetimi kursunda ölçülen günlüklerdir. Servis yeniden başlatıldıysa, bir birim arızalandıysa ya da bir yapılandırma değişikliği kayda düştüyse bu, sınama yapılmadan önce bazı adayları öne çıkarır. Günlüklerin buradaki rolü kanıt değil öncüldür: sıralamayı etkiler, adayı elemez. Eleme yalnız bir sınamanın yanıtıyla olur.
Protokol katmanlarının kendisi, el sıkışma ve yönlendirme protokolleri Bilgisayar Ağları müfredatının konusudur ve burada kurulmaz. Bu kurs tek bir makinenin yapılandırmasına ve tanısına bakar. Ad alanı ile konteyner ağı da buraya girmez; onlar Çekirdek Arayüzleri ve İzolasyon kursuna bırakılmıştır.
Katmanlı Sıra ve İki Rakibi
Katmanlı tanı, sınamaları bağımlılık sırasına göre dizer: önce arayüz, sonra adres ve rota, sonra yerel ağa erişim, sonra uzak erişim, sonra ad çözümleme, en sonda servisin kendisi. Gerekçe sezgiseldir — alttaki bozuksa üsttekinin sonucu zaten anlamsızdır.
Ters sıra aynı listeyi tersten okur: önce servise bağlanmayı dener, sonra aşağı iner. Bu da savunulabilir bir sıradır; çoğu arıza servis tarafındadır diye düşünen bir operatör doğrudan oradan başlar.
Açgözlü sıra ise her adımda geriye en az aday bırakacak sınamayı seçer. Üç sıranın kullandığı sınamalar aynıdır; aşağıdaki döküm bunların hangi komutlara karşılık geldiğini gösterir ve çalıştırılmamıştır. Ölçüm ardından gelen blokta yapılır ve üç sırayı da aynı sekiz arıza üzerinde koşturur.
# ornek dokum , calistirilmis degildir $ ip -brief link show # arayuz acik mi $ ip -brief addr show # adres atanmis mi $ ip route show # varsayilan gecit ve rota $ ping -c 3 <ag-gecidi> # yerel aga yanki $ getent hosts <sunucu-adi> # ad cozumleme $ ss -ltn # dinleyen bag noktalari $ nc -z -w 3 <hedef> <bag-noktasi> # baglanti denemesi
SAGLAM = {"arayuz_acik": True, "adres_var": True, "ag_gecidi_dogru": True, "rota_var": True, "cozumleyici_yanit": True, "servis_dinliyor": True, "guvenlik_duvari_gecirir": True, "yol_bozulmadan": True} ARIZA = { # SG2: her ariza TEK alani bozar "arayuz-kapali": {"arayuz_acik": False, "adres_var": False}, "adres-yok": {"adres_var": False}, "ag-gecidi-yanlis": {"ag_gecidi_dogru": False}, "rota-eksik": {"rota_var": False}, "cozumleyici-sessiz": {"cozumleyici_yanit": False}, "servis-dinlemiyor": {"servis_dinliyor": False}, "guvenlik-duvari-dusuruyor": {"guvenlik_duvari_gecirir": False}, "buyuk-paket-dusuyor": {"yol_bozulmadan": False}, } ADAYLAR = tuple(ARIZA) def durum(ariza=None): d = dict(SAGLAM) if ariza: d.update(ARIZA[ariza]) return d def yol(d): # arayuz + adres + gecit + rota birlikte return (d["arayuz_acik"] and d["adres_var"] and d["ag_gecidi_dogru"] and d["rota_var"]) SINAMA = { "arayuz": lambda d: ("acik-adresli" if d["arayuz_acik"] and d["adres_var"] else "acik-adressiz" if d["arayuz_acik"] else "kapali"), "rota": lambda d: ("tablo-bos" if not d["adres_var"] else "tam" if d["rota_var"] else "varsayilan-yok"), "gecit-yankisi": lambda d: ("yanit" if d["arayuz_acik"] and d["adres_var"] else "yanit-yok"), "uzak-yanki": lambda d: "yanit" if yol(d) else "yanit-yok", "ad-cozumleme": lambda d: "cozuldu" if d["cozumleyici_yanit"] else "cozulemedi", "dinleyen": lambda d: "dinliyor" if d["servis_dinliyor"] else "dinlemiyor", "baglanti": lambda d: ("ulasilamaz" if not yol(d) else "zaman-asimi" if not d["guvenlik_duvari_gecirir"] else "reddedildi" if not d["servis_dinliyor"] else "kuruldu"), "buyuk-paket": lambda d: ("geciyor" if yol(d) and d["yol_bozulmadan"] else "gecmiyor"), } def ele(adaylar, s, yanit): return tuple(a for a in adaylar if SINAMA[s](durum(a)) == yanit) def eledigi(adaylar, s, gercek): kalan = ele(adaylar, s, SINAMA[s](durum(gercek))) return len(adaylar) - len(kalan), len(kalan) def maliyet(sira, gercek, adaylar=ADAYLAR): # SG3: aday teke inince durulur kalan, adim = tuple(adaylar), 0 for s in sira: if len(kalan) <= 1: break adim += 1 kalan = ele(kalan, s, SINAMA[s](durum(gercek))) return adim def acgozlu(gercek, adaylar=ADAYLAR): # SG4: her adimda kahine bakar kalan, secilen = tuple(adaylar), [] while len(kalan) > 1 and len(secilen) < len(SINAMA): en, en_s = None, None for s in SINAMA: if s not in secilen: k = len(ele(kalan, s, SINAMA[s](durum(gercek)))) if en is None or k < en: en, en_s = k, s secilen.append(en_s) kalan = ele(kalan, en_s, SINAMA[en_s](durum(gercek))) return secilen KATMANLI = ["arayuz", "rota", "gecit-yankisi", "uzak-yanki", "ad-cozumleme", "dinleyen", "baglanti", "buyuk-paket"] TERS = list(reversed(KATMANLI)) KAHIN = "guvenlik-duvari-dusuruyor" print("aday ariza:", len(ADAYLAR), "| sinama:", len(SINAMA), "| kahin:", KAHIN) print("sinama yanit elenen kalan") for s in KATMANLI: e, k = eledigi(ADAYLAR, s, KAHIN) print(f" {s:14s}{SINAMA[s](durum(KAHIN)):16s}{e:6d} {k:6d}") print() print("ariza katmanli ters acgozlu acgozlu sira") for a in ADAYLAR: g = acgozlu(a) print(f" {a:26s}{maliyet(KATMANLI, a):6d}{maliyet(TERS, a):6d}" f"{len(g):8d} {', '.join(g)}") print("toplam adim: katmanli", sum(maliyet(KATMANLI, a) for a in ADAYLAR), "| ters", sum(maliyet(TERS, a) for a in ADAYLAR), "| acgozlu", sum(len(acgozlu(a)) for a in ADAYLAR)) print() print("aday kumesi supurmesi -- kume buyurken baglanti denemesinin eledigi") kume = [KAHIN] for a in ADAYLAR: if a not in kume: kume.append(a) e, k = eledigi(tuple(kume), "baglanti", KAHIN) print(f" aday {len(kume)} eklenen {a:26s} elenen {e} kalan {k}") print("bir aday cikarildiginda katmanli toplam (8 adayda 33)") for cikan in ADAYLAR: alt = tuple(x for x in ADAYLAR if x != cikan) print(f" cikan {cikan:26s} {sum(maliyet(KATMANLI, a, alt) for a in alt):3d}")
aday ariza: 8 | sinama: 8 | kahin: guvenlik-duvari-dusuruyor sinama yanit elenen kalan arayuz acik-adresli 2 6 rota tam 3 5 gecit-yankisi yanit 2 6 uzak-yanki yanit 4 4 ad-cozumleme cozuldu 1 7 dinleyen dinliyor 1 7 baglanti zaman-asimi 7 1 buyuk-paket geciyor 5 3 ariza katmanli ters acgozlu acgozlu sira arayuz-kapali 1 8 1 arayuz adres-yok 1 8 1 arayuz ag-gecidi-yanlis 4 7 2 uzak-yanki, rota rota-eksik 2 7 1 rota cozumleyici-sessiz 5 2 1 ad-cozumleme servis-dinlemiyor 6 2 1 dinleyen guvenlik-duvari-dusuruyor 7 2 1 baglanti buyuk-paket-dusuyor 7 2 2 baglanti, ad-cozumleme toplam adim: katmanli 33 | ters 38 | acgozlu 10 aday kumesi supurmesi -- kume buyurken baglanti denemesinin eledigi aday 2 eklenen arayuz-kapali elenen 1 kalan 1 aday 3 eklenen adres-yok elenen 2 kalan 1 aday 4 eklenen ag-gecidi-yanlis elenen 3 kalan 1 aday 5 eklenen rota-eksik elenen 4 kalan 1 aday 6 eklenen cozumleyici-sessiz elenen 5 kalan 1 aday 7 eklenen servis-dinlemiyor elenen 6 kalan 1 aday 8 eklenen buyuk-paket-dusuyor elenen 7 kalan 1 bir aday cikarildiginda katmanli toplam (8 adayda 33) cikan arayuz-kapali 32 cikan adres-yok 32 cikan ag-gecidi-yanlis 29 cikan rota-eksik 31 cikan cozumleyici-sessiz 28 cikan servis-dinlemiyor 27 cikan guvenlik-duvari-dusuruyor 25 cikan buyuk-paket-dusuyor 25
Kâhin, Sınama, Elenen Aday
Üç sayı yan yana durur. Kâhin: gerçek arıza guvenlik-duvari-dusuruyor, yani güvenlik
duvarı paketi sessizce düşürüyor. Sınama: bağlantı denemesi zaman-asimi yanıtını
veriyor. Elenen aday: bu tek yanıt sekiz adaydan 7’sini eliyor ve geriye 1 aday
bırakıyor, yani arıza tek sınamayla çözülüyor.
Aynı kâhin altında ad çözümleme sınaması cozuldu, dinleyen listesi dinliyor yanıtını
verir; her ikisi de yalnız 1’er aday eler ve geriye 7 aday bırakır. Ortaya çıkan
oran kursun ilk okumasıdır: aynı çabayla yapılan iki sınamadan biri ötekinin yedi katı
iş görüyor. Bir sınamanın değeri verdiği yanıtta değil, o yanıtın kaç adayı düşürdüğündedir.
Yanıtı doğru olan bir sınama, hiçbir adayı elemiyorsa ölçülmemiş sayılır.
Toplam adım tablosu ikinci okumadır. Sekiz arızanın hepsi tek tek gerçek arıza yapıldığında katmanlı sıra toplam 33 adım, ters sıra 38 adım, açgözlü sıra 10 adım harcıyor. Katmanlı sıra optimalin 3,3 katı kadar sınama yapıyor. Ters sıranın kaybı ise dağılımda: servis tarafındaki dört arızayı 2 adımda bitiriyor, ama arayüz tarafındaki iki arızada 8 adımın tamamını harcıyor.
Açgözlü Sıra Neden Bir Yordam Değil
On sayısı okuyucuyu yanlış bir sonuca çekebilir: “en çok eleyen sınamayı seç” kuralı
uygulanabilir bir yöntem gibi görünür. Değildir. Kuralın işleyebilmesi için her adımda,
henüz bilinmeyen gerçek arıza altında her sınamanın hangi yanıtı vereceğini hesaplamak
gerekir. Blokta bunu yapan satır SINAMA[s](durum(gercek)) çağrısıdır ve gercek, tam da
tanının bulmaya çalıştığı şeydir.
Başka bir deyişle açgözlü sıra kâhini girdi olarak alır. Cevabı bilen biri en kısa yolu seçebilir; cevabı bilmeyen biri o seçimi yapamaz. Bu yüzden 10 sayısı bir hedef değil, ulaşılamaz bir alt sınırdır. Ölçüde bir işi vardır — katmanlı sıranın ne kadar fazla iş yaptığını gösteren bir ölçek verir — ama uygulanabilir bir sıra olarak hiçbir yerde sunulmaz.
Bu ayrım tanı yazınında sık karıştırılır. “Deneyimli operatör doğrudan doğru yere bakar” cümlesi, açgözlü sıranın insan biçimidir ve aynı kusuru taşır: deneyim geçmiş arızaların dağılımını bilmektir, o anki arızayı değil. Geçmiş dağılım bugünkü arızaya uyduğunda kısa yol çalışır, uymadığında operatör ters sıranın en kötü durumunu yaşar — arayüz kapalıyken sekiz sınamanın hepsini yapmak gibi.
Katmanlı Sıranın Savunması
Katmanlı yöntemin savunması hız değildir; 33 adım 10 adımdan üç kat pahalıdır ve bu fark gerçektir. Savunma şudur: katmanlı sıra kâhin olmadan çalışır. Sıra, arızadan önce sabitlenmiştir ve hangi arıza etkin olursa olsun aynı sırada yürür. Girdisi yalnız sınamaların yanıtlarıdır.
İkinci savunma, sıranın verdiği ara bilginin birikimli olmasıdır. Arayüz sınaması
acik-adresli yanıtını verdiğinde yalnız iki aday elenmez; sonraki sınamaların yorumlanma
biçimi de sabitlenir. Ters sırada bu birikim yoktur: servise bağlanılamadığı görüldüğünde
elde kalan dört aday hâlâ ayrılmamıştır ve aşağı inen her sınama baştan yorumlanır.
Üçüncü savunma yanlış tanıya karşı korumadır. Ters sıra çalışırken servis tarafında bir düzeltme yapma isteği doğar — servisi yeniden başlatmak, kuralı gevşetmek — ve alt katman bozukken yapılan bu düzeltmeler sistemin durumunu değiştirir. Katmanlı sıra, düzeltmeye geçmeden önce altın sağlam olduğunu kanıtlar.
Dördüncü nokta pratik bir uyarıdır: en pahalı arızalar tabloda en aşağıdadır.
guvenlik-duvari-dusuruyor ve buyuk-paket-dusuyor katmanlı sırada 7’şer adım tutar.
Bir kısayol arayan operatör için doğru hamle sırayı bozmak değil, bağlantı denemesini
sıraya erken sokmaktır: dört ayrı yanıt döndürdüğü için tek başına en güçlü bölücüdür ve
sıranın mantığını bozmadan yukarı taşınabilir.
Aday Kümesi Süpürmesi
Kurguda rastgelelik yoktur; bütün sayılar tam sayımdır. Sonuçların kurguya ne kadar bağlı olduğu bu yüzden ikinci bir tohumla değil, aday kümesini değiştirerek sınanır.
Küme büyürken bağlantı denemesinin elediği aday sayısı 1’den 7’ye çıkar, kalan hep 1’dir. Buradan çıkan sonuç önemlidir: eleme sayısı aracın tek başına bir özelliği değildir, aday kümesinin de ölçüsüdür. “Bu araç yedi adayı eler” cümlesi ancak sekiz adaylı bir küme tanımlanmışsa anlamlıdır. Aday listesini yazmadan araç karşılaştırmak, paydası olmayan bir kesir yazmaktır.
Bir aday çıkarıldığında katmanlı toplam 33’ten 25 ile 32 arasına iner. Düşüş nerede
olduğuna bağlıdır: sıranın başındaki arayuz-kapali çıkarıldığında toplam yalnız 1 adım
azalır (32), sonundaki guvenlik-duvari-dusuruyor ya da buyuk-paket-dusuyor
çıkarıldığında 8 adım azalır (25). Katmanlı sıranın maliyetini belirleyen şey aday sayısı
değil, adayların sıranın neresinde durduğudur. Aynı sonucun tersi de doğrudur: listeye
eklenen yeni bir derin aday, toplamı sekiz adıma kadar büyütebilir.
Özet
- Tanı bir kümeyi daraltma işidir; bir sınamanın sayısı verdiği yanıt değil, elediği aday neden sayısıdır ve kaç adayı elediği yazılmayan sınama ölçülmemiş sayılır.
- Güvenlik duvarının düşürdüğü senaryoda bağlantı denemesi 7 aday eler ve tek başına çözer; ad çözümleme ile dinleyen listesi yalnız 1’er aday eler.
- Sekiz arızanın toplam adım maliyeti: katmanlı sıra 33, ters sıra 38, kâhin destekli açgözlü sıra 10.
- Açgözlü sıra bir yordam değildir: her adımda en çok eleyen sınamayı seçmek gerçek arızayı bilmeyi gerektirir, bu yüzden 10 ulaşılamaz bir alt sınırdır.
- Katmanlı yöntemin savunması hızı değil, kâhin olmadan da çalışmasıdır; sırası arızadan önce sabitlenmiştir ve yalnız sınama yanıtlarını girdi alır.
- Eleme sayısı aday kümesine bağlıdır: küme 2’den 8’e büyürken bağlantı denemesinin elediği aday 1’den 7’ye çıkar.
Sonraki Adım
Katmanlı sıranın ilk dört adımı erişilebilirlik sınamalarıdır ve tabloda en zayıf görünenler de oradadır: ağ geçidine yankı yalnız 2 aday eliyor, uzak adrese yankı 4. Bu sınamaların gerçek sorunu zayıflıkları değil, yanlış okunmalarıdır: yanıt gelmemesi tek bir nedene değil, birden çok nedene uyar ve yanıt gelmesi de erişimin sağlam olduğunu söylemez. Sonraki ders yankı ve yol izleme araçlarının döndürdüğü sessizliği açar ve “yanıt yok” durumunun kaç ayrı aday nedene karşılık geldiğini sayar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.