Ders 04 / 16
İçerik Dağıtım Ağları
Çekme modelinde kenar yalnız istenmiş olanı taşır ve bedeli 33 ıskadır, itme modelinde ıska sıfırdır ama kenarda hiç istenmeyen 402 birim durur; kenara 800 birimlik sınır konduğunda çekme 245, popülerliği bilmeyen itme 379 ıska verir ve iki modelde de kenarın hiç görmediği nesne 25'e çıkar.
İçindekiler
Önceki üç derste kaldıraç hep tek bir noktada durdu: isteğin geçmek zorunda olduğu yerde. Ters vekil öznelerin önünde, ileri vekil istemcilerin önünde, ama ikisi de tek bir yerde ve içeriğin tamamına erişimi olan bir yerde.
İçerik dağıtım ağı (content delivery network) bu noktayı çoğaltır: aynı içeriğin kopyaları istemcilere yakın duran birçok kenar önbelleğinde (edge cache) tutulur ve istek kaynak sunucuya kadar gitmez. Kaldıraç da değişir. Artık ayarlanan şey yükün nasıl bölüneceği değil, neyin nerede duracağıdır — ve bu kaldıracın kuyruğu, kenarın hiç görmediği içeriktir.
Kenarın Ölçtüğü Şey
Kenar önbelleğinin çalışma modelleri, hangi katmanların önbelleklenebileceği ve dağıtımın tasarım kararları Sistem Tasarımı müfredatının İçerik Dağıtım kursunda ele alındı; o tartışma burada tekrarlanmıyor. Fark tek cümledir: orada dağıtım modeli tasarım olarak karşılaştırıldı, burada tek bir yerleştirme kararının kırk nesnede bıraktığı kuyruk sayılır.
Bu dersin kurgusunda kırk özne birer içerik nesnesidir. Küme aynı kümedir; değişen tek
şey kapasite alanının okunuşudur — burada o alan nesnenin boyutudur. Kırk nesnenin
toplam boyutu, önceki derslerdeki toplam kapasiteyle aynı sayıdır.
Kenarın belirleyici özelliği kaynak sunucudan küçük olmasıdır. Küçük olmasaydı kenar olmazdı; bütün içeriği taşıyan ikinci bir kaynak sunucu olurdu. Bu yüzden her kenar önbelleği bir seçim yapmak zorundadır: kırk nesnenin hangileri orada duracak? Kaldıraç bu seçimin kuralıdır ve iki temel biçimi vardır.
Çekme ve İtme
Çekme (pull) modelinde kenar boş başlar. Bir nesne ilk kez istendiğinde kenarda yoktur; istek kaynak sunucuya gider, yanıt dönerken kenarda saklanır ve sonraki istekler oradan karşılanır. Kenar hiçbir zaman istenmemiş bir nesneyi taşımaz — ama her nesnenin ilk isteği kaçınılmaz olarak ıskalar.
İtme (push) modelinde içerik, istenmesi beklenmeden kenara yerleştirilir. İlk istek de kenardan karşılanır ve ıska sıfırlanabilir. Karşılığında kenar, hiç istenmeyecek içeriği de taşır ve onun için ayrılan yer başka bir şeye ayrılamaz.
Yapılandırma tarafında ikisi birkaç satırdır:
# öğretilen yapılandırma dökümü, çalıştırılmamıştır
kenar {
model cekme
kaynak kaynak-sunucu
saklama ilk-istekte
boyut 800 birim
tahliye en-az-kullanilan
}
kenar {
model itme
kaynak kaynak-sunucu
yerlestir yayim-aninda
boyut 800 birim
secim nesne-sirasi
}
Son satır itme modelinin asıl sorusunu taşıyor: kenar bütün içeriği alamıyorsa hangisini alacak? Çekme modeli bu soruyu sormaz, çünkü yanıtı istek akışından okur. İtme modeli sormak zorundadır ve yanıtı önceden vermek zorundadır.
Ölçümün varsayımları:
- TY21 — Kırk özne kursun sabit kümesidir. Bu derste her özne bir içerik nesnesidir ve
kapasitealanı onun boyutu olarak okunur; küme değişmez, okuma değişir. - TY22 — İstek akışı altı yüz istekten oluşur ve popülerliği çarpıktır: az sayıda nesne isteklerin çoğunu alır, kuyruktaki nesneler hiç istenmez.
- TY23 — Popülerlik sırası nesne numarasından bağımsızdır. Sıra ayrı bir tohumla karılır; böylece nesne numarasına göre seçim yapan bir itme kuralı popülerlik hakkında hiçbir bilgi taşımaz.
- TY24 — Kenarda duran nesne için ıska yoktur; olmayan nesne için istek kaynak sunucuya gider ve bir ıska sayılır. Nesnelerin tazelik ömrü bu ölçümde sonsuzdur; saklanan kopya eskimez.
- TY25 — Sınırlı kenarda tahliye kuralı en az kullanılandır: yer açmak gerektiğinde en uzun süredir istenmemiş nesne çıkarılır.
- TY26 — Sınırlı itme, nesneleri numara sırasına göre seçer; bu, popülerliği bilmeyen bir yerleştirmenin en yalın biçimidir.
- TY27 — Ölçüm bir ağ ölçümü değildir; hiçbir istek gönderilmez, hiçbir kenar kurulmaz. Sayılan şey kurgudaki yerleştirmenin kendisidir.
Ölçüm
"""Kenar onbellegi: cekme ilk istegi bekler, itme hic istenmeyeni tasir.""" TOHUM = 20260812 SINIFLAR = ("etkilesim", "toplu", "yedek") KENAR = 800 def uretec(tohum): d = tohum % 2147483646 + 1 def r(n): nonlocal d d = (d * 48271) % 2147483647 return d % n return r def ozneler(sayi=40, tohum=TOHUM): r, liste = uretec(tohum), [] for i in range(sayi): liste.append({"no": i + 1, "kapasite": 20 + r(81), "gecikme": 5 + r(45), "sinif": SINIFLAR[r(3)], "ozel": r(9) == 0}) return liste def populerlik(oz, tohum=TOHUM + 17): """Populerlik sirasi nesne numarasindan bagimsizdir.""" r, sira = uretec(tohum), [o["no"] for o in oz] for i in range(len(sira) - 1, 0, -1): j = r(i + 1) sira[i], sira[j] = sira[j], sira[i] return sira def istekler(oz, sayi=600, tohum=TOHUM + 23): """Populerligi carpik istek akisi: kuyrukta hic istenmeyen nesneler kalir.""" r, sira, liste = uretec(tohum), populerlik(oz), [] for _ in range(sayi): liste.append(sira[min(r(len(oz)), r(len(oz)), r(len(oz)))]) return liste def cekme(oz, ist, sinir): """Nesne ilk istendiginde kenara girer; sinir varsa en eski kullanilan cikar.""" boy = {o["no"]: o["kapasite"] for o in oz} kenar, kullanim, iska = [], 0, 0 for n in ist: if n in kenar: kenar.remove(n) kenar.append(n) continue iska += 1 if sinir is not None: while kullanim + boy[n] > sinir and kenar: kullanim -= boy[kenar.pop(0)] if kullanim + boy[n] > sinir: continue kenar.append(n) kullanim += boy[n] return set(kenar), kullanim, iska def itme(oz, ist, sinir): """Kirk nesne onceden itilir; sinir varsa numara sirasina gore secilir.""" boy, kenar, kullanim = {o["no"]: o["kapasite"] for o in oz}, set(), 0 for o in oz: if sinir is None or kullanim + o["kapasite"] <= sinir: kenar.add(o["no"]) kullanim += o["kapasite"] return kenar, kullanim, sum(1 for n in ist if n not in kenar) oz = ozneler() ist = istekler(oz) boy = {o["no"]: o["kapasite"] for o in oz} istenen = set(ist) print(f"nesne {len(oz)} | toplam boyut {sum(boy.values())} | kenar sınırı {KENAR} birim") print(f"istek {len(ist)} | istenen nesne {len(istenen)} | " f"hiç istenmeyen {len(oz) - len(istenen)} " f"({sum(boy[o['no']] for o in oz if o['no'] not in istenen)} birim)") print() print(f"{'model':<22s} {'kenardaki':>10s} {'kullanılan':>11s} {'ıska':>6s} " f"{'isabet':>7s} {'kenarın görmediği':>18s} {'boşa duran':>11s}") for ad, kenar, kullanim, iska in ( ("çekme, sınırsız", *cekme(oz, ist, None)), ("çekme, sınırlı", *cekme(oz, ist, KENAR)), ("itme, sınırsız", *itme(oz, ist, None)), ("itme, sınırlı", *itme(oz, ist, KENAR))): print(f"{ad:<22s} {len(kenar):10d} {kullanim:11d} {iska:6d} {len(ist) - iska:7d} " f"{len(oz) - len(kenar):18d} " f"{sum(boy[n] for n in kenar if n not in istenen):11d}")
nesne 40 | toplam boyut 2336 | kenar sınırı 800 birim istek 600 | istenen nesne 33 | hiç istenmeyen 7 (402 birim) model kenardaki kullanılan ıska isabet kenarın görmediği boşa duran çekme, sınırsız 33 1934 33 567 7 0 çekme, sınırlı 15 788 245 355 25 0 itme, sınırsız 40 2336 0 600 0 402 itme, sınırlı 15 798 379 221 25 30
İlk İsteğin Bedeli
Çekme modelinin sınırsız satırı, modelin saf hâlini gösteriyor. Altı yüz isteğin 33’ü ıskalıyor ve bu sayı bir tesadüf değil: istenen nesne sayısı da 33. Çekme modelinde her nesne tam olarak bir kez ıskalar — ilk istendiğinde. Geri kalan 567 istek kenardan karşılanıyor.
Bu modelin kuyruğu bu yüzden çok belirli bir kuyruktur: her nesnenin ilk isteyeni. O istek kaynak sunucuya kadar gider, en uzun gecikmeyi görür ve bir sonraki isteyen için yolu açar. Kuyrukta olmak burada bir kusur değil, modelin çalışma biçimidir; ama kuyrukta olanın kim olduğu önemlidir.
Bu kuyruk eşit dağılmaz. Popüler bir nesnede tek ıska yüzlerce isabetin arasında kaybolur ve o nesneyi isteyenlerin neredeyse hiçbiri bedeli ödemez. Nadiren istenen bir nesnede ise her isteyen pratikte ilk isteyendir: iki istek arasındaki süre saklamanın ömründen uzunsa, kopya her seferinde yeniden getirilir. Yani çekme modelinin bedelini asıl ödeyen, zaten en az hizmet alan azınlıktır — ve toplam isabet oranına bakan bir gösterge bu azınlığı hiç göstermez, çünkü 567 isabetin yanında 33 ıska iyi bir orandır.
Sağdaki sütun ikinci sayıyı veriyor: kenarın hiç görmediği nesne 7. Kırk nesnenin yedisi altı yüz istek boyunca bir kez bile istenmedi ve çekme modeli onları kenara hiç almadı. Bu, modelin kendi ölçüsüne göre kusursuz bir davranıştır — boşa duran birim 0. Kenarda ne varsa istenmiştir.
Hiç İstenmeyenin Bedeli
İtme modelinin sınırsız satırı, çekmenin ödediği bedeli sıfırlıyor: ıska 0, altı yüz isteğin altı yüzü kenardan karşılanıyor. İlk isteyen diye bir kuyruk kalmıyor.
Bedel sağdaki sütunda duruyor. Kenar 2336 birimin tamamını taşıyor, ama bunun 402 birimi hiç istenmeyen yedi nesneye ait. Kenar alanının yaklaşık altıda biri, altı yüz istek boyunca bir kez bile okunmayan içerikle dolu.
İki modelin kuyruğu bu yüzden birbirinin tersidir. Çekmenin kuyruğu zamandadır: nesne kenara girene kadar geçen ilk istek. İtmenin kuyruğu yerdedir: kenarda duran ama hiç okunmayan içerik. Birini sıfırlayan model ötekini büyütür ve ikisini birden sıfırlayan bir model yoktur — çünkü neyin isteneceğini önceden bilmenin yolu yoktur.
Sınır Konduğunda
Üstteki iki satır kenarın sınırsız olduğunu varsayıyordu ve bu varsayım kenarın tanımına aykırıdır. Alt satırlar 800 birimlik gerçekçi bir sınırla aynı ölçümü yineliyor.
Çekme modelinde ıska 33’ten 245’e çıkıyor. Sebep tahliyedir: kenar dolduğunda en az kullanılan nesne çıkarılır ve çıkarılan nesne yeniden istendiğinde yeniden ıskalar. Artık “her nesne bir kez ıskalar” kuralı geçerli değil; bir nesne kenara girip çıktığı kadar ıskalar. Kenarın hiç görmediği nesne de 7’den 25’e çıkıyor — çünkü kenarda hiç yer bulamayan nesneler var.
İtme modelinde aynı sınır daha ağır ödetiyor: ıska 379. Altı yüz isteğin yarısından
fazlası kaynak sunucuya gidiyor. Sebep açıktır ve TY23 ile TY26 tam olarak bunu ölçmek
için konmuştu: itme kuralı nesneleri numara sırasına göre seçiyor, numara sırası ise
popülerlikle ilgisiz. Kenar 798 birim doluyor, kırkta 15 nesne taşıyor — çekmeyle
neredeyse aynı doluluk — ama yanlış on beş nesneyi taşıyor.
Üstüne, sınırlı itme hâlâ 30 birimlik hiç istenmeyen içerik taşıyor. Yer kıtken bile kaldıraç, kıt yerin bir kısmını kimsenin istemediği şeye ayırıyor.
Buradaki asıl ders yerleştirme kuralının kendisiyle ilgilidir. İtme modeli bir tahmin gerektirir ve tahminin yanlışlığı ölçülmedikçe görünmez. Çekme modeli tahmin gerektirmez; karşılığında her yeni nesne için bir ıska öder ve bu bedel her zaman görünür. Kırk nesnelik bir kümede ölçülebilen en küçük fark 1/40 = 0,025’tir; 245 ile 379 arasındaki fark bunun çok üstündedir ve iki modelin sıralaması bu kümeyle savunulabilir.
Kenar Tek Değildir
Ölçüm tek bir kenar önbelleği modelledi ve bu, içerik dağıtım ağının tanımına aykırıdır: ağ, kenarı çoğalttığı için ağdır. Çoğalmanın iki modele etkisi de doğrudandır.
Çekme modelinde ilk isteğin bedeli kenar başına ödenir. Her kenar kendi ilk isteğini kendisi ıskalar, çünkü bir kenarın sakladığı kopya öteki kenarda yoktur. Ölçümdeki 33 ıska tek bir kenarın soğuk başlangıcıdır; kenar sayısı arttıkça bu bedel onunla birlikte çarpılır. Aynı nesneyi isteyen iki istemci ayrı kenarlara düşerse ikisi de ilk isteyendir.
Bu, çekme modelinin en sık gözden kaçan maliyetidir: kenar eklemek istemcinin gördüğü gecikmeyi düşürür ama kaynak sunucuya düşen ıska sayısını artırır. Kenar sayısını artırmak kuyruğu kaldırmaz, çoğaltır — önceki derslerdeki örüntünün aynısı.
İtme modelinde çarpım yerde görünür. Hiç istenmeyen 402 birim her kenarda ayrı ayrı durur; kırk nesneyi çok sayıda kenara itmek, kimsenin istemediği içeriği de o kadar kez taşımak demektir.
Aradaki dengeyi kuran ara biçim, kenarların kaynak sunucudan değil birbirinden ya da ortak bir üst katmandan çekmesidir. İlk isteyen yine ıskalar, ama ıska kaynak sunucuya değil daha yakın bir kopyaya gider. Kaldıraç yine tektir: hangi kenarın kimden çekeceği tek bir kuralla yazılır ve kırk nesnenin kırkına birden uygulanır.
Saklananın Eskimesi
TY24 ölçümde saklanan kopyanın eskimediğini varsaydı ve bu varsayımın gerçek olmadığını
söylemek gerekir. İçerik değişirse kenardaki kopya yanlışa döner ve kenar bunu kendiliğinden
bilmez.
Bunu kapatan şey üçüncü bir kaldıraçtır: geçersiz kılma. İçerik değiştiğinde kenarlardaki kopyalarının düşürülmesi gerekir ve bu da tek bir karardır — hangi nesnelerin, hangi kenarlarda düşürüleceği tek bir kuralla yazılır.
Kuyruğu iki uçludur ve artık tanıdıktır. Kural dar yazılırsa değişmiş içeriğin eski kopyası kenarda kalır ve her isteyene yanlış yanıt verilir; üstelik böyle bir kopya, ona bakılmadığı sürece hiçbir belirti vermez. Kural geniş yazılırsa — örneğin her yayımda kenarın tamamı düşürülürse — hiç değişmemiş nesneler de kenardan çıkar ve çekme modelinin ilk istek bedeli baştan ödenir. Ölçümdeki 33 ıska, geniş bir geçersiz kılma kuralında her yayımda yeniden doğar; sınırlı kenardaki 245 ise tahliye ile geçersiz kılmanın üst üste binmesiyle daha da büyür.
Tazelik ömrü, doğrulayıcı alanlar ve önbellek direktiflerinin kendisi Sunucu Tarafı ve Uygulama Katmanı Protokolleri kurslarında ölçüldü; burada tekrarlanmıyor. Bu dersin ekseninde önemli olan, geçersiz kılmanın da tek karar, çok özne biçiminde olması ve kuyruğunun iki ucunun birlikte kapanmamasıdır.
Özet
- İçerik dağıtım ağı kaldıracı yükü değil yerleştirmeyi ayarlar: kırk nesneden hangilerinin kenarda duracağını. Kuyruk, kenarın hiç görmediği içeriktir.
- Çekme modelinde her nesne tam bir kez ıskalar: 33 istenen nesne, 33 ıska, 567 isabet, boşa duran birim 0; kenar yalnız istenmiş olanı taşır.
- İtme modelinde ıska 0’dır ama kenarda hiç istenmeyen 402 birim durur; iki modelin kuyruğu birbirinin tersidir — biri zamanda, öteki yerde.
- 800 birimlik sınır çekmede ıskayı 33’ten 245’e çıkarır; tahliye edilen nesne yeniden istendiğinde yeniden ıskalar ve kenarın hiç görmediği nesne 7’den 25’e çıkar.
- Aynı sınırda popülerliği bilmeyen itme 379 ıska verir: 798 birimle çekmeyle aynı kadar dolu, ama yanlış 15 nesneyle dolu ve üstüne 30 birimi hiç istenmeyen içerik.
- İtme bir tahmin gerektirir ve tahminin yanlışlığı ölçülmedikçe görünmez; çekme tahmin gerektirmez ve bedelini her zaman görünür biçimde öder.
Sonraki Adım
Bu derse kadarki dört kaldıraç da tek bir soruyu farklı biçimlerde sordu: iş nereye gitsin? Dengeleyici özneye, vekil kime ait olduğuna, kenar hangi kopyaya. Hiçbiri işlerin birbirinden farklı önemde olabileceğini hesaba katmadı; kırk özne de aynı sırada bekliyordu. Sonraki ders bu varsayımı kaldırır: trafik sınıflara ayrılır, bir sınıf öne alınır ve öteki bekletilir. Ölçü de doğrudan bunu sorar — bir sınıfın kazandığı gecikme kimin kuyruğundan alınmıştır, ve iki sayı her zaman birlikte yazılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.