Ders 03 / 11
Aktarım Katmanı
Yerel ve uzak aktarımın aynı iş yükünde gidiş-dönüş cinsinden karşılaştırılması: aynı üç araçlık zincir üç aktarım kurulumunda da 844 sonucunu, 6 istek, 6 yanıt ve 179 zarf belirteciyle üretir, ama gidiş-dönüş hepsi yerelde 6, karışımda 9, hepsi uzakta 12 olur. İstek sayısı sabitken gidiş-dönüş tam iki katına çıkar ve zarfın belirteç sayısı hiç değişmez; aktarım araç tanımını, işleyiciyi ve sonucu değiştirmez, yalnız fiyatını değiştirir. On iki abonelik bir partide istek 39'da sabit kalırken gidiş-dönüş 39'dan 78'e çıkar ve fark tam olarak istek sayısı kadardır. Sürüm sapmasıyla düşen kayit sunucusu için de aktarım ödenir: hiçbir araç kazandırmayan bu sunucu yerelde 1, uzakta 2 gidiş-dönüş tüketir. Bu ders kursun ikinci iddiasının ilk örneğidir: standartlaştırmak da bozar.
İçindekiler
Önceki derste yerleşim değişti, aktarım değişmedi: olcum yerelde, tarife ile kayit uzakta
duruyordu ve eklenen bütün mesajlar yerel fiyatla sayıldı. O tablonun bir tuhaflığı vardı. Doğru
dağılımda 6 istek gönderildi ama 9 gidiş-dönüş sayıldı; iki sütun birlikte hareket etmedi.
İstek bir sayma birimidir, gidiş-dönüş başka bir sayma birimidir ve aradaki farkı mesajın nasıl
taşındığı belirler.
Protokol bu yüzden iki katmana ayrılır. Veri katmanı mesajın ne olduğunu söyler: istek mi, yanıt mı, hangi araç, hangi alanlar. Aktarım katmanı o mesajın karşı tarafa nasıl ulaştığını söyler ve iki biçimi vardır: yerel aktarım, sunucu aynı makinede bir süreç olarak durur ve mesajlar süreçler arası akışlardan geçer; uzak aktarım, sunucu ağın ötesindedir. Bu ders aynı iş yükünü üç aktarım kurulumunda koşturur ve tek bir soruyu sorar: istek sayısı sabitken gidiş-dönüşe ne oluyor?
- PY18. Ortam, üç kurgu sunucu ve protokol benzeticisi kurgudur; gerçek bir soket, süreç ya da ağ bağlantısı açılmaz. Tohum 20260218. Zarfın sabit bedeli sekiz belirteçtir.
- PY19. Yerel aktarımda bir istek bir, uzak aktarımda iki gidiş-dönüş sayılır. Bu kurgu bir ölçektir; ölçülen şey mutlak değer değil, aynı iş yükünde sayının nasıl değiştiğidir.
- PY20. Süreçler arası iletişimin ve ağ üzerinden çağrının kendi yordamı Linux ve Servis Mimarileri kurslarında ele alındı ve tekrarlanmaz; burada yalnız aktarımın protokole eklediği gidiş-dönüş sayılır.
- PY21. Aktarım biçimi araç tanımını, işleyiciyi ve sonucu değiştirmez; yalnız mesajın taşınma biçimini değiştirir.
- PY22. Üç kurulum karşılaştırılır: hepsi yerel, karışım (
olcumyerel,tarifeilekayituzak) ve hepsi uzak. Sürüm denetimi aktarımdan bağımsızdır;kayitüç kurulumda da düşer. - PY23. Zarfın belirteç sayısı aktarımdan bağımsızdır; aktarım gövdeyi değiştirmez.
- PY24. Süre ham birimle yazılmaz; sayılan şey gidiş-dönüştür.
- PY25. İkinci ölçü on iki abonelik bir parti üzerinde alınır. Sayımlar koşumdan bağımsızdır ve bu ders oran değil sayım basar.
Üç Aktarım Kurulumu
İki biçim yalnız hızda ayrılmaz; sunucunun yaşam süresini ve kime erişilebilir olduğunu da ayırır. Yerel aktarımda sunucuyu genellikle istemcinin kendisi başlatır ve sunucu barındırıcı kapandığında biter; ona ancak aynı makinedeki bir istemci ulaşabilir. Uzak aktarımda sunucunun yaşam süresi bağımsızdır ve başka makinelerdeki istemciler de aynı sunucuya bağlanabilir. Bu ayrım ilk derste sayılan taşınabilirliği doğrudan etkiler: aynı sunucunun dört istemciye takılması ve tanımın tek yerde durması uzak aktarımla gerçek anlamını bulur; yerel aktarımda o dört istemci aynı makinede olmak zorundadır.
Aşağıdaki kod önceki derslerin kurgu ortamını ve benzeticisini kurar, sonra sunucuların aktarım
biçimini zorlayarak aynı üç araçlık zinciri üç kez koşturur. aktarimla işlevi biçimi
değiştirmeden önce özgün değerleri saklar ve koşum sonunda geri yazar; araçların kodu, alan adları
ve hesap hiç değişmez.
TOHUM, M32 = 20260218, 0xFFFFFFFF def uretec(t): x = ((t ^ (t >> 16)) * 2246822507) & M32 x = ((x ^ (x >> 13)) * 3266489909) & M32 s = [(x ^ (x >> 16)) & M32] def sonraki(): s[0] = (s[0] * 1664525 + 1013904223) & M32 return s[0] / 4294967296 return sonraki def belirtecle(m): b = [] for s in str(m).lower().replace(",", " , ").split(): while len(s) > 5: b.append(s[:5]) s = s[5:] b.append(s) return b # ---- KURGU ortam: olcum aginin abone kayitlari BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"] TIP = ["mesken", "isyeri"] ABONE = {} for i in range(60): r = uretec(TOHUM + 31 * i) onceki = 10000 + int(r() * 80000) ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)], "onceki": onceki, "simdiki": onceki + int(r() * 70)} BASAMAK, USTU, ISYERI_KAT = ((10, 4), (25, 7), (40, 11)), 16, 2 def _bedel(m3, tip): kalan, alt, top = m3, 0, 0 for ust, birim in BASAMAK: dilim = min(kalan, ust - alt) if dilim <= 0: break top += dilim * birim kalan -= dilim alt = ust return (top + kalan * USTU) * (ISYERI_KAT if tip == "isyeri" else 1) def t_sayac(abone=None, **_): a = ABONE.get(abone) return {"hata": "abone yok"} if a is None else { "onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"]} def t_tuketim(onceki=None, simdiki=None, **_): if onceki is None or simdiki is None: return {"hata": "eksik alan"} f = simdiki - onceki return {"m3": f + 100000 if f < 0 else f} def t_tarife(m3=None, tip="mesken", **_): return {"hata": "eksik alan"} if m3 is None else {"tutar": _bedel(m3, tip)} def t_bolge(bolge=None, **_): if bolge not in BOLGE: return {"hata": "bolge yok"} n = sum(1 for a in ABONE.values() if a["bolge"] == bolge) return {"bolge": bolge, "abone": n} def t_kayit(abone=None, sutun=None, deger=None, **_): if not (abone and sutun and deger is not None): return {"hata": "eksik alan"} return {"yazildi": True} # ---- KURGU sunucular: her biri yetenek bildirir SUNUCU = { "olcum": {"surum": 2, "aktarim": "yerel", "arac": {"sayac_oku": {"islev": t_sayac, "alan": ("abone",), "yan_etki": False}, "tuketim": {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False}}, "kaynak": ("abone_listesi",), "istem": ()}, "tarife": {"surum": 1, "aktarim": "uzak", "arac": {"tarife": {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False}}, "kaynak": ("basamak_tablosu",), "istem": ("bedel_aciklamasi",)}, "kayit": {"surum": 3, "aktarim": "uzak", "arac": {"bolge_ozet": {"islev": t_bolge, "alan": ("bolge",), "yan_etki": False}, "kayit_yaz": {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True}}, "kaynak": (), "istem": ()}, } ISTEMCI_SURUM = {"olcum": 2, "tarife": 1, "kayit": 2} # kayit sunucusu ileride IZIN = ("sayac_oku", "tuketim", "tarife", "bolge_ozet") # kayit_yaz izin listesinde yok SAYIM = {"istek": 0, "yanit": 0, "bildirim": 0, "belirtec": 0, "gidis_donus": 0} def mesaj(tur, govde, aktarim="yerel"): """KURGU zarf. Gercek bir protokol uygulanmaz; sayilan sey zarfin bedelidir.""" SAYIM[tur] += 1 b = len(belirtecle(govde)) + 8 # zarf sabiti SAYIM["belirtec"] += b if tur == "istek": SAYIM["gidis_donus"] += 2 if aktarim == "uzak" else 1 return b def elsikismasi(istemci_surum=None, izin=None): """Yetenek uzlasmasi: surum uyusmazligi ve izin listesi arac kumesini daraltir.""" istemci_surum = ISTEMCI_SURUM if istemci_surum is None else istemci_surum izin = IZIN if izin is None else izin anlasilan, dusen = {}, [] for ad, s in SUNUCU.items(): mesaj("istek", f"yetenek sor {ad}", s["aktarim"]) mesaj("yanit", f"yetenek bildir {ad} surum {s['surum']} " + " ".join(s["arac"]) + " " + " ".join(s["kaynak"])) if istemci_surum.get(ad, 0) < s["surum"]: dusen.append((ad, "surum", s["surum"], istemci_surum.get(ad, 0))) continue for t, tan in s["arac"].items(): if t not in izin: dusen.append((ad, "izin", t, None)) continue anlasilan[t] = dict(tan, sunucu=ad, aktarim=s["aktarim"]) return anlasilan, dusen def cagir(anlasilan, ad, durum): if ad not in anlasilan: return {"hata": "arac bildirilmedi"} t = anlasilan[ad] kw = {a: durum[a] for a in t["alan"] if a in durum} mesaj("istek", f"{ad} " + " ".join(f"{k} {v}" for k, v in kw.items()), t["aktarim"]) s = t["islev"](**kw) mesaj("yanit", " ".join(f"{k} {v}" for k, v in s.items())) return s VARSAYILAN = {ad: s["aktarim"] for ad, s in SUNUCU.items()} BICIM = (("hepsi yerel", "yerel"), ("karisim", None), ("hepsi uzak", "uzak")) def aktarimla(zorla, abone_listesi): """Ayni is yuku, sunucularin aktarim bicimi degistirilerek.""" for ad, s in SUNUCU.items(): s["aktarim"] = VARSAYILAN[ad] if zorla is None else zorla for k in SAYIM: SAYIM[k] = 0 anlasilan, _ = elsikismasi() el = dict(SAYIM) sonuc = [] for abone in abone_listesi: durum = {"abone": abone} for ad in ("sayac_oku", "tuketim", "tarife"): durum.update(cagir(anlasilan, ad, durum)) sonuc.append(durum["tutar"]) for ad, s in SUNUCU.items(): s["aktarim"] = VARSAYILAN[ad] return sonuc, el, dict(SAYIM) print("aktarim sonuc istek yanit zarf belirteci el sikismasi g-d" " zincir g-d toplam g-d") for ad, z in BICIM: s, el, top = aktarimla(z, ["A017"]) print(f"{ad:<12} {s[0]:>6} {top['istek']:>6} {top['yanit']:>6} {top['belirtec']:>15}" f" {el['gidis_donus']:>17} {top['gidis_donus'] - el['gidis_donus']:>11}" f" {top['gidis_donus']:>11}") print("dusen kayit sunucusunun el sikismasi bedeli : yerelde 1, uzakta 2 gidis-donus")
aktarim sonuc istek yanit zarf belirteci el sikismasi g-d zincir g-d toplam g-d hepsi yerel 844 6 6 179 3 3 6 karisim 844 6 6 179 5 4 9 hepsi uzak 844 6 6 179 6 6 12 dusen kayit sunucusunun el sikismasi bedeli : yerelde 1, uzakta 2 gidis-donus
İstek Sabit, Gidiş-Dönüş İki Kat
Tablonun ilk dört sütunu üç satırda da aynı: sonuç 844, istek 6, yanıt 6, zarf belirteci 179. Araçların kodu değişmedi, alan adları değişmedi, mesajların gövdesi değişmedi. Beşinci sütundan sonrası ise iki katına çıktı: gidiş-dönüş 6’dan 12’ye. Aradaki karışım kurulumu 9 ile tam ortada duruyor, çünkü üç sunucudan biri yerel kalıyor.
Bu, kursun ikinci iddiasının ilk örneğidir: standartlaştırmak da bozar. Bir aracı ağın ötesine taşımak onu paylaşılabilir yapar; aynı hareket, hiçbir şey kazandırmadan gidiş-dönüş sayısını ikiye katlar. Kazanç ile bedel aynı karardan çıkar ve ayrılamaz.
Zarf belirtecinin üç satırda da 179 olması ayrıca kayda değer. Aktarım katmanı veri katmanının üstünde durur ve mesajın gövdesine dokunmaz; bir mesajın kaç belirteç ettiği o mesajın nereden geçtiğine bağlı değildir. Bu, iki katmanın gerçekten ayrı olduğunun sayısal kanıtıdır ve bir tasarım sonucu doğurur: uzak aktarımın bedeli belirteç bütçesinden kısarak azaltılamaz, çünkü belirteç bütçesiyle ilgisi yoktur. Azaltılacak şey istek sayısıdır.
Son satır bir kayıptır. kayit sunucusu üç kurulumda da sürüm sapmasıyla düşüyor ve hiçbir araç
kazandırmıyor; buna rağmen el sıkışması için aktarım bedeli ödeniyor: yerelde 1, uzakta 2
gidiş-dönüş. Hepsi uzak kurulumunda el sıkışmasının altı gidiş-dönüşünün ikisi bu sunucuya
gidiyor. Bir bağlantının bedeli, o bağlantının işe yarayıp yaramamasından bağımsız olarak ödenir.
İş Yükü Büyüdükçe
Tek abonelik bir zincir dar bir ölçüdür. Aynı ölçü, aynı el sıkışmanın ardından on iki abone için tekrarlanan bir zincirde de alınır: parti büyüdükçe el sıkışmasının sabit payı erir ve geriye yalnız çağrıların aktarım bedeli kalır.
PARTI = [f"A{1 + 5 * i:03d}" for i in range(12)] print("abone ", "yerel: istek g-d karisim: istek g-d uzak: istek g-d" " uzak/yerel g-d farki") for k in (1, 4, 12): satir, g = [], {} for ad, z in BICIM: s, _, top = aktarimla(z, PARTI[:k]) satir += [top["istek"], top["gidis_donus"]] g[ad] = top["gidis_donus"] print(f"{k:>5} {satir[0]:>11} {satir[1]:>4} {satir[2]:>15} {satir[3]:>4}" f" {satir[4]:>13} {satir[5]:>4} {g['hepsi uzak'] - g['hepsi yerel']:>21}") s12, _, t12 = aktarimla("yerel", PARTI) u12, _, u12t = aktarimla("uzak", PARTI) print(f"on iki abone : sonuclar ayni mi {s12 == u12} ; zarf belirteci" f" yerel {t12['belirtec']} uzak {u12t['belirtec']} ;" f" gidis-donus {t12['gidis_donus']} ve {u12t['gidis_donus']}")
abone yerel: istek g-d karisim: istek g-d uzak: istek g-d uzak/yerel g-d farki
1 6 6 6 9 6 12 6
4 15 15 15 21 15 30 15
12 39 39 39 53 39 78 39
on iki abone : sonuclar ayni mi True ; zarf belirteci yerel 1059 uzak 1059 ; gidis-donus 39 ve 78
İstek sütunu üç kurulumda da aynı kalıyor: bir abonede 6, dörtte 15, on ikide 39. Gidiş-dönüş sütunu ise yerelde isteğe eşit, uzakta tam iki katı. Son sütun bu ilişkiyi tek sayıya indiriyor: uzak ile yerel arasındaki fark her zaman istek sayısı kadar. Karışım kurulumu ikisinin arasında kalıyor ve büyüdükçe uzak tarafa yaklaşıyor, çünkü partideki her zincir bir uzak çağrı içeriyor.
On iki abonelik parti de aynı sonuçları veriyor ve zarf belirteci iki kurulumda da 1059. On iki abonenin sonuç listesi yerel ile uzakta birebir aynı; benzeticide belirsiz bir bileşen yok ve sayımlar koşumdan bağımsız. Aktarım katmanı işin ne olduğunu değil kaç kez gidip geldiğini belirler.
Sabit pay ile değişken payın ayrılması da bu tablodan okunur. Hepsi uzak kurulumunda el sıkışması 6 gidiş-dönüş tutuyor ve parti ne kadar büyürse büyüsün 6’da kalıyor; zincirlerin payı ise bir abonede 6, dört abonede 24, on iki abonede 72. Tek abonede toplamın yarısı bağlantı kurmaya gidiyor, on iki abonede on üçte biri. Yerel kurulumda el sıkışması 3’te sabit kalıyor ve zincir payı 3’ten 36’ya çıkıyor; ayrımın biçimi aynı, ölçeği yarım. El sıkışması bir kez ödenen bir bedeldir ve oturum ne kadar uzun kullanılırsa çağrı başına payı o kadar küçülür; oturumu her iş için yeniden kurmak bu payı her seferinde yeniden ödetir.
Buradan çıkan mühendislik kararı gidiş-dönüşü azaltmakla ilgilidir ve iki yolu vardır. Birincisi sunucuyu yerele almaktır; bu, o sunucuyu ağın ötesindeki istemciler için erişilemez kılar ve taşınabilirliği geri verir. İkincisi istek sayısını düşürmektir; on iki abonelik partide isteğin 39’da kalması, el sıkışmasının bir kez yapılmasından gelir. Oturum başına ödenen sabit bedel, oturum ne kadar uzun kullanılırsa o kadar ucuzlar.
Özet
- Protokol iki katmana ayrılır: veri katmanı mesajın ne olduğunu, aktarım katmanı nasıl taşındığını söyler; yerel aktarımda sunucu aynı makinede, uzak aktarımda ağın ötesindedir.
- Aynı üç araçlık zincir üç aktarım kurulumunda da 844 sonucunu 6 istek, 6 yanıt ve 179 zarf belirteciyle üretir; değişen tek şey gidiş-dönüştür: hepsi yerelde 6, karışımda 9, hepsi uzakta 12.
- Zarfın belirteç bedeli aktarımdan bağımsızdır; uzak aktarımın bedeli belirteç bütçesinden kısarak azaltılamaz, azaltılacak şey istek sayısıdır.
- On iki abonelik partide istek 39’da sabit kalırken gidiş-dönüş 39’dan 78’e çıkar ve fark her ölçekte tam olarak istek sayısı kadardır.
- Sürüm sapmasıyla düşen
kayitsunucusu hiçbir araç kazandırmadığı hâlde el sıkışması için yerelde 1, uzakta 2 gidiş-dönüş tüketir. - Bir aracı ağın ötesine taşımak onu paylaşılabilir yapar ve aynı hareket gidiş-dönüşü ikiye katlar; kazanç ile bedel aynı karardan çıkar.
Sonraki Adım
Üç derste bağlantının nasıl kurulduğu ölçüldü: roller adlandırıldı, sorumluluklar dağıtıldı, aktarımın fiyatı sayıldı. Mesajlar boyunca hep aynı iki tür kullanıldı — bir istek gitti, bir yanıt geldi — ve bu ikilinin dışında bir şey olup olmadığı hiç sorulmadı. Oysa el sıkışmasında yanıt bekleyen bir mesajla, karşı tarafa yalnız bir durum bildiren mesaj aynı şey değildir; ikincisi yanıtsızdır, gidiş-dönüşü yarıya indirir ve karşılığında bir şeyi görünmez kılar. Sonraki ders zarfın içine bakar: istek, yanıt ve bildirim türlerinin ayrı bedelini sayar ve yanıtsız bir mesajın neyi kazandırıp neyi sakladığını ölçer.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.