Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Unë ju sugjeroj të lexoni transkriptin e raportit të fundit të vitit 2019 nga Alexander Valyalkin "Shko optimizimet në VictoriaMetrics"

VictoriaMetrics - një DBMS e shpejtë dhe e shkallëzueshme për ruajtjen dhe përpunimin e të dhënave në formën e një serie kohore (rekordi formon kohën dhe një grup vlerash që korrespondojnë me këtë kohë, për shembull, të marra përmes sondazheve periodike të statusit të sensorëve ose mbledhjes së metrikë).

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Këtu është një lidhje me videon e këtij raporti - https://youtu.be/MZ5P21j_HLE

Rrëshqitje

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Na trego rreth vetes. Unë jam Alexander Valyalkin. Këtu llogaria ime GitHub. Unë jam i apasionuar pas Go dhe optimizimit të performancës. Kam shkruar shumë biblioteka të dobishme dhe jo aq të dobishme. Ata fillojnë me ose fast, ose me quick parashtesë.

Aktualisht jam duke punuar në VictoriaMetrics. Çfarë është dhe çfarë jam duke bërë atje? Unë do të flas për këtë në këtë prezantim.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Përmbledhja e raportit është si më poshtë:

  • Së pari, unë do t'ju tregoj se çfarë është VictoriaMetrics.
  • Pastaj do t'ju tregoj se cilat janë seritë kohore.
  • Pastaj do t'ju tregoj se si funksionon një bazë të dhënash e serive kohore.
  • Më pas, unë do t'ju tregoj për arkitekturën e bazës së të dhënave: nga çfarë përbëhet.
  • Dhe pastaj le të kalojmë te optimizimet që ka VictoriaMetrics. Ky është një optimizim për indeksin e përmbysur dhe një optimizim për zbatimin e bitseve në Go.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

A e di dikush nga audienca se çfarë është VictoriaMetrics? Wow, shumë njerëz tashmë e dinë. Është një lajm i mirë. Për ata që nuk e dinë, kjo është një bazë të dhënash e serive kohore. Ai bazohet në arkitekturën ClickHouse, në disa detaje të zbatimit të ClickHouse. Për shembull, në të tilla si: MergeTree, llogaritja paralele në të gjitha bërthamat e disponueshme të procesorit dhe optimizimi i performancës duke punuar në blloqet e të dhënave që vendosen në cache të procesorit.

VictoriaMetrics ofron kompresim më të mirë të të dhënave sesa bazat e të dhënave të tjera të serive kohore.

Ai shkallëzohet vertikalisht - domethënë, ju mund të shtoni më shumë procesorë, më shumë RAM në një kompjuter. VictoriaMetrics do të përdorë me sukses këto burime të disponueshme dhe do të përmirësojë produktivitetin linear.

VictoriaMetrics gjithashtu shkallëzohet horizontalisht - domethënë, ju mund të shtoni nyje shtesë në grupin VictoriaMetrics dhe performanca e tij do të rritet pothuajse në mënyrë lineare.

Siç e keni marrë me mend, VictoriaMetrics është një bazë të dhënash e shpejtë, sepse nuk mund të shkruaj të tjera. Dhe është shkruar në Go, kështu që unë po flas për të në këtë takim.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Kush e di se çfarë është një seri kohore? Ai gjithashtu njeh shumë njerëz. Një seri kohore është një seri çiftesh (timestamp, значение), ku këto çifte janë të renditura sipas kohës. Vlera është një numër me pikë lundruese - float64.

Çdo seri kohore identifikohet në mënyrë unike nga një çelës. Nga se përbëhet ky çelës? Ai përbëhet nga një grup jo bosh çiftesh çelës-vlerë.

Këtu është një shembull i një serie kohore. Çelësi i kësaj serie është një listë e çifteve: __name__="cpu_usage" është emri i metrikës, instance="my-server" - ky është kompjuteri në të cilin është mbledhur kjo metrikë, datacenter="us-east" - kjo është qendra e të dhënave ku ndodhet ky kompjuter.

Ne përfunduam me një emër të serisë kohore të përbërë nga tre çifte çelës-vlerë. Ky çelës korrespondon me një listë çiftesh (timestamp, value). t1, t3, t3, ..., tN - këto janë vula kohore, 10, 20, 12, ..., 15 - vlerat përkatëse. Ky është përdorimi i cpu-së në një kohë të caktuar për një seri të caktuar.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Ku mund të përdoren seritë kohore? A ka dikush ndonjë ide?

  • Në DevOps, mund të matni CPU, RAM, rrjet, rps, numrin e gabimeve, etj.
  • IoT - ne mund të matim temperaturën, presionin, gjeokoordinatat dhe diçka tjetër.
  • Gjithashtu financa – ne mund të monitorojmë çmimet për të gjitha llojet e aksioneve dhe monedhave.
  • Përveç kësaj, seritë kohore mund të përdoren në monitorimin e proceseve të prodhimit në fabrika. Ne kemi përdorues që përdorin VictoriaMetrics për të monitoruar turbinat e erës, për robotët.
  • Seritë kohore janë gjithashtu të dobishme për mbledhjen e informacionit nga sensorë të pajisjeve të ndryshme. Për shembull, për një motor; për matjen e presionit të gomave; për matjen e shpejtësisë, distancës; për matjen e konsumit të benzinës etj.
  • Seritë kohore mund të përdoren gjithashtu për të monitoruar avionët. Çdo avion ka një kuti të zezë që mbledh seritë kohore për parametra të ndryshëm të shëndetit të avionit. Seritë kohore përdoren gjithashtu në industrinë e hapësirës ajrore.
  • Kujdesi shëndetësor është presioni i gjakut, pulsi etj.

Mund të ketë më shumë aplikacione që kam harruar, por shpresoj se e kuptoni që seritë kohore përdoren në mënyrë aktive në botën moderne. Dhe vëllimi i përdorimit të tyre po rritet çdo vit.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Pse keni nevojë për një bazë të dhënash të serive kohore? Pse nuk mund të përdorni një bazë të dhënash të rregullt relacionale për të ruajtur seritë kohore?

Sepse seritë kohore zakonisht përmbajnë një sasi të madhe informacioni, i cili është i vështirë për t'u ruajtur dhe përpunuar në bazat e të dhënave konvencionale. Prandaj, u shfaqën bazat e të dhënave të specializuara për seritë kohore. Këto baza ruajnë në mënyrë efektive pikat (timestamp, value) me çelësin e dhënë. Ato ofrojnë një API për leximin e të dhënave të ruajtura me çelës, me një çift të vetëm çelës-vlerë, ose me çifte të shumta çelës-vlerë, ose me regexp. Për shembull, ju dëshironi të gjeni ngarkesën e CPU-së të të gjitha shërbimeve tuaja në një qendër të dhënash në Amerikë, atëherë duhet të përdorni këtë pseudo-kërkesë.

Në mënyrë tipike, bazat e të dhënave të serive kohore ofrojnë gjuhë të specializuara për pyetje, sepse seritë kohore SQL nuk janë shumë të përshtatshme. Edhe pse ka baza të dhënash që mbështesin SQL, ajo nuk është shumë e përshtatshme. Gjuhët e pyetjeve si p.sh PromQL, InfluxQL, Gradient, Q. Shpresoj që dikush të ketë dëgjuar të paktën një nga këto gjuhë. Shumë njerëz ndoshta kanë dëgjuar për PromQL. Kjo është gjuha e pyetjes Prometheus.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Kështu duket një arkitekturë moderne e bazës së të dhënave të serive kohore duke përdorur VictoriaMetrics si shembull.

Ai përbëhet nga dy pjesë. Ky është ruajtja për indeksin e përmbysur dhe ruajtja për vlerat e serive kohore. Këto depo janë të ndara.

Kur një rekord i ri arrin në bazën e të dhënave, ne fillimisht i qasemi indeksit të përmbysur për të gjetur identifikuesin e serisë kohore për një grup të caktuar label=value për një metrikë të caktuar. Ne e gjejmë këtë identifikues dhe e ruajmë vlerën në dyqanin e të dhënave.

Kur vjen një kërkesë për të marrë të dhëna nga TSDB, fillimisht shkojmë te indeksi i përmbysur. Le të marrim gjithçka timeseries_ids rekorde që përputhen me këtë grup label=value. Dhe pastaj marrim të gjitha të dhënat e nevojshme nga depoja e të dhënave, të indeksuara nga timeseries_ids.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të shohim një shembull se si një bazë të dhënash e serive kohore përpunon një pyetje të përzgjedhur në hyrje.

  • Para së gjithash, ajo merr gjithçka timeseries_ids nga një indeks i përmbysur që përmban çiftet e dhëna label=value, ose plotësoni një shprehje të rregullt të caktuar.
  • Pastaj merr të gjitha pikat e të dhënave nga ruajtja e të dhënave në një interval kohor të caktuar për ato të gjetura timeseries_ids.
  • Pas kësaj, baza e të dhënave kryen disa llogaritje në këto pika të dhënash, sipas kërkesës së përdoruesit. Dhe pas kësaj kthen përgjigjen.

Në këtë prezantim do t'ju tregoj për pjesën e parë. Ky është një kërkim timeseries_ids sipas indeksit të përmbysur. Ju mund të shikoni për pjesën e dytë dhe pjesën e tretë më vonë Burimet e VictoriaMetrics, ose prisni derisa të përgatis raporte të tjera :)

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të kalojmë në indeksin e përmbysur. Shumë mund të mendojnë se kjo është e thjeshtë. Kush e di se çfarë është një indeks i përmbysur dhe si funksionon? Oh, jo më shumë njerëz. Le të përpiqemi të kuptojmë se çfarë është.

Në fakt është e thjeshtë. Është thjesht një fjalor që paraqet një çelës për një vlerë. Çfarë është një çelës? Ky çift label=valueKu label и value - këto janë rreshta. Dhe vlerat janë një grup timeseries_ids, e cila përfshin çiftin e dhënë label=value.

Indeksi i përmbysur ju lejon të gjeni shpejt gjithçka timeseries_ids, të cilat kanë dhënë label=value.

Gjithashtu ju lejon të gjeni shpejt timeseries_ids seri kohore për disa çifte label=value, ose për çifte label=regexp. Si ndodh kjo? Me gjetjen e kryqëzimit të grupit timeseries_ids për çdo çift label=value.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të shohim zbatime të ndryshme të indeksit të përmbysur. Le të fillojmë me zbatimin më të thjeshtë naiv. Ajo duket kështu.

Funksion getMetricIDs merr një listë të vargjeve. Çdo rresht përmban label=value. Ky funksion kthen një listë metricIDs.

Si punon? Këtu kemi një ndryshore globale të quajtur invertedIndex. Ky është një fjalor i rregullt (map), i cili do të hartojë vargun për të prerë ints. Linja përmban label=value.

Zbatimi i funksionit: merrni metricIDs për të parën label=value, pastaj kalojmë gjithçka tjetër label=value, e kuptojmë metricIDs për ata. Dhe thirrni funksionin intersectInts, e cila do të diskutohet më poshtë. Dhe ky funksion kthen kryqëzimin e këtyre listave.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Siç mund ta shihni, zbatimi i një indeksi të përmbysur nuk është shumë i komplikuar. Por ky është një zbatim naiv. Çfarë disavantazhesh ka? Disavantazhi kryesor i zbatimit naiv është se një indeks i tillë i përmbysur ruhet në RAM. Pas rinisjes së aplikacionit ne e humbasim këtë indeks. Nuk ka ruajtje të këtij indeksi në disk. Një indeks i tillë i përmbysur nuk ka gjasa të jetë i përshtatshëm për një bazë të dhënash.

E meta e dytë lidhet gjithashtu me kujtesën. Indeksi i përmbysur duhet të përshtatet në RAM. Nëse tejkalon madhësinë e RAM-it, atëherë padyshim që do të dalim nga gabimi i kujtesës. Dhe programi nuk do të funksionojë.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Ky problem mund të zgjidhet duke përdorur zgjidhje të gatshme si p.sh NiveliDBOse RocksDB.

Shkurtimisht, ne kemi nevojë për një bazë të dhënash që na lejon të bëjmë tre operacione shpejt.

  • Operacioni i parë është regjistrimi ключ-значение në këtë bazë të dhënash. Ajo e bën këtë shumë shpejt, ku ключ-значение janë vargje arbitrare.
  • Operacioni i dytë është një kërkim i shpejtë për një vlerë duke përdorur një çelës të caktuar.
  • Dhe operacioni i tretë është një kërkim i shpejtë për të gjitha vlerat me një prefiks të caktuar.

LevelDB dhe RocksDB - këto baza të të dhënave janë zhvilluar nga Google dhe Facebook. Së pari erdhi LevelDB. Pastaj djemtë nga Facebook morën LevelDB dhe filluan ta përmirësojnë atë, ata bënë RocksDB. Tani pothuajse të gjitha bazat e të dhënave të brendshme punojnë në RocksDB brenda Facebook, duke përfshirë ato që janë transferuar në RocksDB dhe MySQL. Ata e emëruan atë MyRocks.

Një indeks i përmbysur mund të zbatohet duke përdorur LevelDB. Si ta bëjmë atë? Ne kursejmë si çelës label=value. Dhe vlera është identifikuesi i serisë kohore ku çifti është i pranishëm label=value.

Nëse kemi shumë seri kohore me një çift të caktuar label=value, atëherë do të ketë shumë rreshta në këtë bazë të dhënash me të njëjtin çelës dhe të ndryshëm timeseries_ids. Për të marrë një listë të të gjithëve timeseries_ids, të cilat fillojnë me këtë label=prefix, ne bëjmë një skanim të intervalit për të cilin kjo bazë të dhënash është optimizuar. Kjo do të thotë, ne zgjedhim të gjitha linjat që fillojnë me label=prefix dhe merrni të nevojshmen timeseries_ids.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Këtu është një shembull i zbatimit të asaj se si do të dukej në Go. Kemi një indeks të përmbysur. Ky është LevelDB.

Funksioni është i njëjtë si për zbatimin naiv. Ai përsërit zbatimin naiv pothuajse rresht pas rreshti. Pika e vetme është se në vend që të ktheheni te map ne aksesojmë indeksin e përmbysur. Ne marrim të gjitha vlerat për të parën label=value. Pastaj kalojmë nëpër të gjitha çiftet e mbetura label=value dhe merrni grupet përkatëse të metricID-ve për to. Pastaj gjejmë kryqëzimin.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Gjithçka duket se është në rregull, por ka disavantazhe në këtë zgjidhje. VictoriaMetrics fillimisht zbatoi një indeks të përmbysur bazuar në LevelDB. Por në fund më duhej të hiqja dorë.

Pse? Sepse LevelDB është më i ngadalshëm se zbatimi naiv. Në një zbatim naiv, duke pasur parasysh një çelës të caktuar, ne e marrim menjëherë të gjithë fetën metricIDs. Ky është një operacion shumë i shpejtë - e gjithë feta është gati për përdorim.

Në LevelDB, sa herë që thirret një funksion GetValues ju duhet të kaloni nëpër të gjitha linjat që fillojnë me label=value. Dhe merrni vlerën për secilën rresht timeseries_ids. Nga të tilla timeseries_ids mblidhni një pjesë të tyre timeseries_ids. Natyrisht, kjo është shumë më e ngadaltë sesa thjesht qasja në një hartë të rregullt me ​​çelës.

E meta e dytë është se LevelDB është shkruar në C. Thirrja e funksioneve C nga Go nuk është shumë e shpejtë. Duhen qindra nanosekonda. Kjo nuk është shumë e shpejtë, sepse në krahasim me një thirrje funksioni të rregullt të shkruar në lëvizje, e cila zgjat 1-5 nanosekonda, diferenca në performancë është dhjetëra herë. Për VictoriaMetrics kjo ishte një e metë fatale :)

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Kështu që unë shkrova zbatimin tim të indeksit të përmbysur. Dhe ai e thirri atë bashkohen.

Mergeset bazohet në strukturën e të dhënave MergeTree. Kjo strukturë e të dhënave është huazuar nga ClickHouse. Natyrisht, mergeset duhet të optimizohet për kërkim të shpejtë timeseries_ids sipas çelësit të dhënë. Mergeset është shkruar tërësisht në Go. Ti mund te shohesh Burimet e VictoriaMetrics në GitHub. Zbatimi i bashkimit është në dosje /lib/bashkimi. Mund të përpiqeni të kuptoni se çfarë po ndodh atje.

API i bashkimit është shumë i ngjashëm me LevelDB dhe RocksDB. Kjo do të thotë, ju lejon të ruani shpejt regjistrimet e reja atje dhe të zgjidhni shpejt regjistrimet sipas një prefiksi të caktuar.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Ne do të flasim për disavantazhet e bashkimit më vonë. Tani le të flasim për problemet që u shfaqën me VictoriaMetrics në prodhim kur zbatohet një indeks i përmbysur.

Pse lindën?

Arsyeja e parë është shkalla e lartë e dyndjes. Përkthyer në Rusisht, ky është një ndryshim i shpeshtë në seritë kohore. Kjo është kur një seri kohore përfundon dhe fillon një seri e re, ose fillojnë shumë seri të reja kohore. Dhe kjo ndodh shpesh.

Arsyeja e dytë është numri i madh i serive kohore. Në fillim, kur monitorimi po fitonte popullaritet, numri i serive kohore ishte i vogël. Për shembull, për çdo kompjuter ju duhet të monitoroni ngarkimin e procesorit, kujtesës, rrjetit dhe diskut. 4 seri kohore për kompjuter. Le të themi se keni 100 kompjuterë dhe 400 seri kohore. Kjo është shumë pak.

Me kalimin e kohës, njerëzit kuptuan se mund të masnin informacion më të hollësishëm. Për shembull, matni ngarkesën jo të të gjithë procesorit, por veçmas të çdo bërthame të procesorit. Nëse keni 40 bërthama procesori, atëherë keni 40 herë më shumë seri kohore për të matur ngarkesën e procesorit.

Por kjo nuk është e gjitha. Çdo bërthamë procesori mund të ketë disa gjendje, si p.sh. i papunë, kur është i papunë. Dhe gjithashtu punoni në hapësirën e përdoruesit, punoni në hapësirën e kernelit dhe gjendje të tjera. Dhe çdo gjendje e tillë mund të matet gjithashtu si një seri kohore e veçantë. Kjo gjithashtu rrit numrin e rreshtave me 7-8 herë.

Nga një metrikë kemi marrë 40 x 8 = 320 metrikë për vetëm një kompjuter. Duke shumëzuar me 100, marrim 32 në vend të 000.

Pastaj erdhi Kubernetes. Dhe u përkeqësua sepse Kubernetes mund të presë shumë shërbime të ndryshme. Çdo shërbim në Kubernetes përbëhet nga shumë pods. Dhe e gjithë kjo duhet të monitorohet. Përveç kësaj, ne kemi një vendosje të vazhdueshme të versioneve të reja të shërbimeve tuaja. Për çdo version të ri, duhet të krijohen seri të reja kohore. Si rezultat, numri i serive kohore rritet në mënyrë eksponenciale dhe përballemi me problemin e një numri të madh të serive kohore, i cili quhet kardinalitet i lartë. VictoriaMetrics e përballon atë me sukses në krahasim me bazat e të dhënave të tjera të serive kohore.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të hedhim një vështrim më të afërt në shkallën e lartë të frenimit. Çfarë e shkakton shkallën e lartë të frenimit në prodhim? Sepse disa kuptime të etiketave dhe etiketave ndryshojnë vazhdimisht.

Për shembull, merrni Kubernetes, i cili ka konceptin deployment, d.m.th. kur shfaqet një version i ri i aplikacionit tuaj. Për disa arsye, zhvilluesit e Kubernetes vendosën të shtojnë ID-në e vendosjes në etiketë.

Në çfarë çoi kjo? Për më tepër, me çdo vendosje të re, të gjitha seritë e vjetra kohore ndërpriten dhe në vend të tyre, seritë e reja kohore fillojnë me një vlerë të re të etiketës. deployment_id. Mund të ketë qindra mijëra dhe madje miliona rreshta të tillë.

Gjëja e rëndësishme për të gjithë këtë është se numri i përgjithshëm i serive kohore rritet, por numri i serive kohore që aktualisht janë aktive dhe marrin të dhëna mbetet konstant. Kjo gjendje quhet shkalla e lartë e djegies.

Problemi kryesor i shkallës së lartë të frenimit është sigurimi i një shpejtësie konstante kërkimi për të gjitha seritë kohore për një grup të caktuar etiketash gjatë një intervali të caktuar kohor. Zakonisht ky është intervali kohor për orën e fundit ose ditën e fundit.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Si të zgjidhet ky problem? Këtu është opsioni i parë. Kjo është për të ndarë indeksin e përmbysur në pjesë të pavarura me kalimin e kohës. Kjo do të thotë, kalon një interval kohor, ne përfundojmë punën me indeksin aktual të përmbysur. Dhe krijoni një indeks të ri të përmbysur. Një interval tjetër kohor kalon, ne krijojmë një tjetër dhe një tjetër.

Dhe kur marrim mostra nga këta indekse të përmbysur, gjejmë një grup indeksesh të përmbysur që bien brenda intervalit të dhënë. Dhe, në përputhje me rrethanat, ne zgjedhim ID-në e serisë kohore prej andej.

Kjo kursen burime sepse nuk duhet të shikojmë pjesët që nuk bien brenda intervalit të caktuar. Kjo do të thotë, zakonisht, nëse zgjedhim të dhëna për orën e fundit, atëherë për intervalet e mëparshme kohore ne i anashkalojmë kërkesat.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Ekziston një mundësi tjetër për të zgjidhur këtë problem. Kjo është për të ruajtur për çdo ditë një listë të veçantë të ID-ve të serive kohore që kanë ndodhur në atë ditë.

Avantazhi i kësaj zgjidhjeje ndaj zgjidhjes së mëparshme është se ne nuk dublikojmë informacionin e serisë kohore që nuk zhduket me kalimin e kohës. Ato janë vazhdimisht të pranishme dhe nuk ndryshojnë.

Disavantazhi është se një zgjidhje e tillë është më e vështirë për t'u zbatuar dhe më e vështirë për të korrigjuar. Dhe VictoriaMetrics zgjodhi këtë zgjidhje. Kështu ka ndodhur historikisht. Kjo zgjidhje gjithashtu funksionon mirë në krahasim me atë të mëparshme. Sepse kjo zgjidhje nuk u zbatua për faktin se është e nevojshme të dublikohen të dhënat në secilën ndarje për seritë kohore që nuk ndryshojnë, pra që nuk zhduken me kalimin e kohës. VictoriaMetrics u optimizua kryesisht për konsumin e hapësirës në disk, dhe zbatimi i mëparshëm e përkeqësoi konsumin e hapësirës në disk. Por ky zbatim është më i përshtatshëm për të minimizuar konsumin e hapësirës në disk, kështu që u zgjodh.

Më duhej ta luftoja. Lufta ishte që në këtë zbatim ju duhet ende të zgjidhni një numër shumë më të madh timeseries_ids për të dhëna sesa kur indeksi i përmbysur është i ndarë në kohë.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Si e zgjidhëm këtë problem? Ne e zgjidhëm atë në një mënyrë origjinale - duke ruajtur disa identifikues të serive kohore në çdo hyrje të indeksit të përmbysur në vend të një identifikuesi. Kjo është, ne kemi një çelës label=value, e cila ndodh në çdo seri kohore. Dhe tani ne kursejmë disa timeseries_ids në një hyrje.

Ja një shembull. Më parë kishim N hyrje, por tani kemi një hyrje, prefiksi i të cilit është i njëjtë me të gjitha të tjerat. Për hyrjen e mëparshme, vlera përmban të gjitha ID-të e serive kohore.

Kjo bëri të mundur rritjen e shpejtësisë së skanimit të një indeksi të tillë të përmbysur deri në 10 herë. Dhe kjo na lejoi të reduktojmë konsumin e memories për cache, sepse tani ne ruajmë vargun label=value vetëm një herë në cache së bashku N herë. Dhe kjo linjë mund të jetë e madhe nëse ruani rreshta të gjata në etiketat dhe etiketat tuaja, të cilat Kubernetes pëlqen t'i fusë atje.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Një tjetër mundësi për përshpejtimin e kërkimit në një indeks të përmbysur është sharding. Krijimi i disa indekseve të përmbysur në vend të njërit dhe ndarja e të dhënave ndërmjet tyre me çelës. Ky është një grup key=value avulli. Kjo do të thotë, marrim disa indekse të pavarura të përmbysura, të cilat mund t'i kërkojmë paralelisht në disa procesorë. Implementimet e mëparshme lejuan funksionimin vetëm në modalitetin me një procesor, d.m.th., skanimin e të dhënave vetëm në një bërthamë. Kjo zgjidhje ju lejon të skanoni të dhënat në disa bërthama në të njëjtën kohë, siç pëlqen të bëjë ClickHouse. Kjo është ajo që ne planifikojmë të zbatojmë.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Tani le të kthehemi te delet tona - te funksioni i kryqëzimit timeseries_ids. Le të shqyrtojmë se çfarë zbatimesh mund të ketë. Ky funksion ju lejon të gjeni timeseries_ids për një grup të caktuar label=value.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Opsioni i parë është një zbatim naiv. Dy sythe të mbivendosur. Këtu marrim hyrjen e funksionit intersectInts dy feta - a и b. Në dalje, duhet të na kthejë kryqëzimin e këtyre fetave.

Një zbatim naiv duket kështu. Ne përsërisim mbi të gjitha vlerat nga feta a, brenda këtij laku kalojmë të gjitha vlerat e fetës b. Dhe ne i krahasojmë ato. Nëse ato përputhen, atëherë ne kemi gjetur një kryqëzim. Dhe ruajeni brenda result.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Cilat janë disavantazhet? Kompleksiteti kuadratik është pengesa kryesore e tij. Për shembull, nëse dimensionet tuaja janë feta a и b një milion në të njëjtën kohë, atëherë ky funksion nuk do t'ju kthejë kurrë një përgjigje. Sepse do të duhet të bëjë një trilion përsëritje, që është shumë edhe për kompjuterët modernë.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Zbatimi i dytë bazohet në hartë. Ne krijojmë hartën. Ne vendosim të gjitha vlerat nga feta në këtë hartë a. Pastaj kalojmë nëpër fetë në një lak të veçantë b. Dhe ne kontrollojmë nëse kjo vlerë është nga feta b në hartë. Nëse ekziston, atëherë shtojeni në rezultat.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Cilat janë përfitimet? Avantazhi është se ka vetëm kompleksitet linear. Kjo do të thotë, funksioni do të ekzekutohet shumë më shpejt për feta më të mëdha. Për një pjesë me madhësi milioni, ky funksion do të ekzekutohet në 2 milionë përsëritje, në krahasim me trilion përsëritjet e funksionit të mëparshëm.

E keqja është se ky funksion kërkon më shumë memorie për të krijuar këtë hartë.

E meta e dytë është shpenzimi i madh për hash. Kjo pengesë nuk është shumë e dukshme. Dhe për ne gjithashtu nuk ishte shumë e dukshme, kështu që fillimisht në VictoriaMetrics zbatimi i kryqëzimit ishte përmes një harte. Por më pas profilizimi tregoi se koha e procesorit kryesor harxhohet duke shkruar në hartë dhe duke kontrolluar praninë e një vlere në këtë hartë.

Pse humbet koha e CPU-së në këto vende? Sepse Go kryen një operacion hashing në këto linja. Kjo do të thotë, ai llogarit hash-in e çelësit në mënyrë që më pas t'i qaset atij në një indeks të caktuar në HashMap. Operacioni i llogaritjes së hash-it përfundon në dhjetëra nanosekonda. Kjo është e ngadaltë për VictoriaMetrics.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Vendosa të zbatoj një bitset të optimizuar posaçërisht për këtë rast. Kështu duket tani kryqëzimi i dy fetave. Këtu krijojmë një grup bit. I shtojmë elementë nga feta e parë. Pastaj kontrollojmë praninë e këtyre elementeve në fetën e dytë. Dhe shtoni ato në rezultat. Kjo do të thotë, pothuajse nuk ndryshon nga shembulli i mëparshëm. E vetmja gjë këtu është se ne zëvendësuam aksesin në hartë me funksione të personalizuara add и has.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Në pamje të parë, duket se kjo duhet të funksionojë më ngadalë, nëse më parë është përdorur një hartë standarde, dhe më pas thirren disa funksione të tjera, por profilizimi tregon se kjo gjë funksionon 10 herë më shpejt se harta standarde në rastin e VictoriaMetrics.

Përveç kësaj, ai përdor shumë më pak memorie në krahasim me zbatimin e hartës. Sepse ne po ruajmë bit këtu në vend të vlerave tetë bajt.

Disavantazhi i këtij zbatimi është se nuk është aq i dukshëm, jo ​​i parëndësishëm.

Një tjetër pengesë që shumë mund të mos e vënë re është se ky zbatim mund të mos funksionojë mirë në disa raste. Domethënë, është optimizuar për një rast specifik, për këtë rast të kryqëzimit të ID-ve të serive kohore VictoriaMetrics. Kjo nuk do të thotë se është i përshtatshëm për të gjitha rastet. Nëse përdoret gabimisht, nuk do të kemi një rritje të performancës, por një gabim memorie dhe një ngadalësim të performancës.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të shqyrtojmë zbatimin e kësaj strukture. Nëse dëshironi të shikoni, ai ndodhet në burimet e VictoriaMetrics, në dosje lib/uint64set. Është optimizuar posaçërisht për rastin VictoriaMetrics, ku timeseries_id është një vlerë 64-bitësh, ku 32 bit-ët e parë janë në thelb konstante dhe vetëm 32-bitët e fundit ndryshojnë.

Kjo strukturë e të dhënave nuk ruhet në disk, ajo funksionon vetëm në memorie.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Këtu është API-ja e tij. Nuk është shumë e komplikuar. API është përshtatur posaçërisht për një shembull specifik të përdorimit të VictoriaMetrics. Kjo do të thotë, nuk ka funksione të panevojshme këtu. Këtu janë funksionet që përdoren në mënyrë eksplicite nga VictoriaMetrics.

Ka funksione add, e cila shton vlera të reja. Ekziston një funksion has, i cili kontrollon për vlera të reja. Dhe ka një funksion del, e cila heq vlerat. Ekziston një funksion ndihmës len, e cila kthen madhësinë e grupit. Funksioni clone klonon shumë. Dhe funksioni appendto e konverton këtë grup në fetë timeseries_ids.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Kështu duket zbatimi i kësaj strukture të dhënash. grupi ka dy elemente:

  • ItemsCount është një fushë ndihmëse për të kthyer shpejt numrin e elementeve në një grup. Do të ishte e mundur të bëhej pa këtë fushë ndihmëse, por duhej shtuar këtu sepse VictoriaMetrics shpesh kërkon gjatësinë e biteve në algoritmet e saj.

  • Fusha e dytë është buckets. Kjo është një pjesë nga struktura bucket32. Çdo strukturë ruan hi fushë. Këto janë 32 bitet e sipërme. Dhe dy feta - b16his и buckets nga bucket16 strukturat.

Këtu ruhen 16 bitët kryesorë të pjesës së dytë të strukturës 64-bit. Dhe këtu bit-et ruhen për 16 bit-et më të ulët të çdo bajt.

Bucket64 përbëhet nga një grup uint64. Gjatësia llogaritet duke përdorur këto konstante. Në një bucket16 maksimumi mund të ruhet 2^16=65536 pak. Nëse e ndani këtë me 8, atëherë është 8 kilobajt. Nëse pjesëtoni përsëri me 8, është 1000 uint64 kuptimi. Kjo eshte Bucket16 - kjo është struktura jonë 8 kilobajt.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Le të shohim se si zbatohet një nga metodat e kësaj strukture për shtimin e një vlere të re.

Gjithçka fillon me uint64 kuptimet. Ne llogarisim 32 bitet e sipërme, llogarisim 32 bitet e poshtme. Le të kalojmë gjithçka buckets. Krahasojmë 32 bitet e sipërme në secilën kovë me vlerën që shtohet. Dhe nëse përputhen, atëherë ne e quajmë funksionin add në strukturën b32 buckets. Dhe shtoni 32 bitet e poshtme atje. Dhe nëse do të kthehej true, atëherë kjo do të thotë se ne kemi shtuar një vlerë të tillë dhe nuk kemi pasur një vlerë të tillë. Nëse kthehet false, atëherë një kuptim i tillë ekzistonte tashmë. Pastaj rrisim numrin e elementeve në strukturë.

Nëse nuk kemi gjetur atë që ju nevojitet bucket me vlerën e kërkuar hi, atëherë e quajmë funksionin addAlloc, e cila do të prodhojë një të re bucket, duke e shtuar atë në strukturën e kovës.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Ky është zbatimi i funksionit b32.add. Është e ngjashme me zbatimin e mëparshëm. Ne llogarisim 16 bit më të rëndësishëm, 16 bit më pak të rëndësishëm.

Pastaj kalojmë nëpër të gjitha 16 bitet e sipërme. Ne gjejmë ndeshje. Dhe nëse ka një përputhje, ne e quajmë metodën e shtimit, të cilën do ta shqyrtojmë në faqen tjetër bucket16.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Dhe këtu është niveli më i ulët, i cili duhet të optimizohet sa më shumë që të jetë e mundur. Ne llogarisim për uint64 Vlera e id në bit dhe gjithashtu bitmask. Kjo është një maskë për një vlerë të caktuar 64-bit, e cila mund të përdoret për të kontrolluar praninë e këtij biti ose për ta vendosur atë. Ne kontrollojmë nëse ky bit është vendosur dhe e vendosim atë dhe kthejmë praninë. Ky është zbatimi ynë, i cili na lejoi të përshpejtojmë funksionimin e identifikimit të kryqëzimit të serive kohore me 10 herë në krahasim me hartat konvencionale.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Përveç këtij optimizimi, VictoriaMetrics ka shumë optimizime të tjera. Shumica e këtyre optimizimeve u shtuan për një arsye, por pas profilizimit të kodit në prodhim.

Ky është rregulli kryesor i optimizimit - mos shtoni optimizim duke supozuar se do të ketë një pengesë këtu, sepse mund të rezultojë se nuk do të ketë një pengesë atje. Optimizimi zakonisht degradon cilësinë e kodit. Prandaj, ia vlen të optimizohet vetëm pas profilizimit dhe mundësisht në prodhim, në mënyrë që këto të jenë të dhëna reale. Nëse dikush është i interesuar, mund të shikoni kodin burimor të VictoriaMetrics dhe të eksploroni optimizime të tjera që janë atje.

Shkoni në optimizimet në VictoriaMetrics. Alexander Valyalkin

Kam nje pyetje per bitset. Shumë e ngjashme me implementimin e vektorit bool C++, bitset i optimizuar. A e morët zbatimin prej andej?

Jo, jo nga atje. Gjatë zbatimit të këtij grupi bit, jam udhëhequr nga njohuritë për strukturën e këtyre serive të identifikimit, të cilat përdoren në VictoriaMetrics. Dhe struktura e tyre është e tillë që 32 bitët e sipërm janë në thelb konstante. 32-bitët më të ulët mund të ndryshojnë. Sa më i ulët të jetë biti, aq më shpesh mund të ndryshojë. Prandaj, ky zbatim është optimizuar posaçërisht për këtë strukturë të dhënash. Zbatimi i C++, me sa di unë, është i optimizuar për rastin e përgjithshëm. Nëse optimizoni për rastin e përgjithshëm, kjo do të thotë se nuk do të jetë më optimali për një rast specifik.

Unë gjithashtu ju këshilloj të shikoni raportin e Alexey Milovid. Rreth një muaj më parë, ai foli për optimizimin në ClickHouse për specializime specifike. Ai thjesht thotë se në rastin e përgjithshëm, një zbatim C++ ose ndonjë zbatim tjetër është përshtatur për të funksionuar mirë mesatarisht në një spital. Mund të funksionojë më keq se një zbatim specifik i njohurive si ky i yni, ku ne e dimë se 32 bitet kryesore janë kryesisht konstante.

Unë kam një pyetje të dytë. Cili është ndryshimi themelor nga InfluxDB?

Ka shumë dallime thelbësore. Për sa i përket performancës dhe konsumit të memories, InfluxDB në teste tregon 10 herë më shumë konsum të memories për seritë kohore me kardinalitet të lartë, kur keni shumë prej tyre, për shembull, miliona. Për shembull, VictoriaMetrics konsumon 1 GB për milion rreshta aktive, ndërsa InfluxDB konsumon 10 GB. Dhe ky është një ndryshim i madh.

Dallimi i dytë themelor është se InfluxDB ka gjuhë të çuditshme të pyetjeve - Flux dhe InfluxQL. Ato nuk janë shumë të përshtatshme për të punuar me seri kohore në krahasim me PromQL, e cila mbështetet nga VictoriaMetrics. PromQL është një gjuhë pyetjesh nga Prometheus.

Dhe një ndryshim tjetër është se InfluxDB ka një model paksa të çuditshëm të dhënash, ku çdo rresht mund të ruajë disa fusha me një grup të ndryshëm etiketash. Këto rreshta ndahen më tej në tabela të ndryshme. Këto komplikime shtesë e ndërlikojnë punën e mëvonshme me këtë bazë të dhënash. Është e vështirë për të mbështetur dhe kuptuar.

Në VictoriaMetrics gjithçka është shumë më e thjeshtë. Atje, çdo seri kohore është një vlerë-kyç. Vlera është një grup pikësh - (timestamp, value), dhe çelësi është grupi label=value. Nuk ka ndarje midis fushave dhe matjeve. Ju lejon të zgjidhni çdo të dhënë dhe më pas të kombinoni, shtoni, zbritni, shumëzoni, pjesëtoni, ndryshe nga InfluxDB ku llogaritjet midis rreshtave të ndryshëm nuk zbatohen ende me sa di unë. Edhe nëse zbatohen, është e vështirë, duhet të shkruani shumë kod.

Unë kam një pyetje sqaruese. A e kuptova mirë që kishte një lloj problemi për të cilin folët, që ky indeks i përmbysur nuk futet në memorie, pra ka ndarje atje?

Së pari, tregova një zbatim naiv të një indeksi të përmbysur në një hartë standarde Go. Ky implementim nuk është i përshtatshëm për bazat e të dhënave sepse ky indeks i përmbysur nuk ruhet në disk dhe baza e të dhënave duhet të ruhet në disk në mënyrë që këto të dhëna të mbeten të disponueshme pas rinisjes. Në këtë zbatim, kur rinisni aplikacionin, indeksi juaj i përmbysur do të zhduket. Dhe do të humbni aksesin në të gjitha të dhënat sepse nuk do të mund t'i gjeni.

Përshëndetje! Faleminderit për raportin! Emri im është Pavel. Unë jam nga Wildberries. Kam disa pyetje për ju. Pyetja e parë. A mendoni se nëse do të kishit zgjedhur një parim tjetër gjatë ndërtimit të arkitekturës së aplikacionit tuaj dhe do të kishit ndarë të dhënat me kalimin e kohës, atëherë ndoshta do të kishit qenë në gjendje të kryqëzonit të dhënat gjatë kërkimit, bazuar vetëm në faktin se një ndarje përmban të dhëna për një periudhë kohore, domethënë në një interval kohor dhe nuk do të të duhet të shqetësohesh për faktin se pjesët e tua shpërndahen ndryshe? Pyetja numër 2 - meqenëse po zbatoni një algoritëm të ngjashëm me bitset dhe gjithçka tjetër, atëherë ndoshta keni provuar të përdorni udhëzimet e procesorit? Ndoshta ju keni provuar optimizime të tilla?

Unë do t'i përgjigjem të dytës menjëherë. Nuk kemi arritur ende në atë pikë. Por nëse është e nevojshme, ne do të arrijmë atje. Dhe e para, cila ishte pyetja?

Ju diskutuat dy skenarë. Dhe ata thanë se zgjodhën të dytin me një zbatim më kompleks. Dhe nuk preferuan të parën, ku të dhënat ndahen sipas kohës.

Po. Në rastin e parë, vëllimi total i indeksit do të ishte më i madh, sepse në çdo ndarje do të duhej të ruanim të dhëna dublikate për ato seri kohore që vazhdojnë nëpër të gjitha këto ndarje. Dhe nëse shkalla e përmbytjes së serive kohore është e vogël, d.m.th. të njëjtat seri përdoren vazhdimisht, atëherë në rastin e parë do të humbnim shumë më tepër në sasinë e hapësirës së zënë në disk në krahasim me rastin e dytë.

Dhe kështu - po, ndarja e kohës është një opsion i mirë. Prometeu e përdor atë. Por Prometeu ka një pengesë tjetër. Kur bashkon këto pjesë të të dhënave, duhet të mbajë në kujtesë meta informacion për të gjitha etiketat dhe seritë kohore. Prandaj, nëse pjesët e të dhënave që bashkon janë të mëdha, atëherë konsumi i kujtesës rritet shumë gjatë bashkimit, ndryshe nga VictoriaMetrics. Kur bashkohet, VictoriaMetrics nuk konsumon fare memorie; konsumohen vetëm disa kilobajt, pavarësisht nga madhësia e pjesëve të bashkuara të të dhënave.

Algoritmi që po përdorni përdor memorie. Ajo shënon etiketat e serive kohore që përmbajnë vlera. Dhe në këtë mënyrë ju kontrolloni praninë e çiftuar në një grup të dhënash dhe në një tjetër. Dhe ju e kuptoni nëse kryqëzimi ka ndodhur apo jo. Në mënyrë tipike, bazat e të dhënave zbatojnë kursorë dhe përsëritës që ruajnë përmbajtjen e tyre aktuale dhe kalojnë nëpër të dhënat e renditura për shkak të kompleksitetit të thjeshtë të këtyre operacioneve.

Pse nuk përdorim kursorët për të përshkuar të dhënat?

Po.

Ne ruajmë rreshtat e renditur në LevelDB ose mergeset. Mund të lëvizim kursorin dhe të gjejmë kryqëzimin. Pse nuk e përdorim atë? Sepse është i ngadalshëm. Sepse kursorët nënkuptojnë që ju duhet të thërrisni një funksion për çdo rresht. Një thirrje funksioni është 5 nanosekonda. Dhe nëse keni 100 linja, atëherë rezulton se kalojmë gjysmë sekonde vetëm duke thirrur funksionin.

Ekziston një gjë e tillë, po. Dhe pyetja ime e fundit. Pyetja mund të tingëllojë pak e çuditshme. Pse nuk është e mundur të lexoni të gjithë agregatët e nevojshëm në momentin që vijnë të dhënat dhe t'i ruani ato në formën e kërkuar? Pse të kurseni vëllime të mëdha në disa sisteme si VictoriaMetrics, ClickHouse, etj., dhe pastaj të shpenzoni shumë kohë në to?

Do të jap një shembull për ta bërë më të qartë. Le të themi se si funksionon një shpejtësimatës i vogël lodër? Ai regjistron distancën që keni udhëtuar, duke e shtuar atë në një vlerë gjatë gjithë kohës, dhe të dytën - kohën. Dhe ndan. Dhe merr shpejtësi mesatare. Ju mund të bëni për të njëjtën gjë. Shtoni të gjitha faktet e nevojshme në fluturim.

Mirë, e kuptoj pyetjen. Shembulli juaj e ka vendin e vet. Nëse e dini se çfarë agregate ju nevojiten, atëherë ky është zbatimi më i mirë. Por problemi është se njerëzit i ruajnë këto metrika, disa të dhëna në ClickHouse dhe ata ende nuk e dinë se si do t'i grumbullojnë dhe filtrojnë ato në të ardhmen, kështu që duhet të ruajnë të gjitha të dhënat e papërpunuara. Por nëse e dini se duhet të llogarisni diçka mesatarisht, atëherë pse të mos e llogarisni atë në vend që të ruani një grumbull vlerash të papërpunuara atje? Por kjo është vetëm nëse e dini saktësisht se çfarë ju nevojitet.

Nga rruga, bazat e të dhënave për ruajtjen e serive kohore mbështesin numërimin e agregateve. Për shembull, Prometeu mbështet rregullat e regjistrimit. Kjo do të thotë, kjo mund të bëhet nëse e dini se cilat njësi do t'ju nevojiten. VictoriaMetrics nuk e ka këtë ende, por zakonisht paraprihet nga Prometheus, në të cilin kjo mund të bëhet në rregullat e rikodimit.

Për shembull, në punën time të mëparshme më duhej të numëroja numrin e ngjarjeve në një dritare rrëshqitëse gjatë orës së fundit. Problemi është se më duhej të bëja një implementim personal në Go, pra një shërbim për numërimin e kësaj gjëje. Ky shërbim në fund të fundit ishte jo i parëndësishëm, sepse është i vështirë për t'u llogaritur. Zbatimi mund të jetë i thjeshtë nëse keni nevojë të numëroni disa agregate në intervale kohore fikse. Nëse dëshironi të numëroni ngjarjet në një dritare rrëshqitëse, atëherë nuk është aq e thjeshtë sa duket. Unë mendoj se kjo nuk është zbatuar ende në ClickHouse ose në bazat e të dhënave të serive kohore, sepse është e vështirë të zbatohet.

Dhe një pyetje tjetër. Thjesht po flisnim për mesataren, dhe m'u kujtua se dikur ekzistonte një gjë e tillë si Grafiti me një bazë karboni. Dhe ai dinte të hollonte të dhënat e vjetra, domethënë të linte një pikë në minutë, një pikë në orë, etj. Në parim, kjo është mjaft e përshtatshme nëse kemi nevojë për të dhëna të papërpunuara, relativisht të flasim, për një muaj, dhe gjithçka tjetër mundet. të rrallohen . Por Prometheus dhe VictoriaMetrics nuk e mbështesin këtë funksionalitet. A është planifikuar të mbështetet? Nëse jo, pse jo?

Faleminderit për pyetjen. Përdoruesit tanë e bëjnë këtë pyetje në mënyrë periodike. Ata pyesin se kur do të shtojmë mbështetje për uljen e mostrave. Këtu ka disa probleme. Së pari, çdo përdorues e kupton downsampling diçka ndryshe: dikush dëshiron të marrë ndonjë pikë arbitrare në një interval të caktuar, dikush dëshiron vlera maksimale, minimale, mesatare. Nëse shumë sisteme shkruajnë të dhëna në bazën tuaj të të dhënave, atëherë nuk mund t'i bashkoni të gjitha së bashku. Mund të ndodhë që çdo sistem të kërkojë rrallime të ndryshme. Dhe kjo është e vështirë për t'u zbatuar.

Dhe gjëja e dytë është se VictoriaMetrics, si ClickHouse, është e optimizuar për të punuar në sasi të mëdha të dhënash të papërpunuara, kështu që mund të zhvillojë një miliardë rreshta në më pak se një sekondë nëse keni shumë bërthama në sistemin tuaj. Skanimi i pikave të serive kohore në VictoriaMetrics – 50 pikë për sekondë për bërthamë. Dhe kjo performancë shkallëzohet në bërthamat ekzistuese. Kjo do të thotë, nëse keni 000 bërthama, për shembull, do të skanoni një miliard pikë në sekondë. Dhe kjo veti e VictoriaMetrics dhe ClickHouse redukton nevojën për zvogëlim të përzgjedhjes.

Një veçori tjetër është se VictoriaMetrics i ngjesh në mënyrë efektive këto të dhëna. Kompresimi mesatarisht në prodhim është nga 0,4 në 0,8 bajt për pikë. Çdo pikë është një vulë kohore + vlerë. Dhe është i ngjeshur mesatarisht në më pak se një bajt.

Sergej. Kam një pyetje. Cila është sasia minimale e kohës së regjistrimit?

Një milisekondë. Së fundmi kemi pasur një bisedë me zhvillues të tjerë të bazës së të dhënave të serive kohore. Koha minimale e tyre është një sekondë. Dhe në Grafit, për shembull, është gjithashtu një sekondë. Në OpenTSDB është gjithashtu një sekondë. InfluxDB ka saktësi nanosekonda. Në VictoriaMetrics është një milisekonda, sepse në Prometheus është një milisekondë. Dhe VictoriaMetrics fillimisht u zhvillua si ruajtje në distancë për Prometheus. Por tani mund të kursejë të dhëna nga sisteme të tjera.

Personi me të cilin fola thotë se kanë saktësi sekondë në sekondë - kjo është e mjaftueshme për ta sepse varet nga lloji i të dhënave që ruhen në bazën e të dhënave të serive kohore. Nëse këto janë të dhëna DevOps ose të dhëna nga infrastruktura, ku i mbledhni në intervale prej 30 sekondash, në minutë, atëherë mjafton saktësia e sekondës, nuk ju nevojitet asgjë më pak. Dhe nëse i mbledhni këto të dhëna nga sistemet e tregtimit me frekuencë të lartë, atëherë keni nevojë për saktësi nanosekonda.

Saktësia milisekonda në VictoriaMetrics është gjithashtu e përshtatshme për rastin DevOps dhe mund të jetë e përshtatshme për shumicën e rasteve që përmenda në fillim të raportit. E vetmja gjë për të cilën mund të mos jetë e përshtatshme janë sistemet e tregtimit me frekuencë të lartë.

Faleminderit! Dhe një pyetje tjetër. Çfarë është përputhshmëria në PromQL?

Pajtueshmëri e plotë prapa. VictoriaMetrics mbështet plotësisht PromQL. Përveç kësaj, ai shton funksionalitet shtesë të avancuar në PromQL, i cili quhet MetricsQL. Ka një bisedë në YouTube për këtë funksionalitet të zgjeruar. Unë fola në Takimin e Monitorimit në pranverë në Shën Petersburg.

Kanali Telegram VictoriaMetrics.

Vetëm përdoruesit e regjistruar mund të marrin pjesë në anketë. Hyni, te lutem

Çfarë po ju pengon të kaloni te VictoriaMetrics si ruajtja juaj afatgjatë për Prometheus? (Shkruani në komente, do ta shtoj në sondazh))

  • 71,4%Unë nuk përdor Prometheus5

  • 28,6%Nuk e dija për VictoriaMetrics2

7 përdorues votuan. 12 përdorues abstenuan.

Burimi: www.habr.com

Shto një koment