Ders 08 / 26
Toplu ve Eşzamansız Çağrılar
Yüz yirmi kurgu talebin yedi ayrı toplu boyutta işlenmesi ve toplu boyutun üç ayrı sayıyı ters yönde oynatması: giriş belirteci 5854'ten 1784'e, çağrı sayısı 120'den 10'a, dörtlü eşzamanlılıkta tur sayısı 30'dan 3'e iniyor. Yönergenin tekrarı dışındaki yük yedi satırda da tam 1414 belirteç; bütün tasarruf yinelenen yönergeden geliyor. Buna karşılık tek bir başarısızlığın etkilediği istek sayısı toplu boyuta eşittir ve 1'den 12'ye çıkar; boyut 18'de istem bağlam penceresini aşar, yedi çağrının altısı düşer ve isabet 0,0667'ye çöker. İsabetin toplu boyutla oynaması iki koşum farkının altında kalır, yani ölçülmemiş sayılır. Çıktı sınırı toplu boyutla büyütülmezse boyut 12'de 26 istek yanıtsız kalır ve isabet 0,5333'e iner.
İçindekiler
Önceki derse kadar her ölçü istek başına bir çağrı varsayımıyla yazıldı: yüz yirmi talep, yüz yirmi çağrı. Bu varsayımın görünmeyen bir bedeli var. Her çağrının başına aynı yönerge konuyor ve her seferinde yeniden ödeniyor. Bir gecelik toplu işte yüz yirmi değil binlerce kayıt olduğunda bu tekrar tek başına faturanın çoğunu oluşturur.
Toplu çağrı bunu ortadan kaldırır: yönerge bir kez yazılır, arkasına numaralanmış istekler dizilir ve yanıt tek seferde okunur. Bu ders toplu boyutu bir ayar olarak ele alır ve üç sayıyı yan yana basar: çağrı ve belirteç, bekleme, ve tek bir başarısızlığın etkilediği istek sayısı. İlk ikisi toplu boyut büyüdükçe düşer, üçüncüsü büyür.
- AK63. Kod bir benzeticidir; gerçek bir uç nokta çağrılmaz. Talepler ve bütün başarısızlık kuralları kurgudur, tohum 20260218, ikinci koşum 20260219.
- AK64. Başarısızlık çağrı düzeyindedir. Bir çağrı hangi sebeple reddedilirse içindeki isteklerin tamamı reddedilir. Toplu arayüzün tanımı budur ve bu dersin ölçtüğü asıl şeydir.
- AK65. Üç ret kaynağı vardır: bağlam penceresi (240 belirteç), hız sınırı (otuz yedi çağrıda bir) ve biçim bozukluğu. Sonuncusu istek başına yüzde bir buçuk paydır; bir istek bozarsa yanıtın tamamı düşer.
- AK66. Biçim bozukluğu payının istek başına olması bu dersin kilit varsayımıdır. Altta yatan kusur oranı toplu boyuttan bağımsızdır; değişen tek şey bir kusurun kaç isteği götürdüğüdür.
- AK67. Bekleme tur sayısıyla yazılır. Dört çağrı eşzamanlı gönderilir; tur sayısı çağrı sayısının dörde bölümünün yukarı yuvarlanmışıdır. Ham süre yazılmaz; tur koşumdan koşuma değişmeyen bir sayımdır.
- AK68. Çıktı sınırı öntanımlı olarak toplu boyutla birlikte büyür (istek başına üç belirteç ve iki paylık boşluk). Büyütülmediğinde ne olduğu ayrıca ölçülür.
- AK69. Yanıt sıralara çözücüyle ayrılır: numara, ardından etiket. Bir sıra okunamazsa o istek yanıtsız sayılır; çağrı başarılı olsa bile.
- AK70. Kuyruk, geri çekilme ve eşzamansız iş yönetimi yordamı Backend Geliştirme müfredatının Önbellekleme, Kuyruklar ve Eşzamansız İşleme kursunda ölçüldü; tekrarlanmaz. Bu ders yalnız toplu boyutun üç sayıya ne yaptığını ekler.
Bir Çağrıya Kaç İstek Sığar
Toplu çağrının istemi tek parçadır: yönerge bir kez, ardından numaralanmış istekler. Yanıt da tek parçadır ve okunabilmesi için sıraya ayrılması gerekir. Aşağıdaki blok bu iki ucu kurar ve üç toplu boyutta ne olduğunu gösterir.
# BENZETICI -- KURGUDUR. Gercek bir model uc noktasi cagrilmaz. Talepler ve # butun basarisizlik kurallari kurgudur. import math TOHUM, M32 = 20260218, 0xFFFFFFFF PENCERE, ESZAMAN = 240, 4 # baglam penceresi , eszamanli cagri sayisi 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 ayrik(u, w): t = 0.0 for i, x in enumerate(w): t += x if u < t: return i return len(w) - 1 def belirtecle(m): # KURGU belirtecleyici, parca en cok bes damga b = [] for s in m.lower().replace(",", " , ").split(): while len(s) > 5: b.append(s[:5]) s = s[5:] b.append(s) return b def izno(m): h = 2166136261 for c in m: h = ((h ^ ord(c)) * 16777619) & M32 return h KONU = ["fatura", "ariza", "sayac", "tarife", "kesinti"] KALIP = [("bu ayki fatura tutari gecen aya gore cok yuksek geldi", "fatura"), ("faturami odedim ama sistemde borc gorunuyor", "fatura"), ("fatura ayrintisini nereden gorebilirim", "fatura"), ("evde su akmiyor bir ariza var galiba", "ariza"), ("baglanti bozuk oldu ve hic calismiyor", "ariza"), ("ariza kaydi actim ama ekip gelmedi", "ariza"), ("sayac okumasi yanlis girilmis endeks tutmuyor", "sayac"), ("sayac degisimi icin randevu istiyorum", "sayac"), ("sayac uzerindeki endeks ile fatura ayni degil", "sayac"), ("hangi tarife basamagindayim ogrenmek istiyorum", "tarife"), ("tarife degisikligi icin ne yapmam gerekiyor", "tarife"), ("birim ucret abone tipine gore degisiyor mu", "tarife"), ("mahallede kesinti var ne zaman gelecek", "kesinti"), ("planli kesinti duyurusu nereden takip edilir", "kesinti"), ("aksamdan beri kesinti yasiyoruz", "kesinti")] TALEP = [] for i in range(120): # 120 KURGU destek talebi r = uretec(TOHUM + i) k = KONU[ayrik(r(), [0.24, 0.22, 0.18, 0.20, 0.16])] TALEP.append({"no": 4001 + i, "konu": k, "metin": [x for x in KALIP if x[1] == k][int(r() * 3)][0]}) IZ = {"fatur": "fatura", "tutar": "fatura", "ayrin": "fatura", "ariza": "ariza", "bozuk": "ariza", "calis": "ariza", "akmiy": "ariza", "sayac": "sayac", "endek": "sayac", "okuma": "sayac", "tarif": "tarife", "birim": "tarife", "abone": "tarife", "basam": "tarife", "kesin": "kesinti", "duyur": "kesinti", "mahal": "kesinti"} ONEK = ("Her talebi su etiketlerden birine ata: fatura , ariza , sayac , tarife ," " kesinti . Her satir icin once numara sonra tek etiket yaz . Talepler: ") ONEK5 = {k[:5]: k for k in KONU} SAYAC = [0] def toplu(parti, tohum=TOHUM, en_uzun=None, sicaklik=0.6): """k istegi tek cagrida gonderir. Basarisizlik cagri duzeyindedir: kim reddedilirse partinin tamami reddedilir.""" SAYAC[0] += 1 k = len(parti) istem = ONEK + " ".join(f"{i + 1} {x['metin']} ;" for i, x in enumerate(parti)) bel = belirtecle(istem) en_uzun = 3 * k + 2 if en_uzun is None else en_uzun bos = {"giris": len(bel), "cikis": 0, "yanit": []} if len(bel) > PENCERE: return dict(bos, durum="baglam_asimi") if SAYAC[0] % 37 == 0: return dict(bos, durum="hiz_siniri") r = uretec(tohum ^ izno(istem)) for _ in parti: # her istek kendi bozukluk payini tasir if r() < 0.015: # bir istek bozarsa yanit tumuyle duser return dict(bos, durum="bicim_bozuk") cb = [] for i, x in enumerate(parti): p = {c: 0.15 for c in KONU} for t in belirtecle(x["metin"]): if IZ.get(t) in p: p[IZ[t]] += 1.0 ad = sorted(p) w = [math.exp(p[a] / sicaklik) for a in ad] cb += [str(i + 1)] + belirtecle(ad[ayrik(r(), [q / sum(w) for q in w])]) kesik = len(cb) > en_uzun return {"durum": "tamam", "giris": len(bel), "cikis": min(len(cb), en_uzun), "yanit": cb[:en_uzun], "kesik": kesik} def coz(cb, k): """Toplu yanittan sira basina etiket okur. Okunamayan sira None kalir.""" out, i = [None] * k, 0 while i < len(cb): if cb[i].isdigit(): n, j = int(cb[i]), i + 1 parca = [] while j < len(cb) and not cb[j].isdigit(): parca.append(cb[j]) j += 1 e = "".join(parca) if 1 <= n <= k and e[:5] in ONEK5: out[n - 1] = ONEK5[e[:5]] i = j else: i += 1 return out for k in (1, 6, 18): s = toplu(TALEP[:k]) print(f"toplu boyut {k:>2} : giris {s['giris']:>3} , cikis {s['cikis']:>2} ," f" durum {s['durum']}") s = toplu(TALEP[:6]) print("\nalti istekli tek cagrinin yaniti:", " ".join(s["yanit"])) print("cozulmus:", coz(s["yanit"], 6)) print("gercek :", [x["konu"] for x in TALEP[:6]]) d = toplu(TALEP[:6], en_uzun=8) # cikti siniri toplu boyutla buyutulmezse print(f"\nen_uzun 8 ile ayni cagri: cikis {d['cikis']} , kesik {d['kesik']} ," f" cozulen {sum(e is not None for e in coz(d['yanit'], 6))} / 6")
toplu boyut 1 : giris 50 , cikis 3 , durum tamam toplu boyut 6 : giris 107 , cikis 16 , durum tamam toplu boyut 18 : giris 247 , cikis 0 , durum baglam_asimi alti istekli tek cagrinin yaniti: 1 kesin ti 2 kesin ti 3 kesin ti 4 ariza 5 sayac 6 fatur a cozulmus: ['kesinti', 'kesinti', 'kesinti', 'ariza', 'sayac', 'fatura'] gercek : ['kesinti', 'fatura', 'ariza', 'ariza', 'sayac', 'tarife'] en_uzun 8 ile ayni cagri: cikis 8 , kesik True , cozulen 3 / 6
İlk üç satır toplu boyutun tavanını gösteriyor. Yönerge otuz yedi belirteç; tek istekli bir çağrı elli belirteç ediyor, yani girişin dörtte üçü yönergedir. Altı istekli çağrıda giriş 107’ye çıkıyor ama istek başına düşen pay on yediye iniyor. On sekiz istekte istem 247 belirtece ulaşıyor ve 240 belirteçlik pencereyi aşıyor: çağrı hiç kurulmadan reddediliyor. Toplu boyutun üst sınırını hız sınırı değil bağlam penceresi koyuyor.
Çözücü satırları toplu yanıtın ikinci yüzünü gösteriyor. Yanıt tek bir belirteç dizisidir ve sıralar ancak numaralarla ayrılabilir. Altı sıranın hepsi okunuyor, üçü doğru. Son blok ise çıktı sınırı toplu boyutla büyütülmediğinde ne olduğunu gösteriyor: sekiz belirteçlik sınır yanıtı ortadan kesiyor, çağrı başarılı dönüyor ve altı isteğin yalnız üçü çözülüyor. Kesilme çağrı durumunda yazmaz; ancak çözücünün boş bıraktığı sıralar sayılırsa görünür.
Toplu Boyutun Üç Sayısı
Yüz yirmi talep yedi ayrı toplu boyutta baştan sona işlenir. Her satırda çağrı sayısı, giriş ve çıkış belirteci, başarısız çağrı, o başarısızlıkların etkilediği istek sayısı, teslim edilen isabet, ikinci koşum isabeti ve dörtlü eşzamanlılıkta tur sayısı basılır.
def kosum(k, tohum=TOHUM, en_uzun=None): SAYAC[0] = 0 cagri = g = c = hata = etkilenen = dogru = yanitsiz = 0 for i in range(0, 120, k): parti = TALEP[i:i + k] s = toplu(parti, tohum, en_uzun) cagri, g, c = cagri + 1, g + s["giris"], c + s["cikis"] if s["durum"] != "tamam": hata, etkilenen = hata + 1, etkilenen + len(parti) continue for x, e in zip(parti, coz(s["yanit"], len(parti))): dogru, yanitsiz = dogru + (e == x["konu"]), yanitsiz + (e is None) return cagri, g, c, hata, etkilenen, dogru / 120, -(-cagri // ESZAMAN), yanitsiz print("boyut cagri giris cikis basarisiz etkilenen isabet ikinci kosum tur") for k in (1, 2, 3, 6, 12, 18, 24): a, b = kosum(k), kosum(k, TOHUM + 1) print(f"{k:>5} {a[0]:>6} {a[1]:>6} {a[2]:>6} {a[3]:>10} {a[4]:>10}" f" {a[5]:>7.4f} {b[5]:>13.4f} {a[6]:>4}") for k in (6, 12): a = kosum(k, en_uzun=24) print(f"cikti siniri 24 sabit , boyut {k:>2} : yanitsiz istek {a[7]:>2} ," f" isabet {a[5]:.4f}")
boyut cagri giris cikis basarisiz etkilenen isabet ikinci kosum tur
1 120 5854 300 3 3 0.8250 0.7083 30
2 60 3634 300 3 6 0.7667 0.7250 15
3 40 2894 291 3 9 0.7167 0.6667 10
6 20 2154 299 1 6 0.7833 0.7583 5
12 10 1784 284 1 12 0.7083 0.6833 3
18 7 1673 30 6 108 0.0667 0.0750 2
24 5 1599 0 5 120 0.0000 0.0000 2
cikti siniri 24 sabit , boyut 6 : yanitsiz istek 0 , isabet 0.7833
cikti siniri 24 sabit , boyut 12 : yanitsiz istek 26 , isabet 0.5333
Giriş sütunundaki düşüşün tamamı tek bir kalemden geliyor ve bunu tam olarak ayırmak mümkün. Yönerge otuz yedi belirteç; tek tek gönderimde 120 kez, on ikili toplu gönderimde 10 kez ödeniyor, yani 4440 belirteçten 370’e iniyor. Geriye kalan yük yedi satırın hepsinde tam 1414 belirteçtir: taleplerin kendisi, numaraları ve ayraçları. Toplu çağrı isteğin yükünü değil, yönergenin tekrarını ortadan kaldırır. Çıkış sütunu bu okumayı doğruluyor: istek başına üç belirteç ve toplam üç yüz civarı, toplu boyuttan bağımsız. Toplu çağrı çıkıştan tasarruf ettirmez.
Tur sütunu beklemenin ölçüsüdür. Yüz yirmi ayrı çağrı dörderli gönderildiğinde otuz tur sürüyor; on ikili partilerde üç tur. Gecikme sınıfı tek çağrıdan toplu çağrıya geçiyor ve aradaki fark onlu bir çarpandır. Ham süre yazılmaz, ama tur sayısı koşumdan koşuma değişmez ve karşılaştırma için yeter.
Kazanan Giriş, Büyüyen Yarıçap
Etkilenen istek sütunu bu dersin asıl bulgusudur ve tek satırda okunur: etkilenen istek sayısı, başarısız çağrı sayısı ile toplu boyutun çarpımıdır. Tek tek gönderimde üç başarısızlık üç isteği götürüyor. Altılı partilerde tek bir başarısızlık altı isteği, on ikili partilerde on iki isteği götürüyor. Altta yatan kusur oranı değişmedi; her istek aynı yüzde bir buçukluk payı taşıyor. Değişen tek şey bir kusurun yarıçapıdır.
Başarısız çağrı sayısının toplu boyut büyüdükçe düşmesi bu okumayı gizleyebilir. Üçten bire iniyor ve tek başına iyi bir haber gibi duruyor. Oysa bu düşüşün bir kısmı yalnız çağrı sayısı azaldığı içindir: hız sınırı otuz yedi çağrıda bir devreye giriyor, on çağrı yapan bir kurulumda hiç devreye girmiyor. Aynı işi daha az çağrıyla yapmak hız sınırını gerçekten seyreltir, ama biçim bozukluğunu seyreltmez; onun payı isteğe bağlıdır ve istek sayısı sabittir.
On sekiz ve yirmi dört satırları bir eşiğin ötesidir. On sekizde istem pencereye sığmıyor; yedi çağrının altısı hiç kurulmadan düşüyor ve 108 istek yanıtsız kalıyor. Ayakta kalan tek çağrı son kalan on iki istektir ve isabet 0,0667’ye iniyor. Yirmi dörtte hiçbir çağrı kurulmuyor, isabet sıfır. Eklenen düzeneğin işi kötüleştirmesi bu tabloda bir eğri değil bir uçurumdur: toplu boyutu on ikiden on sekize çıkarmak giriş belirtecinden yalnız yüz on bir belirteç kazandırıyor ve karşılığında işin tamamını götürüyor.
İsabet sütununu okurken ölçüt gerekiyor. İlk beş satırda isabet 0,7083 ile 0,8250 arasında geziniyor; aradaki fark 0,1167. İkinci koşum sütununun aynı satırdaki farkı ise en büyük 0,1167 (tek tek gönderimde 0,8250 ve 0,7083). Toplu boyutun isabete etkisi koşum farkını aşmıyor, yani ölçülmemiş sayılır. Bu şaşırtıcı değildir: etiket kararı istek başına verilir ve toplu göndermek o kararı değiştirmez. Toplu boyut bir kalite ayarı değil, bir maliyet ve risk ayarıdır. Onu kalite üzerinden savunmak da suçlamak da tabloya aykırıdır.
Son iki satır çıktı sınırının unutulduğu durumu ölçüyor. Sınır yirmi dörtte sabit tutulduğunda altılı partiler etkilenmiyor, çünkü altı sıra yirmi belirtece sığıyor. On ikili partilerde ise yanıtın kuyruğu kesiliyor ve 26 istek yanıtsız kalıyor; isabet 0,7083’ten 0,5333’e düşüyor. Bu kayıp başarısız çağrı sütununda görünmez: çağrılar başarıyla döndü. Toplu boyutu büyütmek, çıktı sınırını da onunla birlikte büyütmeyi zorunlu kılar.
Özet
- Toplu çağrı yönergenin tekrarını ortadan kaldırır: giriş belirteci 5854’ten 1784’e iner, çünkü otuz yedi belirteçlik yönerge 120 kez yerine 10 kez ödenir. Kalan yük yedi satırda da tam 1414 belirteçtir ve çıkış belirteci toplu boyuttan bağımsızdır.
- Bekleme tur sayısıyla yazılır: dörtlü eşzamanlılıkta 30 turdan 3 tura iner.
- Tek bir başarısızlığın etkilediği istek sayısı toplu boyuta eşittir; aynı kusur oranı 3 isteği değil 12 isteği götürür hâle gelir.
- Toplu boyutun üst sınırını bağlam penceresi koyar: boyut 18’de istem 247 belirtece çıkar, yedi çağrının altısı hiç kurulmadan düşer ve isabet 0,0667’ye, boyut 24’te 0,0000’a iner.
- İsabetin ilk beş satırdaki 0,1167’lik oynaması iki koşum farkının içindedir: toplu boyut bir kalite ayarı değil, maliyet ve risk ayarıdır.
- Çıktı sınırı toplu boyutla büyütülmezse boyut 12’de 26 istek yanıtsız kalır ve isabet 0,5333’e düşer; bu kayıp başarısız çağrı sütununda hiç görünmez.
Sonraki Adım
Sekiz derste mesaj tabanlı arayüzün ne sunduğu tek tek ölçüldü: konuşma durumunun bedeli, yanıt akışının değiştirdiği, araç çağrısının geçerlilik oranı, arayüz düzeyinde şema zorunluluğu, girdi biçiminin belirteç faturası, gömme boyutunun takası, ortak arayüzün kaybettiği alanlar ve toplu boyutun üç sayısı. Sekizinin de altında aynı varsayım duruyordu: çağrı başarılı oluyor.
O varsayımın tutmadığı bu derste sayıldı ama karşılığı verilmedi. Reddedilen çağrılar yeniden denenmedi, penceresi aşan parti bölünmedi, yanıtsız kalan yirmi altı istek kurtarılmadı, yinelenen yönerge önbelleğe alınmadı. Sayıldılar ve öylece bırakıldılar. Sonraki konu tam buradan başlar ve ilk dersinde bu kursun ikinci iddiasını kurar: bir isteği yeniden denemek onu kurtarabilir, ama belirteci de katlar ve hız sınırını daha da zorlar. Dayanıklılık eklemek bedava değildir ve bazen düzeltmeye çalıştığı sayıyı bozar.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.