Ders 05 / 11
Kaynak Yöneticileri
Bir işin küme üzerinde zamanlanmasında görev sayısı ile eşzamanlı görev sayısının ayrı iki düğme olduğunun ve her görevin elli birimlik sabit bedelinin nereye gittiğinin sayılması: tek görev tek yuvada süre 2250 ve sabit bedel 50 iken on altı görev on altı yuvada süre 215'e iniyor ama sabit bedel 800'e çıkıyor, eşzamanlılığı büyütmek sabit bedeli hiç değiştirmezken görev sayısını büyütmek onu görev başına elli birim artırıyor, aynı eşzamanlılıkta işi daha çok göreve bölmek süreyi 611'den 950'ye yükseltiyor, süre kazancı sekiz görevden on altıya geçerken 121'de kalıp eklenen 400 birimlik sabit bedele yeniliyor, ve aynı kümede iki iş çalıştığında öncelikli ile paylaşımlı politika bitiş sıralarını değiştiriyor ama ödenen 600 birimlik sabit bedeli değiştirmiyor.
İçindekiler
Önceki ders hangi hesabın koşacağına karar verdi ve koşmayanı saydı, ama o hesabı kimin
koşturacağına hiç dokunmadı. Bölümler işçilere sırayla verildi, işçi sayısı dört kabul edildi ve
süre hesabına GOREV_SABIT sessizce bir kez eklendi. Gerçek bir kümede bu üç şeyin hiçbiri
sürücünün elinde değildir.
Bu ders arada duran bileşeni ölçer: kaynak yöneticisi (resource manager). Sürücü bir iş gönderir, kaynak yöneticisi işi kaç göreve böleceğine, kaç görevin aynı anda koşacağına ve bekleyen bir işin ne zaman sıra alacağına karar verir. Ölçülen sayı şudur: her görevin 50 birimlik sabit bedeli varken görev sayısını ve eşzamanlılığı büyütmek süreyi nereye kadar düşürür, ve kazanç nerede bu bedele yenilir.
- DH49. Küme, iş ve kaynak yöneticisi kurgudur; gerçek bir kaynak yöneticisi, küme yöneticisi ya da bulut servisi çağrılmaz. Tohum 20260218, ölçü koşumdan bağımsızdır.
- DH50. Süre bu modelin kendi birimidir, ham milisaniye değildir: en yüklü yuvanın bitirdiği iştir.
- DH51.
GOREV_SABIT = 50bir seçimdir ve bu dersin bulgusu doğrudan ona dayanır; her sonuç değeriyle birlikte yazılır. Bedel görev başına ödenir: bir işçiye iki görev verilirse iki kez ödenir. - DH52. Görev işçiye verilen paydır. Yuva (slot) kümede aynı anda koşabilen bir görev yeridir; bir yuva boşalınca sıradaki görevi alır. Eşzamanlı görev sayısı yuva sayısıdır.
- DH53. Bölüşüm anahtarı
aboneve bu derste karıştırma yoktur; satır işi her kurulumda 2200’dür. Yanlış anahtarın işçi eklemeyi anlamsızlaştırdığı durum bu kursun ikinci konusuna aittir. - DH54. Kaynak yöneticisi büyük görevi önce koyar ve her görevi en boş yuvaya yerleştirir.
- DH55. Sayılan birimler: görev, eşzamanlı görev, süre, satır işi, sabit bedel toplamı ve ödenen toplam (satır işi artı sabit bedel). Taban çizgisi tek görev, tek yuvadır.
- DH56. Kaynak isteği, sınırı ve kuyruk yordamı Konteyner Orkestrasyonu kursunda, otomatik ölçekleme Bulutta Hesaplama ve Ağ kursunda ölçüldü ve tekrarlanmaz. Buradaki soru yalnız görev sayısı ile yuva sayısının süreye ve sabit bedele ne yaptığıdır.
- DH57. Çözünürlük: satır 2200, görev en çok 32, yuva en çok 16. Süre ve sabit bedel tam sayıdır, oran basılmaz.
Kaynak Yöneticisi Neye Karar Verir
Sürücünün gönderdiği şey bir hesap planıdır; kaç makinede koşacağını söylemez. O kararı kaynak yöneticisi verir ve karar üç parçalıdır. Birincisi görev sayısı: iş kaç paya bölünecek. İkincisi yuva sayısı: bu payların kaçı aynı anda koşacak. Üçüncüsü sıra: küme başka işlerle doluysa bu iş ne zaman başlayacak.
Üç kararın da ortak bir bedeli vardır. Bir göreve iş vermek bedava değildir: plan gönderilir,
yuva ayrılır, işçi tarafında bir yürütücü hazırlanır. Bu modelde o bedelin adı GOREV_SABIT ve
değeri 50’dir. Değer bir seçimdir ama seçildiği anda bir sonuç doğurur: görev sayısını
büyütmek sabit bedeli görev başına 50 artırır, yuva sayısını büyütmek onu hiç değiştirmez.
İki düğme aynı düğme değildir.
# KURGUDUR. Kaynak, hattin ilk uc asamasi, kume ve kaynak yoneticisi ders icinde # tanimlanir; gercek bir kaynak yoneticisi ya da kume yoneticisi cagrilmaz. 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 BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"] TIP = ["mesken", "isyeri"] DONEM = [f"2026-{a:02d}" for a in range(1, 13)] ABONE = {} for i in range(200): r = uretec(TOHUM + 37 * i) ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)], "baslangic": 10000 + int(r() * 60000)} def kaynak_uret(): kayit = [] for i, (ab, a) in enumerate(ABONE.items()): e = a["baslangic"] for d in DONEM: r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d)) e += 4 + int(r() * 46) kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"], "endeks": e, "birim": "m3"}) return kayit def a1_ayikla(kayit): ZOR = ("abone", "donem", "bolge", "endeks", "birim") tut = [k for k in kayit if all(a in k for a in ZOR)] return tut, len(kayit) - len(tut) def a2_tekille(kayit): gor, tut = set(), [] for k in kayit: ad = (k["abone"], k["donem"]) if ad in gor: continue gor.add(ad) tut.append(k) return tut, len(kayit) - len(tut) def a3_tuketim(kayit): tablo = {(k["abone"], k["donem"]): k for k in kayit} cikti, dusen = [], 0 for k in kayit: i = DONEM.index(k["donem"]) if i == 0: continue onceki = tablo.get((k["abone"], DONEM[i - 1])) if onceki is None: dusen += 1 continue try: f = int(k["endeks"]) - int(onceki["endeks"]) except (TypeError, ValueError): dusen += 1 continue cikti.append(dict(k, m3=f)) return cikti, dusen ISCI = 4 AG_BEDELI = 3 # bir satiri agdan tasimanin bedeli , yerel islemin kac kati GOREV_SABIT = 50 # bir goreve is vermenin sabit bedeli , bir secimdir def satirlar(): v, _ = a1_ayikla(kaynak_uret()) v, _ = a2_tekille(v) v, _ = a3_tuketim(v) return v def izno(m): h = 2166136261 for c in str(m): h = ((h ^ ord(c)) * 16777619) & 0xFFFFFFFF return h def dagit(kayitlar, anahtar, isci=ISCI): kova = {i: [] for i in range(isci)} for k in kayitlar: kova[izno(k[anahtar]) % isci].append(k) return kova def maliyet(kova, tasinan=0, isci=ISCI): """Sure = en yuklu iscinin isi (paralel). Toplam is ayrica sayilir.""" n = [len(v) for v in kova.values()] return {"sure": max(n) + tasinan * AG_BEDELI // isci + GOREV_SABIT, "toplam_is": sum(n) + tasinan * AG_BEDELI, "tasinan": tasinan}
Görev, Yuva ve Sabit Bedel
Zamanlayıcı gerçek bir kaynak yöneticisinin çekirdeğini taşır: görevler büyükten küçüğe sıraya konur, her görev en boş yuvaya yerleştirilir ve her yerleşim kendi sabit bedelini öder. Süre en yüklü yuvanın bitirdiği iştir.
S = satirlar() def paylar(kayitlar, gorev): """Is 'gorev' paya bolunur; ayni anahtar hep ayni paya gider.""" return sorted((len(v) for v in dagit(kayitlar, "abone", gorev).values()), reverse=True) def zamanla(pay, eszamanli, sabit=GOREV_SABIT): """Kaynak yoneticisi: ayni anda en cok 'eszamanli' gorev kosar. Bosalan yuva siradaki gorevi alir , ve her gorev kendi sabit bedelini oder.""" yuva = [0] * eszamanli for p in pay: i = yuva.index(min(yuva)) yuva[i] += p + sabit return {"gorev": len(pay), "sure": max(yuva), "satir_isi": sum(pay), "sabit": len(pay) * sabit, "odenen": sum(pay) + len(pay) * sabit} print("maliyet (4 isci , karistirma yok):", maliyet(dagit(S, "abone", 4))) print("zamanla (4 gorev , 4 yuva) :", zamanla(paylar(S, 4), 4)) print("taban (1 gorev , 1 yuva) :", zamanla(paylar(S, 1), 1))
maliyet (4 isci , karistirma yok): {'sure': 611, 'toplam_is': 2200, 'tasinan': 0}
zamanla (4 gorev , 4 yuva) : {'gorev': 4, 'sure': 611, 'satir_isi': 2200, 'sabit': 200, 'odenen': 2400}
taban (1 gorev , 1 yuva) : {'gorev': 1, 'sure': 2250, 'satir_isi': 2200, 'sabit': 50, 'odenen': 2250}
İlk iki satır aynı süreyi veriyor: 611. Bu bir denetimdir, kursun maliyet işlevi ile bu
dersin zamanlayıcısı dört görev dört yuvada aynı sonucu üretiyor. Fark üçüncü sayıdadır.
maliyet sabit bedeli süreye bir kez ekler, çünkü orada her işçiye tam bir görev düşer;
zamanla onu ayrı bir kalem olarak sayar ve dört görevin toplam sabit bedelini 200 olarak
yazar. Taban çizgisi son satırdır: tek görev, tek yuva, süre 2250, sabit bedel 50.
İki Düğme Aynı Düğme Değildir
Aşağıdaki matris görev sayısını satırlara, yuva sayısını sütunlara koyar. Her hücre süredir; sol sütun her satırın ödediği sabit bedel toplamıdır ve yuva sayısından bağımsızdır.
ESZ = (1, 2, 4, 8, 16) print(f"{'gorev':>6}{'sabit bedel':>13}", "".join(f"{'esz=' + str(e):>9}" for e in ESZ)) for g in (4, 8, 16, 32): p = paylar(S, g) print(f"{g:>6}{g * GOREV_SABIT:>13}", "".join(f"{zamanla(p, e)['sure']:>9}" for e in ESZ))
gorev sabit bedel esz=1 esz=2 esz=4 esz=8 esz=16
4 200 2400 1200 611 611 611
8 400 2600 1300 650 336 336
16 800 3000 1500 750 386 215
32 1600 3800 1900 950 475 243
Satır boyunca okuyunca yuva düğmesi görünür: on altı görevlik iş bir yuvada 3000, on altı yuvada 215 sürede biter ve ödenen sabit bedel iki uçta da 800’dür. Eşzamanlılığı büyütmek sabit bedele dokunmaz; yalnız aynı bedelin daha kısa sürede ödenmesini sağlar.
Sütun boyunca okuyunca ikinci düğme görünür ve ters yönde çalışır. Dört yuvada iş dört göreve bölünürse süre 611, sekize bölünürse 650, on altıya 750, otuz ikiye 950. İş değişmedi, satır işi hâlâ 2200. Yükselen tek şey sabit bedeldir: 200’den 1600’e. Yuva sayısını aşan her görev bir 50 öder ve karşılığında hiçbir paralellik satın almaz, çünkü koşacak boş yer yoktur.
İki düğme birbirine bağlıdır ve tablonun en pahalı köşesi bunu söyler. On altı yuvayı kullanabilmek için işi en az on altı göreve bölmek gerekir, yani 215 süreye inmenin ön koşulu 800 birimlik sabit bedeldir. Otuz iki göreve bölmek aynı on altı yuvada süreyi 215’ten 243’e yükseltir ve sabit bedeli 1600’e çıkarır. Doygunluk da aynı yerde: dört görevlik iş sekiz ya da on altı yuvada da 611 sürede biter, fazladan yuvalar boş durur.
Süre Kazancının Yenildiği Yer
Matrisin köşegeni en sık verilen kararı temsil eder: her göreve bir yuva, yani işi kaç işçiye böleceğini seçmek. Kazancın nerede yenildiğini görmek için iki sütun yan yana konur — kazanılan süre ve eklenen sabit bedel.
print(f"{'gorev=esz':>10}{'carpiklik':>11}{'sure':>7}{'sure kazanci':>14}" f"{'eklenen sabit':>15}{'odenen':>8}") onceki = None for g in (1, 2, 4, 8, 16): p, z = paylar(S, g), zamanla(paylar(S, g), g) c = round(max(p) / (sum(p) / len(p)), 4) kaz = "-" if onceki is None else str(onceki[0] - z["sure"]) ek = "-" if onceki is None else str(z["sabit"] - onceki[1]) print(f"{g:>10}{c:>11}{z['sure']:>7}{kaz:>14}{ek:>15}{z['odenen']:>8}") onceki = (z["sure"], z["sabit"])
gorev=esz carpiklik sure sure kazanci eklenen sabit odenen
1 1.0 2250 - - 2250
2 1.0 1150 1100 50 2300
4 1.02 611 539 100 2400
8 1.04 336 275 200 2600
16 1.2 215 121 400 3000
İlk üç adım tartışmasızdır: tek görevden iki göreve geçmek süreyi 1100 birim düşürüyor ve karşılığında 50 birim sabit bedel ekliyor. İkiden dörde kazanç 539, bedel 100. Dörtten sekize kazanç 275, bedel 200. Kazanç her adımda yarılanırken bedel her adımda ikiye katlanıyor, yani iki sayı birbirine doğru koşuyor.
Sekizden on altıya geçişte karşılaşıyorlar ve sıra tersine dönüyor: süre kazancı 121, eklenen sabit bedel 400. Süre kazancının yenildiği yer sekiz ile on altı görev arasındadır. Bu, sürenin düşmediği anlamına gelmez; süre 336’dan 215’e gerçekten iniyor. Anlamı şudur: ödenen toplam 2600’den 3000’e çıkarken satır işi hiç değişmiyor, yani eklenen 400 birimin tamamı iş değil iş verme bedelidir. Hangisinin ölçüldüğü yazılmadan bu satıra bakan biri saf bir hızlanma görür.
Çarpıklık sütunu ikinci bir uyarı taşıyor. On altı görevde abone anahtarı bile 1,2
çarpıklık üretiyor: en yüklü pay 165 satır, en hafifi 110. Pay küçüldükçe eşitliği bozulur ve
sabit bedel büyür; iki etki aynı yöne çalışır.
Aynı Kümede İki İş
Kaynak yöneticisinin asıl işi tek bir işi hızlandırmak değil, kümeyi paylaştırmaktır. Sekiz yuvalık bir kümeye iki iş gelir: A bütün satırları işleyen sekiz görevlik iş, B yalnız mesken abonelerini işleyen dört görevlik iş. Öncelikli politikada A kümenin tamamını alır ve B sırasını bekler; paylaşımlı politikada küme ikiye bölünür.
MESKEN = [k for k in S if k["tip"] == "mesken"] A, B = paylar(S, 8), paylar(MESKEN, 4) print("is A satir:", sum(A), " gorev:", len(A), " is B satir:", sum(B), " gorev:", len(B)) for kip in ("oncelikli", "paylasimli"): if kip == "oncelikli": # once A butun kumeyi alir a = zamanla(A, 8)["sure"] b = a + zamanla(B, 8)["sure"] else: # kume ikiye bolunur a, b = zamanla(A, 4)["sure"], zamanla(B, 4)["sure"] print(f"{kip:<12} A biter {a:>5} B biter {b:>5} ikisi {max(a, b):>5}" f" sabit bedel {(len(A) + len(B)) * GOREV_SABIT:>5}")
is A satir: 2200 gorev: 8 is B satir: 1078 gorev: 4 oncelikli A biter 336 B biter 683 ikisi 683 sabit bedel 600 paylasimli A biter 650 B biter 347 ikisi 650 sabit bedel 600
Politika bitiş sırasını baştan aşağı değiştiriyor. Öncelikli kurulumda A 336’da biter ve B 683’e kadar bekler; paylaşımlı kurulumda A 650‘ye gecikirken B 347‘de biter. İkisinin birden bittiği an 683’ten 650’ye iner, yani paylaşımlı politika kümeyi biraz daha dolu tutar. Üstün olan bir politika yoktur; seçilen şey hangi işin geciktiğidir.
Son sütun bu dersin toplayıcı cümlesidir: sabit bedel iki politikada da 600’dür. Zamanlama politikası kimin ne zaman biteceğini belirler, ödenen sabit bedeli belirlemez. O bedel yalnız görev sayısının işlevidir ve on iki görev on iki kez 50 öder. Kaynak yöneticisini değiştirerek kazanılabilecek şey sıradır, iş değil.
Özet
- Kaynak yöneticisi üç şeye karar verir: görev sayısı, yuva sayısı ve sıra; ilk ikisi ayrı düğmelerdir ve sabit bedele farklı davranırlar.
- Yuva sayısını büyütmek sabit bedeli hiç değiştirmez: on altı görevlik iş bir yuvada 3000, on altı yuvada 215 sürede biter ve ödenen sabit bedel iki uçta da 800’dür.
- Görev sayısını büyütmek sabit bedeli görev başına 50 artırır: dört yuvada süre 611’den 950‘ye çıkarken satır işi 2200’de kalır, çünkü yuva sayısını aşan görev paralellik satın almaz.
- Her göreve bir yuva verildiğinde süre kazancı her adımda yarılanır, eklenen sabit bedel her adımda ikiye katlanır; sekiz ile on altı görev arasında kazanç 121’de kalıp eklenen 400 birime yenilir ve ödenen toplam 2600’den 3000’e çıkar.
- On altı görevde
aboneanahtarı bile 1,2 çarpıklık üretir; payların eşitsizliği ile sabit bedelin büyümesi aynı yöne çalışır. - Aynı kümede iki iş koşarken politika bitiş sırasını değiştirir (A 336 ve B 683 yerine A 650 ve B 347) ama ödenen sabit bedeli değiştirmez: iki kurulumda da 600.
Sonraki Adım
Beş derste iş bölündü. Bir küme kuruldu ve sürücü, yürütücü ve görev adlarıyla ayrıldı; bloklar yerleştirildi ve okumanın hangi işçiye düştüğü sayıldı; eşleme ile indirgeme birbirinden ayrıldı; hesabın hangi parçasının hiç koşmayacağı ölçüldü; ve işin kaç göreve bölüneceğine kimin karar verdiği yazıldı. Bütün bu derslerde tek bir sayı hep aynı kaldı ve hiç sorgulanmadı: satır işi 2200. İşi böldük, dağıttık, zamanladık, ama işin kendisine hiç dokunmadık.
Oysa dağıtık bir işin yavaşlığı çoğu zaman satır sayısından gelmez. Bir bölüşüm anahtarından öbürüne geçmek satırları ağ üzerinden taşır ve o taşıma bu modelde yerel işlemin üç katı bedelle sayılır; iki bağıntıyı birleştirmenin iki yolu vardır ve hangisinin ucuz olduğu boyuta göre değişir; bir anahtar payları eşit bölmediğinde işçilerin bir bölümü boş durur. Sonraki konu bu üç kaynağı ayrı ayrı sayar ve ilk soruyu şöyle sorar: aynı iş, aynı işçi sayısıyla, yalnız bölüşüm anahtarı değiştiği için kaç satır ağdan geçiyor ve toplam iş 2200’den nereye çıkıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.