İçeriğe geç
academia.sh

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 = 50 bir 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ı abone ve 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 abone anahtarı 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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat