Ders 02 / 21
Sunucu, Sanal Makine, Konteyner
Üç yalıtım düzeyi aynı ölçütlerle karşılaştırılır: hangisi neyi ayırır, neyi yineler, karşılığında kaç megabayt bellek tabanı ve hangi mertebede başlangıç gecikmesi ister, tek makineye kaç örnek sığar.
İçindekiler
Önceki ders farkın 6’sını ortamdan çıkardı ve bunun bedelini bayt cinsinden ölçtü: en küçük tabanla 84,11 MB’lık bir çıktı. O ölçüm tek bir çıktıyı ele alıyordu. Kurgudaki bölgesel ölçüm ağında ise beş servis var — okuma toplayıcı, doğrulayıcı, faturalama, iş emri ve gecelik toplu iş — ve hepsi aynı makinede koşuyor. Her biri kendi çözümleyicisini, kendi kural paketini ve kendi saat dilimi tablosunu getirdiğinde soru değişir: bu beş çıktı aynı makinede yan yana durduğunda birbirlerinden ne kadar ayrıdır?
Ayrılığın adı yalıtımdır ve tek bir şey değildir. Bir uygulamanın diğerinin dosyalarını görememesi ayrı bir şeydir, süreçlerini durduramaması ayrı, belleğini tüketememesi ayrı. Bu ders üç yalıtım düzeyini — paylaşılan sunucu, konteyner ve sanal makine — aynı ölçütlerle karşılaştırır: neyi ayırıyorlar, neyi yineliyorlar, karşılığında ne istiyorlar.
KK7. Karşılaştırma tek makine ölçeğindedir; birden çok makineye dağıtım bu kursun konusu değildir. KK8. Aşağıdaki bütün sayılar model girdisidir, ölçülmüş bir kurulumdan gelmez; anlamlı olan iki düzey arasındaki mertebe farkıdır, tek bir hücredeki değer değil. KK9. Beş ölçüt vardır ve her ölçüt ikili değer alır: ayrılır ya da paylaşılır. Kısmi yalıtım tam sayılmaz.
Aynı Ölçütlerle Üç Düzey
Ölçütler, yalıtımın delinebileceği yerlerin adlarıdır. Çekirdek: iki uygulama aynı çekirdeği mi çağırıyor. Dosya sistemi: biri diğerinin dosyalarını görebiliyor mu. Ağ: aynı arayüz ve aynı kapı uzayı mı. Süreç tablosu: biri diğerinin süreçlerini listeleyip durdurabiliyor mu. Kullanıcı: dosya sahipliği ve yetki aynı hesaba mı bağlı.
// olcum-agi/duzeyler.mjs — uc yalitim duzeyinin ayni olcutlerle karsilastirilmasi // MODEL: butun sayilar bildirilen model girdisidir, olculmus bir kurulumdan gelmez. // Karsilastirma mertebe duzeyindedir; iki duzey arasindaki oran anlamlidir, tek // bir hucredeki deger degil. export const OLCUT = ["cekirdek", "dosyaSistemi", "ag", "surecTablosu", "kullanici"]; export const DUZEY = { "paylasilan sunucu": { yalitir: { cekirdek: false, dosyaSistemi: false, ag: false, surecTablosu: false, kullanici: true }, yineler: { isletimSistemiKopyasi: 0, kutuphaneKumesi: 0 }, baslangicMs: 30, bellekTabaniMB: 4, diskTabaniMB: 0, }, "konteyner": { yalitir: { cekirdek: false, dosyaSistemi: true, ag: true, surecTablosu: true, kullanici: true }, yineler: { isletimSistemiKopyasi: 0, kutuphaneKumesi: 1 }, baslangicMs: 300, bellekTabaniMB: 12, diskTabaniMB: 84, }, "sanal makine": { yalitir: { cekirdek: true, dosyaSistemi: true, ag: true, surecTablosu: true, kullanici: true }, yineler: { isletimSistemiKopyasi: 1, kutuphaneKumesi: 1 }, baslangicMs: 25_000, bellekTabaniMB: 512, diskTabaniMB: 1_240, }, }; // Onceki dersin 18 farkindan kacinin ortamdan cikarildigi (girdi: 01'in kova sayimi). export const KAPATILAN = { "paylasilan sunucu": [0, "kutuphaneler paylasilir; iceri kovasindaki alti fark ortamda kalir"], "konteyner": [6, "iceri kovasindaki alti fark ciktinin icine girer"], "sanal makine": [7, "cekirdek de icerde oldugu icin ad eslestirme kurali da kapanir"], }; export const ADLAR = Object.keys(DUZEY); export const yalitilan = (d) => OLCUT.filter((o) => DUZEY[d].yalitir[o]); // Dokum yalniz bu dosya dogrudan kosturuldugunda basilir; sonraki blok modulu // veri icin ice aktarir ve bu bolumu yeniden basmaz. if (import.meta.main) { console.log("yalitilan sey (+ ayrilir, - paylasilir)"); console.log("olcut".padEnd(16) + ADLAR.map((d) => d.padEnd(20)).join("")); for (const o of OLCUT) console.log(o.padEnd(16) + ADLAR.map((d) => (DUZEY[d].yalitir[o] ? "+" : "-").padEnd(20)).join("")); console.log("yalitilan/5".padEnd(16) + ADLAR.map((d) => `${yalitilan(d).length}/5`.padEnd(20)).join("")); console.log("\nyinelenen sey (ornek basina kac kopya)"); for (const y of ["isletimSistemiKopyasi", "kutuphaneKumesi"]) console.log(y.padEnd(24) + ADLAR.map((d) => String(DUZEY[d].yineler[y]).padEnd(20)).join("")); console.log("\nortamdan cikarilan fark (18'in kaci):"); for (const d of ADLAR) console.log(" " + d.padEnd(20) + `${KAPATILAN[d][0]}/18 ` + KAPATILAN[d][1]); console.log("\npaylasilan sey (delik):"); for (const d of ADLAR) { const delik = OLCUT.filter((o) => !DUZEY[d].yalitir[o]); console.log(" " + d.padEnd(20) + (delik.length ? delik.join(", ") : "olcutlerin hicbiri")); } }
yalitilan sey (+ ayrilir, - paylasilir) olcut paylasilan sunucu konteyner sanal makine cekirdek - - + dosyaSistemi - + + ag - + + surecTablosu - + + kullanici + + + yalitilan/5 1/5 4/5 5/5 yinelenen sey (ornek basina kac kopya) isletimSistemiKopyasi 0 0 1 kutuphaneKumesi 0 1 1 ortamdan cikarilan fark (18'in kaci): paylasilan sunucu 0/18 kutuphaneler paylasilir; iceri kovasindaki alti fark ortamda kalir konteyner 6/18 iceri kovasindaki alti fark ciktinin icine girer sanal makine 7/18 cekirdek de icerde oldugu icin ad eslestirme kurali da kapanir paylasilan sey (delik): paylasilan sunucu cekirdek, dosyaSistemi, ag, surecTablosu konteyner cekirdek sanal makine olcutlerin hicbiri
Matris üç düzeyi tek bir eksene dizer: 1/5, 4/5, 5/5. Paylaşılan sunucuda beş ölçütten yalnız biri ayrılır — kullanıcı hesabı — ve bu tek ayrım da dosya izinlerinin doğru kurulmuş olmasına bağlıdır. Konteyner dört ölçütü ayırır ve çekirdeği paylaşır. Sanal makine beşini de ayırır, çünkü kendi çekirdeğini taşır.
Yinelenen şey sütunu bu dizilimin nedenini verir. Paylaşılan sunucu hiçbir şeyi yinelemez; kütüphaneler ortaktır, dolayısıyla ortam farkının tümü ortamda kalır — önceki dersin altı farkı kapanmaz. Konteyner kütüphane kümesini örnek başına bir kez yineler, işletim sistemi kopyasını yinelemez. Sanal makine ikisini de yineler. Ortamdan çıkarılan fark bu sıralamayı izler: 0, 6 ve 7. Sanal makinenin yedinci farkı, çekirdeği de içine aldığı için kapattığı boyuttur — dosya adı eşleştirme kuralı önceki derste sınır kovasındaydı; çekirdek içeri girince o da kapanır.
Ortadaki düzey bir uzlaşma değildir; belirli bir ölçütü ayırmaktan vazgeçmenin adıdır. Konteynerin paylaşılan sunucudan satın aldığı üç ölçüt vardır: dosya sistemi, ağ ve süreç tablosu. Sanal makineden vazgeçtiği ölçüt tektir: çekirdek. Üç düzey arasındaki fark bu iki sayıda toplanır ve ikisi de tabloda yazılıdır. Ölçütlerin ikili değer alması (KK9) burada bir sadeleştirmedir: gerçekte bir ölçüt kısmen de ayrılabilir — kullanıcı hesabı ayrıdır ama kök yetkisi ortak kalabilir, ağ uzayı ayrıdır ama aynı fiziksel arayüzü kullanır. Bu ara durumlar tabloda “ayrılır” görünür ve tablonun okuduğundan daha az yalıtım sağlar; sonraki derslerin ölçtüğü şeylerden biri tam olarak budur.
Bedelin Mertebesi
Yalıtım satın alınan bir şeydir ve ödemesi üç kalemde yapılır: başlangıç gecikmesi, bellek tabanı, disk tabanı.
KK10. Bellek tabanı, uygulamanın kendi belleği dışında yalıtım düzeyinin getirdiği ektir. KK11. Makine 16.384 MB’dır, 1.024 MB’ı işletim sistemine ayrılmıştır ve örnek başına uygulama belleği 180 MB’dır. KK12. Örnekler sırayla başlatılır; koşut başlatma modellenmez.
// olcum-agi/mertebe.mjs — yalitim bedelinin mertebesi ve yogunluga cevrilmesi import { DUZEY, ADLAR, yalitilan } from "./duzeyler.mjs"; const mertebe = (n) => (n <= 0 ? "-" : "10^" + Math.round(Math.log10(n))); const MAKINE_MB = 16_384, AYRILAN_MB = 1_024, UYGULAMA_MB = 180, ORNEK = 25; console.log("bedel ve mertebesi (model girdisi)"); console.log("duzey".padEnd(20) + "baslangic".padEnd(14) + "mertebe".padEnd(9) + "bellek tabani".padEnd(15) + "mertebe".padEnd(9) + "disk tabani"); for (const d of ADLAR) { const v = DUZEY[d]; console.log(d.padEnd(20) + `${v.baslangicMs} ms`.padEnd(14) + mertebe(v.baslangicMs).padEnd(9) + `${v.bellekTabaniMB} MB`.padEnd(15) + mertebe(v.bellekTabaniMB).padEnd(9) + `${v.diskTabaniMB} MB`); } const taban = ADLAR.map((d) => DUZEY[d].bellekTabaniMB); console.log("bellek tabani orani (en kucuge gore): " + ADLAR.map((d, i) => `${d} ${Math.round(taban[i] / taban[0])}x`).join(", ")); console.log("\nyalitilan boyut basina bellek tabani"); for (const d of ADLAR) { const k = yalitilan(d).length; console.log(" " + d.padEnd(20) + `${k} boyut ` + `${(DUZEY[d].bellekTabaniMB / k).toFixed(1)} MB/boyut`); } console.log(`\n${MAKINE_MB} MB'lik tek makine, ${AYRILAN_MB} MB ayrilmis, ` + `ornek basina uygulama ${UYGULAMA_MB} MB`); for (const d of ADLAR) { const ornekMB = UYGULAMA_MB + DUZEY[d].bellekTabaniMB; const sigan = Math.floor((MAKINE_MB - AYRILAN_MB) / ornekMB); const yuk = ((DUZEY[d].bellekTabaniMB / ornekMB) * 100).toFixed(1); console.log(" " + d.padEnd(20) + `ornek ${String(ornekMB).padStart(4)} MB ` + `sigan ${String(sigan).padStart(3)} yalitim yuku %${yuk}`); } console.log(`\n${ORNEK} ornegin sirayla baslatilmasi ve tasidigi disk`); for (const d of ADLAR) { const sn = (DUZEY[d].baslangicMs * ORNEK) / 1000; console.log(" " + d.padEnd(20) + `${sn.toFixed(2).padStart(8)} sn ` + `disk ${String(DUZEY[d].diskTabaniMB * ORNEK).padStart(5)} MB ` + `yalitilan ${yalitilan(d).length}/5`); }
bedel ve mertebesi (model girdisi) duzey baslangic mertebe bellek tabani mertebe disk tabani paylasilan sunucu 30 ms 10^1 4 MB 10^1 0 MB konteyner 300 ms 10^2 12 MB 10^1 84 MB sanal makine 25000 ms 10^4 512 MB 10^3 1240 MB bellek tabani orani (en kucuge gore): paylasilan sunucu 1x, konteyner 3x, sanal makine 128x yalitilan boyut basina bellek tabani paylasilan sunucu 1 boyut 4.0 MB/boyut konteyner 4 boyut 3.0 MB/boyut sanal makine 5 boyut 102.4 MB/boyut 16384 MB'lik tek makine, 1024 MB ayrilmis, ornek basina uygulama 180 MB paylasilan sunucu ornek 184 MB sigan 83 yalitim yuku %2.2 konteyner ornek 192 MB sigan 80 yalitim yuku %6.3 sanal makine ornek 692 MB sigan 22 yalitim yuku %74.0 25 ornegin sirayla baslatilmasi ve tasidigi disk paylasilan sunucu 0.75 sn disk 0 MB yalitilan 1/5 konteyner 7.50 sn disk 2100 MB yalitilan 4/5 sanal makine 625.00 sn disk 31000 MB yalitilan 5/5
Mertebeler okunduğunda tablo iki kümeye ayrılır. Bellek tabanı mertebesinde paylaşılan sunucu ile konteyner aynı yerdedir: ikisi de 10^1. Sanal makine iki mertebe yukarıdadır: 10^3. Başlangıç gecikmesinde ise konteyner tek mertebe yukarı çıkar (10^2), sanal makine üç mertebe (10^4). Yani konteynerin paylaşılan sunucudan ayrıldığı yer bellek değil, başlangıç ve disktir; sanal makinenin ikisinden de ayrıldığı yer her üç kalemdir.
Yalıtılan boyut başına düşen bellek tabanı bunu tek sayıya indirir. Paylaşılan sunucu 4,0 MB/boyut, konteyner 3,0 MB/boyut, sanal makine 102,4 MB/boyut. Konteynerin birim başına en ucuz düzey olması, çekirdeği yinelemeden dört boyut ayırabilmesinden gelir. Sanal makine ise beş boyutun beşini de ayırır ama beşinci boyutu — çekirdeği — ayırmanın bedeli tek başına diğer dördünün toplamının kırk katıdır. Birim ölçüsünün paylaşılan sunucuyu konteynerin altına düşürmesi ilk bakışta ters görünür, çünkü paylaşılan sunucunun toplam bedeli daha küçüktür. Ters görünen şey bölenin değişmesidir: 4 MB tek bir boyuta bölünür, 12 MB dörde. Toplam bedele bakan bir karşılaştırma “en ucuz düzey hangisi” sorusunu, birim bedele bakan bir karşılaştırma ise “ayrılan boyut başına ne ödeniyor” sorusunu yanıtlar; yalıtım bütçesinde ikinci soru karar taşır, çünkü satın alınan şey bayt değil ayrılan ölçüttür. İki soru aynı tablodan okunur ve birbirinin yerine geçmez.
Yoğunluk sayımı bunu koşum tarafına çevirir. Aynı 16 GB’lık makineye paylaşılan sunucuda 83, konteynerde 80, sanal makinede 22 örnek sığar. Yalıtım yükü — belleğin ne kadarının uygulamaya değil, yalıtıma gittiği — sırasıyla %2,2, %6,3 ve %74,0’tür. Sanal makinede belleğin dörtte üçünden fazlası uygulamanın kendisine gitmez. Yirmi beş örneğin sırayla başlatılması 0,75 saniye, 7,50 saniye ve 625 saniye sürer; taşınan disk 0, 2.100 ve 31.000 MB’dır.
Yirmi beş sayısı kurgudan gelir: beş servisin beşer kopyası. Başlangıç süresinin karar taşıdığı yer de oradadır. Gecelik toplu iş her gece bir kez başlar ve 625 saniye onun için tolere edilebilir bir sayıdır; okuma toplayıcı ise bir kusur sonrası yeniden başlatıldığında saha ekiplerinin beklediği süredir ve orada 7,50 saniye ile 625 saniye arasındaki fark bir kesinti süresidir. Aynı model girdisi iki servis için iki ayrı anlam taşır — bu yüzden başlangıç gecikmesi tek bir eşikle değil, o düzeyde koşan işin yeniden başlatma sıklığıyla birlikte okunur. Disk kalemi de aynı biçimde çarpılır: 84 MB’lık bir çıktı yirmi beş örnekte 2.100 MB’a çıkar ve bu sayı, katmanların paylaşılıp paylaşılmadığına göre değişir; paylaşımın nasıl çalıştığı sonraki dersin konusudur.
Yalıtımın Delindiği Yer
Matrisin son bölümü her düzeyin deliğini adlandırır. Paylaşılan sunucuda dört ölçüt açıktır: çekirdek, dosya sistemi, ağ ve süreç tablosu. Kurgudaki ağda bu şu demektir — gecelik toplu iş bir tarife dosyasını yanlış yola yazarsa doğrulayıcı onu okur; faturalama servisi bir kapıyı tutarsa iş emri servisi aynı kapıyı açamaz; biri belleği tüketirse hepsi birden durur.
Konteynerde delik tektir ve adı çekirdektir. Beş servis kendi dosya sistemini, kendi ağ uzayını, kendi süreç tablosunu ve kendi kullanıcısını görür; ama beşi de aynı çekirdeğe sistem çağrısı yapar. Bunun üç sonucu vardır. Önceki dersin ölçtüğü saat değeri hâlâ ortaktır: beş servis aynı saati okur, saat dilimi ayarı çıktının içindedir ama saatin kendisi değildir. Çekirdek sürümü ortaktır: bir servisin ihtiyaç duyduğu çekirdek davranışı diğerlerini de ilgilendirir. Ve çekirdekteki bir kusur beş yalıtımın altından birden geçer — dört ölçütün ayrılmış olması bu yolu kapatmaz.
Disk tabanı sütunundaki sıfır da bir deliğin işaretidir. Paylaşılan sunucu hiçbir şey taşımadığı için hiçbir bayt ödemez; ödemediği şey ortam farkının kapatılmasıdır. Bu üç kalemin hepsinde en ucuz düzey olması bir üstünlük değil, hiçbir şey satın almamış olmasının sonucudur. Bedel tablosu tek başına okunduğunda paylaşılan sunucu her satırda kazanır; ölçüt tablosuyla birlikte okunduğunda 1/5 ile 0/18’i de birlikte taşıdığı görünür. Yalıtım bütçesinin iki tabloyu ayrı ayrı değil yan yana okumayı gerektirmesinin nedeni budur.
Sanal makinede ölçütlerin hiçbiri açık değildir; delik ölçüt tablosunda görünmez, bedel tablosunda görünür. 102,4 MB/boyut ve 10^4 mertebesinde başlangıç, yalıtımın tam olmasının fiyatıdır. Üç düzey arasındaki seçim bu yüzden “hangisi daha iyi” sorusu değildir: hangi ölçütün ayrılması gerektiği sorusudur ve ayrılmayan her ölçüt bir hata sınıfını açık bırakır.
Özet
- Yalıtım tek bir şey değil, beş ölçütün her birinde ayrı ayrı verilen bir karardır: çekirdek, dosya sistemi, ağ, süreç tablosu, kullanıcı.
- Üç düzey sırasıyla 1/5, 4/5 ve 5/5 ölçüt ayırır. Yinelenen şey bu sıralamayı belirler: paylaşılan sunucu hiçbir şeyi, konteyner kütüphane kümesini, sanal makine kütüphane kümesi ile işletim sistemi kopyasını yineler.
- Ortamdan çıkarılan fark düzeye bağlıdır: paylaşılan sunucuda 0/18, konteynerde 6/18, sanal makinede 7/18. Yedincisi çekirdek içeri girdiği için kapanan dosya adı eşleştirme kuralıdır.
- Bedel mertebe olarak yazılır: bellek tabanı 10^1, 10^1 ve 10^3; başlangıç 10^1, 10^2 ve 10^4. Yalıtılan boyut başına bellek tabanı 4,0, 3,0 ve 102,4 MB’dır — konteyner birim başına en ucuz düzeydir.
- Aynı makineye 83, 80 ve 22 örnek sığar; yalıtım yükü %2,2, %6,3 ve %74,0’tür. Konteynerin deliği tektir ve adı çekirdektir: saat değeri, çekirdek sürümü ve çekirdek kusuru dört ölçütün altından birden geçer.
Sonraki Adım
Bu ders konteynerin dört ölçütü ayırdığını yazdı ama nasıl ayırdığını hiç sormadı. Aynı çekirdek üzerinde koşan iki süreçten biri diğerinin süreçlerini nasıl görmüyor — süreç tablosu tek bir tablo olduğuna göre, “görmemek” ne demek? Aynı şey bellek sınırı için de geçerli: sınırı uygulayan denetim grubuysa, sınır aşıldığında verilen karar nedir? Ve beş servis aynı kütüphane kümesini taşıyorsa, aynı dosyalar diske beş kez mi yazılıyor? Sonraki ders bu üç soruya karşılık gelen üç mekanizmayı ayrı ayrı modeller — ad alanı bir görünürlük eşlemesi, denetim grubu bir pay dağıtıcı, birleşim dosya sistemi bir katman yığını olarak — ve her birinin yalıtımı nerede deldiğini yazar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.