Ders 02 / 18
Zaman Serisi Verisi
Etiket eklemenin hangi soruyu açtığı soru kümesine karşı sayılır: her etiket için seri, bayt ve açılan soru birlikte ölçülür, marjinal soru başına bayt çıkarılır, hiçbir soru açmayan etiket adıyla yazılır ve saklama penceresinin hangi soruyu ne kadara açtığı ayrıca hesaplanır.
İçindekiler
Bir önceki ders toplamayı bir kutu gibi ölçtü: kaç ölçüm, kaç seri, kaç bayt. Ama yanıtlanan
sekiz ya da dokuz sorunun her biri belirli bir etiketin varlığına bağlıydı ve ornek etiketi
güvenilmez olduğunda iki soru tek seferde kapandı. Bu ders o bağı ters yönden ölçer: bir etiket
eklemek hangi soruyu açıyor ve o soru kaç bayta açılıyor?
Etiketin seri sayısını neden toplamsal değil çarpımsal büyüttüğü Konteyner Orkestrasyonu kursunun küme gözlemlenebilirliği dersinde ölçülmüştü: on bin serilik bir taban, yedi değerli tek bir etiketle 6,8 kata, dört değerli bir etiket bütün ölçütlere eklendiğinde 28,3 kata çıkmıştı. O ölçüm burada tekrarlanmaz; çarpım kuralı bu dersin girdisidir. Burada ölçülen şey başka bir şeydir — çarpanın karşılığında hangi sorunun açıldığı.
Seri kümesi de sayılar da kurgudur; ölçülen şey node ile kurulmuş bir modeldir.
OG7. Etiket kümesi, kardinaliteler ve hangi etiketin hangi ölçüte uygulandığı kurgudur ve
önceden yazılıdır.
OG8. ornek etiketi servis içinde çözülür; servis başına en çok sekiz örnek varsayılır (bir
önceki dersteki 29 örnek dört servise dağılır).
OG9. Her sorunun geriye dönük bir ufku vardır: yanıtlanabilmesi için kaç günlük veriye
bakılması gerektiği önceden yazılıdır.
OG10. Örnekleme 15 saniye, bir kayıt 16 bayt, bir seri künyesi 120 bayttır (bir önceki dersle
aynı).
OG11. Bir sorunun açılmış sayılması için gerektirdiği bütün etiketlerin kümede bulunması
gerekir; tek başına yeten etiket yoktur.
OG12. Ölçüt kümesi bir önceki dersin ölçütlerinden türer; hiçbir soruyu yanıtlamayan üç ölçüt
orada sayıldığı için burada kümeye alınmaz.
Serinin İçindeki Karar
Bir zaman serisi bir ad ile bir etiket kümesinden oluşur ve depoda o ikilinin her ayrı bileşimi ayrı bir seridir. Etiket kümesi bu yüzden bir depolama ayarı değil, bir soru kararıdır: hangi ayrımı sonradan yapabileceğin toplama anında belirlenir.
// seri.mjs — zaman serisi kumesi, etiket kardinaliteleri ve sorularin etiket/ufuk gereksinimi. export const OLCUT = { "istek-sayisi": "uzun", "istek-suresi": "uzun", "kuyruk-boyu": "uzun", "islenen-okuma": "uzun", "is-adimi-suresi": "kisa", "is-islenen-kayit": "kisa" }; export const ETIKET = { // ad: [kardinalite, uygulandigi olcutler] servis: [4, ["istek-sayisi", "istek-suresi", "kuyruk-boyu", "islenen-okuma"]], is: [3, ["is-adimi-suresi", "is-islenen-kayit"]], ortam: [3, Object.keys(OLCUT)], surum: [4, Object.keys(OLCUT)], ornek: [8, Object.keys(OLCUT)], sonuc: [5, ["istek-sayisi", "islenen-okuma"]], dilim: [12, ["istek-suresi"]], kuyruk: [3, ["kuyruk-boyu"]], bolge: [11, ["islenen-okuma"]], adim: [6, ["is-adimi-suresi"]], "dugum-adi": [9, Object.keys(OLCUT)], }; // soru: [kimlik, gereken etiketler, geriye dogru gereken ufuk (gun)] export const SORU = [["S1", ["servis"], 1], ["S2", ["servis", "dilim"], 1], ["S3", ["ortam", "sonuc"], 1], ["S4", ["surum"], 30], ["S5", ["is"], 7], ["S6", ["is", "adim"], 7], ["S7", ["bolge", "sonuc"], 365], ["S8", ["ornek"], 7], ["S9", ["is", "ornek"], 7], ["S10", ["sonuc"], 1], ["S11", ["servis", "kuyruk"], 1], ["S12", ["islem-kimligi"], 1]]; export const seriSayisi = (acik) => Object.keys(OLCUT).reduce((t, m) => t + acik.reduce((c, e) => c * (ETIKET[e][1].includes(m) ? ETIKET[e][0] : 1), 1), 0); export const bayt = (seri, gun, aralik = 15) => seri * Math.floor(86400 / aralik) * gun * 16 + seri * 120; export const gb = (b) => (b / 1024 ** 3).toFixed(2);
Etiketlerin ölçütlere dağılımı eşit değildir. bolge yalnız işlenen okuma ölçütüne uygulanır;
ortam, surum, ornek ve dugum-adi bütün ölçütlere uygulanır. Bu ayrım maliyeti belirler:
tek bir ölçüte eklenen on bir değerli bir etiket, bütün ölçütlere eklenen dört değerli bir
etiketten ucuz olabilir.
Etiket Merdiveni
Merdiven boş bir kümeden başlar — yalnız servis ve iş adları — ve etiketleri birer birer ekler. Her basamakta dört şey birlikte yazılır: seri, bayt, yanıtlanan soru ve o basamakta açılan sorunun marjinal bayt bedeli.
// etiket.mjs — etiket eklemenin actigi soru, kaldirmanin kapattigi soru ve saklama penceresi. import { OLCUT, ETIKET, SORU, seriSayisi, bayt, gb } from "./seri.mjs"; const acilan = (a) => SORU.filter(([, e]) => e.every((x) => a.includes(x))).map(([k]) => k); const MERDIVEN = ["ortam", "sonuc", "dilim", "kuyruk", "bolge", "adim", "surum", "ornek", "dugum-adi"]; let acik = ["servis", "is"], oncekiSoru = acilan(acik), oncekiBayt = bayt(seriSayisi(acik), 30); console.log(`${Object.keys(OLCUT).length} olcut, 15 sn ornekleme, 30 gun saklama; taban etiketler ${acik.join(" + ")}`); console.log("eklenen etiket kardinalite seri GB yanitlanan acilan soru marjinal GB/soru"); const yaz = (ad, kart) => { const s = seriSayisi(acik), b = bayt(s, 30), y = acilan(acik); const yeni = y.filter((q) => !oncekiSoru.includes(q)); const marj = yeni.length ? gb((b - oncekiBayt) / yeni.length) : "-"; console.log(`${ad.padEnd(15)}${String(kart).padStart(12)}${s.toLocaleString("tr-TR").padStart(9)}` + `${gb(b).padStart(10)}${String(`${y.length}/12`).padStart(13)} ${(yeni.join(" ") || "-").padEnd(14)}${marj.padStart(8)}`); oncekiSoru = y; oncekiBayt = b; }; yaz("taban", "-"); for (const e of MERDIVEN) { acik = [...acik, e]; yaz(`+ ${e}`, ETIKET[e][0]); } const TAM = acik, tamBayt = bayt(seriSayisi(TAM), 30); console.log(`\netiket kaldirildiginda (tam kume ${TAM.length} etiket,` + ` ${seriSayisi(TAM).toLocaleString("tr-TR")} seri, ${gb(tamBayt)} GB)`); console.log("kaldirilan etiket kazanilan GB kapanan soru GB/kapanan soru"); for (const e of TAM) { const kalan = TAM.filter((x) => x !== e), kazanc = tamBayt - bayt(seriSayisi(kalan), 30); const kapanan = acilan(TAM).filter((q) => !acilan(kalan).includes(q)); console.log(`${e.padEnd(18)}${gb(kazanc).padStart(13)} ${(kapanan.join(" ") || "-").padEnd(14)}` + `${(kapanan.length ? gb(kazanc / kapanan.length) : "-").padStart(9)}`); } const BUDANMIS = TAM.filter((e) => e !== "dugum-adi"); console.log(`\nsaklama penceresi (budanmis kume ${BUDANMIS.length} etiket,` + ` ${seriSayisi(BUDANMIS).toLocaleString("tr-TR")} seri)`); console.log("pencere GB ufuk icinde yanitlanan GB/soru pencerenin actigi soru"); let oncekiUfuk = []; for (const gun of [7, 30, 90, 395]) { const y = acilan(BUDANMIS).filter((q) => SORU.find(([k]) => k === q)[2] <= gun); const b = bayt(seriSayisi(BUDANMIS), gun); console.log(`${String(`${gun} gun`).padEnd(9)}${gb(b).padStart(9)}${String(`${y.length}/12`).padStart(24)}` + `${gb(b / y.length).padStart(10)} ${y.filter((q) => !oncekiUfuk.includes(q)).join(" ") || "-"}`); oncekiUfuk = y; }
6 olcut, 15 sn ornekleme, 30 gun saklama; taban etiketler servis + is eklenen etiket kardinalite seri GB yanitlanan acilan soru marjinal GB/soru taban - 22 0.06 2/12 - - + ortam 3 66 0.17 2/12 - - + sonuc 5 162 0.42 4/12 S3 S10 0.12 + dilim 12 294 0.76 5/12 S2 0.34 + kuyruk 3 318 0.82 6/12 S11 0.06 + bolge 11 918 2.36 7/12 S7 1.55 + adim 6 963 2.48 8/12 S6 0.12 + surum 4 3.852 9.92 9/12 S4 7.44 + ornek 8 30.816 79.35 11/12 S8 S9 34.72 + dugum-adi 9 277.344 714.17 11/12 - - etiket kaldirildiginda (tam kume 11 etiket, 277.344 seri, 714.17 GB) kaldirilan etiket kazanilan GB kapanan soru GB/kapanan soru servis 500.59 S1 S2 S11 166.86 is 31.15 S5 S6 S9 10.38 ortam 476.11 S3 476.11 sonuc 427.17 S3 S7 S10 142.39 dilim 97.89 S2 97.89 kuyruk 17.80 S11 17.80 bolge 444.97 S7 444.97 adim 33.37 S6 33.37 surum 535.63 S4 535.63 ornek 624.90 S8 S9 312.45 dugum-adi 634.82 - - saklama penceresi (budanmis kume 10 etiket, 30.816 seri) pencere GB ufuk icinde yanitlanan GB/soru pencerenin actigi soru 7 gun 18.52 9/12 2.06 S1 S2 S3 S5 S6 S8 S9 S10 S11 30 gun 79.35 10/12 7.94 S4 90 gun 238.05 10/12 23.80 - 395 gun 1044.76 11/12 94.98 S7
Merdivenin ilk yarısı ucuzdur. Sonuç etiketi iki soruyu 0,12 gigabayta açar, kuyruk etiketi bir soruyu 0,06 gigabayta, adım etiketi bir soruyu 0,12 gigabayta. Bunlar tek ölçüte uygulanan ya da düşük kardinaliteli etiketlerdir; çarpım küçük bir çarpanla büyür.
İkinci yarı pahalıdır. Sürüm etiketi dört değerlidir ama bütün ölçütlere uygulandığı için seriyi dört katına çıkarır ve tek bir soruyu — hangi sürümden sonra bozulduğu — 7,44 gigabayta açar. Örnek etiketi iki soruyu açar, soru başına 34,72 gigabayta. Aynı kümede iki soru açan iki farklı etiket arasında üç yüz kat fark vardır ve bu farkın kaynağı sorunun önemi değil, etiketin kaç ölçüte uygulandığıdır.
ortam satırı ayrı okunmalıdır: eklendiği basamakta hiçbir soru açmaz. Ama S3 hem ortam hem sonuç
etiketini ister; ortam olmasa sonuç etiketi tek başına S3’ü açamazdı. Bir etiketin “hiçbir soru
açmaması” ile “tek başına yetmemesi” farklı şeylerdir ve merdiven bu ikisini ayırt edemez.
Etiketin Kaldırılması ve Budama
Ayrımı yapan şey ikinci tablodur: her etiket tam kümeden çıkarılır ve kapanan soru sayılır.
ortam çıkarıldığında S3 kapanır — demek ki payı vardır ve o pay 476 gigabayta mal olmaktadır.
dugum-adi çıkarıldığında hiçbir soru kapanmaz. Kazanılan bayt 634,82 gigabayttır: tam kümenin
yüzde seksen dokuzu.
Bu etiketin adı yazılmalıdır çünkü zararsız görünür. Dokuz değerli, kısa, okunması kolay bir etikettir ve toplayıcı onu kendiliğinden ekler — düğüm adı zaten bilinmektedir. Sorunu, on iki sorunun hiçbirinin düğüm adı sormamasıdır. Kapsül hangi düğümde koşuyorsa koşsun, işletimin sorduğu şey servis, ortam, sürüm ve örnektir. Etiket bir soruya bağlanmadığı sürece bilgi değil, çarpandır.
Budama sırası da tablodan çıkar. Önce karşılığı olmayan etiket atılır; bu tek adım seriyi 277.344’ten 30.816’ya indirir. Ondan sonra kalan bütün etiketlerin marjinal maliyeti dokuzda birine iner — sürüm etiketi 535 gigabayt yerine 59, örnek etiketi 624 yerine 69 gigabayt tutar. Karşılığı olan bir etiketin pahalı görünmesinin nedeni çoğu zaman kendisi değil, yanındaki karşılıksız etikettir.
Çarpım Üst Sınırdır
Merdivenin bütün sayıları bir çarpımdan çıktı ve çarpım her etiket bileşiminin gerçekten oluşacağını varsayar. Envanter bunu doğrulamaz: dört servisin örnek sayıları eşit değildir, geliştirme ortamında iki servis hiç koşmaz ve işlenen okuma ölçütünü yalnız iki servis üretir. Gerçekleşen seri kümesi envanterden sayılabilir.
// gercek.mjs — carpim ust sinirdir: gerceklesen seri sayisi ve olcunun duzeltilmesi. import { OLCUT, ETIKET, SORU, seriSayisi, bayt, gb } from "./seri.mjs"; const ORNEK = { "okuma-toplayici": [8, 2, 1], dogrulayici: [6, 2, 1], // uretim, sinama, gelistirme faturalama: [4, 1, 0], "is-emri": [3, 1, 0] }; const EMITEN = { "islenen-okuma": ["okuma-toplayici", "dogrulayici"] }; // otekiler dort servisin hepsinde const KOSUCU = 3 * 2; // uc gecelik is, iki ortamda kosucu const BUDANMIS = ["servis", "is", "ortam", "surum", "ornek", "sonuc", "dilim", "kuyruk", "bolge", "adim"]; const TABAN = ["servis", "is", "ortam", "ornek"]; // gercek envanterden sayilan uclu const gerceklesen = Object.keys(OLCUT).reduce((t, m) => { const taban = OLCUT[m] === "kisa" ? KOSUCU : (EMITEN[m] || Object.keys(ORNEK)).reduce((s, v) => s + ORNEK[v].reduce((a, b) => a + b, 0), 0); return t + taban * BUDANMIS.filter((e) => !TABAN.includes(e) && ETIKET[e][1].includes(m)) .reduce((c, e) => c * ETIKET[e][0], 1); }, 0); const kuramsal = seriSayisi(BUDANMIS), yanit = SORU.filter(([, e]) => e.every((x) => BUDANMIS.includes(x))).length; console.log("olcut gerceklesen kuramsal fazla sayim"); for (const m of Object.keys(OLCUT)) { const taban = OLCUT[m] === "kisa" ? KOSUCU : (EMITEN[m] || Object.keys(ORNEK)).reduce((s, v) => s + ORNEK[v].reduce((a, b) => a + b, 0), 0); const carpan = BUDANMIS.filter((e) => !TABAN.includes(e) && ETIKET[e][1].includes(m)) .reduce((c, e) => c * ETIKET[e][0], 1); const k = BUDANMIS.reduce((c, e) => c * (ETIKET[e][1].includes(m) ? ETIKET[e][0] : 1), 1); console.log(`${m.padEnd(22)}${(taban * carpan).toLocaleString("tr-TR").padStart(9)}${k.toLocaleString("tr-TR").padStart(11)}` + `${String(`${(k / (taban * carpan)).toFixed(1)} kat`).padStart(14)}`); } console.log(`${"toplam".padEnd(22)}${gerceklesen.toLocaleString("tr-TR").padStart(9)}` + `${kuramsal.toLocaleString("tr-TR").padStart(11)}${String(`${(kuramsal / gerceklesen).toFixed(1)} kat`).padStart(14)}`); console.log(`\n30 gunluk saklama kuramsal ${gb(bayt(kuramsal, 30))} GB` + ` gerceklesen ${gb(bayt(gerceklesen, 30))} GB`); console.log(`${yanit}/12 soru icin soru basina kuramsal ${gb(bayt(kuramsal, 30) / yanit)} GB` + ` gerceklesen ${gb(bayt(gerceklesen, 30) / yanit)} GB`);
olcut gerceklesen kuramsal fazla sayim istek-sayisi 580 1.920 3.3 kat istek-suresi 1.392 4.608 3.3 kat kuyruk-boyu 348 1.152 3.3 kat islenen-okuma 4.400 21.120 4.8 kat is-adimi-suresi 144 1.728 12.0 kat is-islenen-kayit 24 288 12.0 kat toplam 6.888 30.816 4.5 kat 30 gunluk saklama kuramsal 79.35 GB gerceklesen 17.74 GB 11/12 soru icin soru basina kuramsal 7.21 GB gerceklesen 1.61 GB
Çarpım toplamda dört buçuk kat fazla sayar, gecelik iş ölçütlerinde on iki kat. Nedeni ölçüt başına farklıdır: servis-ortam-örnek üçlüsünün kuramsal doksan altı bileşiminden yalnız yirmi dokuzu vardır, işlenen okumayı dört servisten ikisi üretir, gecelik işi üç ortamda sekiz örnek değil iki ortamda tek koşucu çalıştırır.
Bu düzeltme kararı değiştirir. Kuramsal sayıya bakan bir saklama tartışması otuz günü 79 gigabayta, soru başına 7,21 gigabayta fiyatlandırır; envanterden sayılan gerçek küme aynı otuz günü 17,74 gigabayta, soru başına 1,61 gigabayta indirir. Aradaki fark bir tasarruf değil, bir ölçüm hatasıdır — dört buçuk kat abartılmış bir maliyet, hiç eklenmemesi gereken bir etiketin eklenmemesine değil, gereken bir etiketin eklenmemesine yol açar.
Saklama Penceresi
Etiket kümesi bir sorunun hangi ayrımı yapabileceğini belirler; saklama penceresi ne kadar geriye bakabileceğini. Üçüncü tablo aynı budanmış kümeyi dört pencerede ölçer; sayılar kuramsal seri kümesi üzerindendir, gerçekleşen kümede hepsi dört buçuğa bölünür.
Yedi günlük pencere on sekiz buçuk gigabayt tutar ve dokuz soruyu yanıtlar — soru başına 2,06 gigabayt. Otuz gün S4’ü açar: bir sürüm karşılaştırması iki sürümün de üretimde kaldığı süreyi kapsamalıdır ve dağıtım sıklığı buna otuz gün gerektirir. Bedeli soru başına 7,94 gigabayttır.
Doksan günlük pencere hiçbir yeni soru açmaz. Üç kat bayt, sıfır soru — soru başına maliyet 23,80 gigabayta çıkar. Bu satır, saklamayı “biraz daha uzun tutalım” diye uzatan kararın tam karşılığıdır.
Üç yüz doksan beş gün tek bir soruyu açar: hangi bölgenin okumasının doğrulamadan geçmediği, geçen yılın aynı dönemiyle karşılaştırılarak. Bedeli 965 gigabayt ek saklamadır. Yanıtsız kalmasının bedeli de sayılabilir: mevsimsel karşılaştırma yapılamadığında hangi bölgenin kalıcı olarak sorunlu olduğu ayırt edilemez ve saha ekibi tek bölge yerine on bir bölgenin tamamı için iş emri kapatmak zorunda kalır. Hangi sayının büyük olduğu bölgesel ölçüm ağının kendi maliyet yapısına bağlıdır; kararı taşıyan şey, iki sayının aynı tabloda durmasıdır.
S12 bu tabloların hiçbirinde görünmez. Ne etiket eklemek ne saklamayı uzatmak onu açar; bir faturanın hangi okumadan üretildiği sorusu etiketle çözülemez, çünkü gereken ayrım işlem başınadır.
Özet
- Bir etiketin bedeli kardinalitesi değil, kardinalitesi ile uygulandığı ölçüt sayısının
çarpımıdır: 11 değerli
bolgebir soruyu 1,55 GB’a açarken 4 değerlisurumbir soruyu 7,44 GB’a açar. - Merdiven 22 seriden 277.344 seriye çıkarken yanıtlanan soru 2/12’den 11/12’ye çıkar; marjinal soru başına bayt 0,06 GB’dan 34,72 GB’a kadar üç yüz kat değişir.
dugum-adihiçbir soruyu açmaz ve hiçbir soruyu kapatmaz; kaldırılması 634,82 GB kazandırır, tam kümenin yüzde 89’u. Budama ilk adımdır; sonrasında öteki etiketlerin maliyeti dokuzda birine iner.- Eklendiği basamakta soru açmayan etiket ile hiçbir soruya payı olmayan etiket farklıdır:
ortamtek başına soru açmaz ama kaldırıldığında S3 kapanır. - Çarpım üst sınırdır: envanterden sayılan gerçekleşen küme 6.888 seridir, kuramsal 30.816’nın dörtte biri; soru başına maliyet 7,21 GB’dan 1,61 GB’a iner.
- Saklama penceresi sorunun ufkunu belirler: 7 gün 9/12 soruyu 2,06 GB/soruya, 30 gün 10/12’yi 7,94 GB/soruya, 395 gün 11/12’yi 94,98 GB/soruya yanıtlar. 90 günlük pencere üç kat bayt karşılığında hiçbir yeni soru açmaz.
Sonraki Adım
Buraya kadar seri kümesi bir depo gibi ele alındı: kaç seri var, kaç bayt tutuyor, hangi ayrımı saklıyor. Ama hiçbir soru serinin kendisiyle yanıtlanmaz; yanıt bir toplulaştırmadan çıkar — ortalama, yüzdelik, toplam, oran. Bir sonraki ders aynı soruyu farklı toplulaştırmalarla yanıtlar ve yanıtın değiştiğini gösterir: hangi toplulaştırma neyi gizliyor, önceden toplulaştırma hangi ayrıntıyı geri getirilemez biçimde siliyor ve karşılığında sorgu maliyetinden ne kazandırıyor.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.