İçeriğe geç
academia.sh

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 bolge bir soruyu 1,55 GB’a açarken 4 değerli surum bir 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-adi hiç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: ortam tek 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.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat