Iesaku izlasÄ«t 2019. gada beigu ziÅojuma atÅ”ifrÄjumu, ko sagatavojis Aleksandrs Valjaļkins āOptimizÄÅ”ana programmÄ VictoriaMetricsā.
Å eit ir saite uz Ŕī ziÅojuma video -
PastÄsti mums par sevi. Es esmu Aleksandrs Valjaļkins. Å eit fast
, vai ar quick
priedÄklis.
PaÅ”laik es strÄdÄju pie VictoriaMetrics. Kas tas ir un ko es tur daru? Par to es runÄÅ”u Å”ajÄ prezentÄcijÄ.
ZiÅojuma izklÄsts ir Å”Äds:
- PirmkÄrt, es jums pastÄstÄ«Å”u, kas ir VictoriaMetrics.
- Tad es jums pastÄstÄ«Å”u, kas ir laikrindas.
- Tad es jums pastÄstÄ«Å”u, kÄ darbojas laikrindu datubÄze.
- TÄlÄk es jums pastÄstÄ«Å”u par datu bÄzes arhitektÅ«ru: no kÄ tÄ sastÄv.
- Un tad pÄriesim pie optimizÄcijas, ko piedÄvÄ VictoriaMetrics. Å Ä« ir optimizÄcija apgrieztajam indeksam un optimizÄcija bitkopas ievieÅ”anai Go.
Vai kÄds no skatÄ«tÄjiem zina, kas ir VictoriaMetrics? Oho, daudzi jau zina. TÄ ir laba ziÅa. Tiem, kas nezina, Ŕī ir laikrindu datubÄze. Tas ir balstÄ«ts uz ClickHouse arhitektÅ«ru, uz dažÄm ClickHouse ievieÅ”anas detaļÄm. PiemÄram, uz tÄdiem kÄ: MergeTree, paralÄli aprÄÄ·ini uz visiem pieejamajiem procesora kodoliem un veiktspÄjas optimizÄcija, strÄdÄjot pie datu blokiem, kas tiek ievietoti procesora keÅ”atmiÅÄ.
VictoriaMetrics nodroÅ”ina labÄku datu saspieÅ”anu nekÄ citas laikrindu datu bÄzes.
Tas mÄrogojas vertikÄli - tas ir, jÅ«s varat pievienot vairÄk procesoru, vairÄk RAM vienÄ datorÄ. VictoriaMetrics veiksmÄ«gi izmantos Å”os pieejamos resursus un uzlabos lineÄro produktivitÄti.
VictoriaMetrics mÄrogojas arÄ« horizontÄli - tas ir, jÅ«s varat pievienot papildu mezglus VictoriaMetrics klasterim, un tÄ veiktspÄja palielinÄsies gandrÄ«z lineÄri.
KÄ jÅ«s uzminÄjÄt, VictoriaMetrics ir Ätra datu bÄze, jo es nevaru rakstÄ«t citus. Un tas ir rakstÄ«ts Go, tÄpÄc es par to runÄju Å”ajÄ tikÅ”anÄs reizÄ.
Kas zina, kas ir laikrindas? ViÅÅ” arÄ« pazÄ«st daudzus cilvÄkus. Laika rinda ir pÄru sÄrija (timestamp, Š·Š½Š°ŃŠµŠ½ŠøŠµ)
, kur Å”ie pÄri ir sakÄrtoti pÄc laika. VÄrtÄ«ba ir peldoÅ”Ä komata skaitlis ā float64.
Katra laika rinda ir unikÄli identificÄta ar atslÄgu. No kÄ sastÄv Ŕī atslÄga? Tas sastÄv no atslÄgu un vÄrtÄ«bu pÄru kopas, kas nav tukÅ”a.
Å eit ir laika rindas piemÄrs. Å Ä«s sÄrijas atslÄga ir pÄru saraksts: __name__="cpu_usage"
ir metrikas nosaukums, instance="my-server"
- Å”is ir dators, kurÄ tiek apkopota Ŕī metrika, datacenter="us-east"
- Å”is ir datu centrs, kurÄ atrodas Å”is dators.
MÄs nonÄcÄm pie laikrindas nosaukuma, kas sastÄv no trim atslÄgu-vÄrtÄ«bu pÄriem. Å Ä« atslÄga atbilst pÄru sarakstam (timestamp, value)
. t1, t3, t3, ..., tN
- tie ir laikspiedoli, 10, 20, 12, ..., 15
ā atbilstoÅ”Äs vÄrtÄ«bas. Tas ir CPU lietojums noteiktÄ laikÄ noteiktai rindai.
Kur var izmantot laika rindas? Vai kÄdam ir kÄda ideja?
- ProgrammÄ DevOps varat izmÄrÄ«t centrÄlo procesoru, RAM, tÄ«klu, rps, kļūdu skaitu utt.
- IoT - mÄs varam izmÄrÄ«t temperatÅ«ru, spiedienu, Ä£eogrÄfiskÄs koordinÄtas un kaut ko citu.
- ArÄ« finanses ā varam sekot lÄ«dzi visu veidu akcijÄm un valÅ«tÄm cenas.
- TurklÄt laikrindas var izmantot ražoÅ”anas procesu uzraudzÄ«bÄ rÅ«pnÄ«cÄs. Mums ir lietotÄji, kuri izmanto VictoriaMetrics, lai uzraudzÄ«tu vÄja turbÄ«nas robotiem.
- Laika rindas ir noderÄ«gas arÄ« informÄcijas vÄkÅ”anai no dažÄdu ierÄ«Äu sensoriem. PiemÄram, dzinÄjam; riepu spiediena mÄrÄ«Å”anai; Ätruma, attÄluma mÄrÄ«Å”anai; benzÄ«na patÄriÅa mÄrÄ«Å”anai utt.
- Laika rindas var izmantot arÄ« gaisa kuÄ£u uzraudzÄ«bai. Katrai lidmaŔīnai ir melnÄ kaste, kurÄ tiek apkopotas laika rindas dažÄdiem lidmaŔīnas veselÄ«bas parametriem. Laika rindas tiek izmantotas arÄ« kosmosa rÅ«pniecÄ«bÄ.
- Veselības aprūpe ir asinsspiediens, pulss utt.
Var bÅ«t vairÄk lietojumprogrammu, par kurÄm es aizmirsu, bet es ceru, ka jÅ«s saprotat, ka laikrindas tiek aktÄ«vi izmantotas mÅ«sdienu pasaulÄ. Un to izmantoÅ”anas apjoms ar katru gadu pieaug.
KÄpÄc jums ir nepiecieÅ”ama laikrindu datu bÄze? KÄpÄc jÅ«s nevarat izmantot parastu relÄciju datu bÄzi, lai saglabÄtu laika rindas?
TÄ kÄ laikrindas parasti satur lielu daudzumu informÄcijas, kuru ir grÅ«ti uzglabÄt un apstrÄdÄt parastajÄs datubÄzÄs. TÄpÄc parÄdÄ«jÄs specializÄtas datu bÄzes laikrindÄm. Å Ä«s bÄzes efektÄ«vi uzglabÄ punktus (timestamp, value)
ar doto atslÄgu. Tie nodroÅ”ina API, lai nolasÄ«tu saglabÄtos datus pÄc atslÄgas, pÄc viena atslÄgas-vÄrtÄ«bas pÄra, pÄc vairÄkiem atslÄgu un vÄrtÄ«bu pÄriem, vai pÄc regulÄrÄ izteiksmes. PiemÄram, ja vÄlaties atrast visu savu pakalpojumu CPU noslodzi kÄdÄ datu centrÄ AmerikÄ, tad jums ir jÄizmanto Å”is pseidovaicÄjums.
Parasti laikrindu datu bÄzes nodroÅ”ina specializÄtas vaicÄjumu valodas, jo laikrindu SQL nav Ä«paÅ”i piemÄrota. Lai gan ir datu bÄzes, kas atbalsta SQL, tas nav Ä«paÅ”i piemÄrots. VaicÄjumu valodas, piemÄram,
Å Ädi izskatÄs mÅ«sdienu laikrindu datu bÄzes arhitektÅ«ra, izmantojot VictoriaMetrics kÄ piemÄru.
Tas sastÄv no divÄm daļÄm. Å Ä« ir apgrieztÄ indeksa glabÄÅ”ana un laikrindu vÄrtÄ«bu glabÄÅ”ana. Å Ä«s krÄtuves ir atdalÄ«tas.
Kad datu bÄzÄ nonÄk jauns ieraksts, mÄs vispirms piekļūstam apgrieztajam indeksam, lai atrastu noteiktas kopas laikrindas identifikatoru. label=value
noteiktai metrikai. MÄs atrodam Å”o identifikatoru un saglabÄjam vÄrtÄ«bu datu krÄtuvÄ.
Kad tiek saÅemts pieprasÄ«jums izgÅ«t datus no TSDB, mÄs vispirms pÄrejam uz apgriezto indeksu. SaÅemsim visu timeseries_ids
ieraksti, kas atbilst Ŕai kopai label=value
. Un tad mÄs iegÅ«stam visus nepiecieÅ”amos datus no datu noliktavas, ko indeksÄ timeseries_ids
.
ApskatÄ«sim piemÄru, kÄ laikrindu datu bÄze apstrÄdÄ ienÄkoÅ”o atlases vaicÄjumu.
- PirmkÄrt, viÅa saÅem visu
timeseries_ids
no apgriezta indeksa, kas satur dotos pÄruslabel=value
, vai atbilst noteiktai regulÄrai izteiksmei. - PÄc tam tas izgÅ«st visus datu punktus no datu krÄtuves noteiktÄ laika intervÄlÄ atrastajiem
timeseries_ids
. - PÄc tam datu bÄze veic dažus aprÄÄ·inus par Å”iem datu punktiem atbilstoÅ”i lietotÄja pieprasÄ«jumam. Un pÄc tam tas atgriež atbildi.
Å ajÄ prezentÄcijÄ pastÄstÄ«Å”u par pirmo daļu. Å Ä« ir meklÄÅ”ana timeseries_ids
pÄc apgrieztÄ indeksa. Par otro daļu un treÅ”o daļu varÄsiet noskatÄ«ties vÄlÄk
PÄriesim pie apgrieztÄ indeksa. Daudzi var domÄt, ka tas ir vienkÄrÅ”i. KurÅ” zina, kas ir apgrieztais indekss un kÄ tas darbojas? Ak, vairs nav tik daudz cilvÄku. MÄÄ£inÄsim saprast, kas tas ir.
PatiesÄ«bÄ tas ir vienkÄrÅ”i. TÄ ir vienkÄrÅ”i vÄrdnÄ«ca, kas kartÄ atslÄgu uz vÄrtÄ«bu. Kas ir atslÄga? Å is pÄris label=value
Kur label
Šø value
- tÄs ir lÄ«nijas. Un vÄrtÄ«bas ir kopums timeseries_ids
, kas ietver doto pÄri label=value
.
Apgrieztais indekss ļauj Ätri atrast visu timeseries_ids
, kas ir devuŔi label=value
.
Tas arÄ« ļauj Ätri atrast timeseries_ids
laikrindas vairÄkiem pÄriem label=value
, vai pÄriem label=regexp
. KÄ tas notiek? Atrodot kopas krustpunktu timeseries_ids
katram pÄrim label=value
.
ApskatÄ«sim dažÄdas apgrieztÄ indeksa realizÄcijas. SÄksim ar visvienkÄrÅ”Äko naivu ievieÅ”anu. ViÅa izskatÄs Å”Ädi.
Funkcija getMetricIDs
iegÅ«st virkÅu sarakstu. Katra rinda satur label=value
. Šī funkcija atgriež sarakstu metricIDs
.
KÄ tas strÄdÄ? Å eit mums ir globÄls mainÄ«gais, ko sauc invertedIndex
. Å Ä« ir parasta vÄrdnÄ«ca (map
), kas kartÄs virkni, lai sadalÄ«tu ints. LÄ«nija satur label=value
.
Funkciju īstenoŔana: iegūt metricIDs
par pirmo label=value
, tad ejam cauri visam pÄrÄjam label=value
, mÄs to sapratÄm metricIDs
viÅiem. Un izsauciet funkciju intersectInts
, kas tiks apspriests tÄlÄk. Un Ŕī funkcija atgriež Å”o sarakstu krustpunktu.
KÄ redzat, apgrieztÄ indeksa ievieÅ”ana nav Ä«paÅ”i sarežģīta. Bet tÄ ir naiva Ä«stenoÅ”ana. KÄdi mÄ«nusi tai ir? Galvenais naivÄs ievieÅ”anas trÅ«kums ir tÄds, ka Å”Äds apgriezts indekss tiek saglabÄts RAM. PÄc lietojumprogrammas restartÄÅ”anas mÄs zaudÄjam Å”o indeksu. Å is rÄdÄ«tÄjs netiek saglabÄts diskÄ. Å Äds apgriezts indekss, visticamÄk, nebÅ«s piemÄrots datu bÄzei.
Otrs trÅ«kums ir saistÄ«ts arÄ« ar atmiÅu. Apgrieztajam indeksam jÄiekļaujas RAM. Ja tas pÄrsniedz RAM lielumu, tad acÄ«mredzot mÄs saÅemsim - no atmiÅas kļūdas. Un programma nedarbosies.
Å o problÄmu var atrisinÄt, izmantojot gatavus risinÄjumus, piemÄram,
ÄŖsÄk sakot, mums ir vajadzÄ«ga datu bÄze, kas ļauj Ätri veikt trÄ«s darbÄ«bas.
- PirmÄ darbÄ«ba ir ierakstÄ«Å”ana
ŠŗŠ»ŃŃ-Š·Š½Š°ŃŠµŠ½ŠøŠµ
uz Å”o datu bÄzi. ViÅa to dara ļoti Ätri, kurŠŗŠ»ŃŃ-Š·Š½Š°ŃŠµŠ½ŠøŠµ
ir patvaļīgas virknes. - OtrÄ darbÄ«ba ir Ätra vÄrtÄ«bas meklÄÅ”ana, izmantojot doto taustiÅu.
- Un treÅ”Ä darbÄ«ba ir Ätra visu vÄrtÄ«bu meklÄÅ”ana pÄc noteiktÄ prefiksa.
LevelDB un RocksDB ā Ŕīs datu bÄzes izstrÄdÄja Google un Facebook. Vispirms parÄdÄ«jÄs LevelDB. Tad puiÅ”i no Facebook paÅÄma LevelDB un sÄka to uzlabot, viÅi izveidoja RocksDB. Tagad gandrÄ«z visas iekÅ”ÄjÄs datu bÄzes darbojas pakalpojumÄ RocksDB Facebook iekÅ”ienÄ, ieskaitot tÄs, kas ir pÄrsÅ«tÄ«tas uz RocksDB un MySQL. ViÅi viÅu nosauca
Apgrieztu indeksu var ieviest, izmantojot LevelDB. KÄ to izdarÄ«t? MÄs saglabÄjam kÄ atslÄgu label=value
. Un vÄrtÄ«ba ir tÄs laikrindas identifikators, kurÄ atrodas pÄris label=value
.
Ja mums ir daudz laika rindu ar doto pÄri label=value
, tad Å”ajÄ datu bÄzÄ bÅ«s daudz rindu ar vienu un to paÅ”u atslÄgu un atŔķirÄ«gu timeseries_ids
. Lai iegūtu visu sarakstu timeseries_ids
, kas sÄkas ar Å”o label=prefix
, mÄs veicam diapazona skenÄÅ”anu, kurai Ŕī datu bÄze ir optimizÄta. Tas ir, mÄs atlasÄm visas rindas, kas sÄkas ar label=prefix
un saÅemt nepiecieÅ”amo timeseries_ids
.
Å eit ir piemÄrs tam, kÄ tas izskatÄ«tos Go. Mums ir apgriezts indekss. Tas ir LevelDB.
Funkcija ir tÄda pati kÄ naivai ievieÅ”anai. TÄ gandrÄ«z rindu pÄc rindas atkÄrto naivo ievieÅ”anu. VienÄ«gais ir tas, ka tÄ vietÄ, lai pievÄrstos map
mÄs piekļūstam apgrieztajam indeksam. MÄs iegÅ«stam visas vÄrtÄ«bas pirmajai label=value
. Tad mÄs ejam cauri visiem atlikuÅ”ajiem pÄriem label=value
un iegÅ«stiet tÄm atbilstoÅ”Äs metrikas ID kopas. Tad atrodam krustojumu.
Å Ä·iet, ka viss ir kÄrtÄ«bÄ, taÄu Å”im risinÄjumam ir trÅ«kumi. VictoriaMetrics sÄkotnÄji ieviesa apgrieztu indeksu, pamatojoties uz LevelDB. Bet galu galÄ man nÄcÄs no tÄ atteikties.
KÄpÄc? TÄ kÄ LevelDB ir lÄnÄka nekÄ naivÄ ievieÅ”ana. NaivÄ ievieÅ”anÄ, Åemot vÄrÄ doto atslÄgu, mÄs nekavÄjoties izgÅ«stam visu ŔķÄli metricIDs
. Å Ä« ir ļoti Ätra darbÄ«ba ā visa ŔķÄle ir gatava lietoÅ”anai.
LevelDB katru reizi, kad tiek izsaukta funkcija GetValues
jums ir jÄiet cauri visÄm rindiÅÄm, kas sÄkas ar label=value
. Un iegÅ«stiet katras rindas vÄrtÄ«bu timeseries_ids
. No Å”Äda timeseries_ids
savÄc ŔķÄli no tiem timeseries_ids
. AcÄ«mredzot tas ir daudz lÄnÄk nekÄ vienkÄrÅ”a piekļuve parastai kartei, izmantojot taustiÅu.
Otrs trÅ«kums ir tas, ka LevelDB ir rakstÄ«ts C valodÄ. C funkciju izsaukÅ”ana no Go nav ļoti Ätra. Tas aizÅem simtiem nanosekunžu. Tas nav Ä«paÅ”i Ätri, jo, salÄ«dzinot ar parastu go rakstÄ«tu funkciju izsaukumu, kas aizÅem 1-5 nanosekundes, veiktspÄjas atŔķirÄ«ba ir desmitiem reižu. UzÅÄmumam VictoriaMetrics tas bija liktenÄ«gs trÅ«kums :)
TÄpÄc es uzrakstÄ«ju savu apgrieztÄ indeksa ievieÅ”anu. Un viÅÅ” viÅai piezvanÄ«ja
Mergeset pamatÄ ir MergeTree datu struktÅ«ra. Å Ä« datu struktÅ«ra ir aizgÅ«ta no ClickHouse. AcÄ«mredzot Mergeset ir jÄoptimizÄ Ätrai meklÄÅ”anai timeseries_ids
saskaÅÄ ar doto atslÄgu. Mergeset ir pilnÄ«bÄ uzrakstÄ«ts Go. Tu vari redzÄt
Mergeset API ir ļoti lÄ«dzÄ«ga LevelDB un RocksDB. Tas ir, tas ļauj Ätri saglabÄt jaunus ierakstus un Ätri atlasÄ«t ierakstus pÄc noteiktÄ prefiksa.
Par mergeset trÅ«kumiem mÄs runÄsim vÄlÄk. Tagad parunÄsim par to, kÄdas problÄmas radÄs ar VictoriaMetrics ražoÅ”anÄ, ievieÅ”ot apgrieztu indeksu.
KÄpÄc tie radÄs?
Pirmais iemesls ir augstais atteikÅ”anÄs lÄ«menis. TulkojumÄ krievu valodÄ tÄ ir bieža laika rindas maiÅa. Tas ir tad, kad beidzas laikrindas un sÄkas jauna sÄrija vai sÄkas daudzas jaunas laikrindas. Un tas notiek bieži.
Otrs iemesls ir lielais laikrindu skaits. SÄkumÄ, kad monitorings kļuva arvien populÄrÄks, laikrindu skaits bija neliels. PiemÄram, katram datoram ir jÄuzrauga CPU, atmiÅas, tÄ«kla un diska noslodze. 4 laikrindas uz datoru. PieÅemsim, ka jums ir 100 datori un 400 laikrindas. Tas ir ļoti maz.
Laika gaitÄ cilvÄki saprata, ka viÅi var izmÄrÄ«t detalizÄtÄku informÄciju. PiemÄram, mÄra slodzi nevis visam procesoram, bet gan atseviŔķi katram procesora kodolam. Ja jums ir 40 procesora kodoli, jums ir 40 reizes vairÄk laikrindu, lai izmÄrÄ«tu procesora slodzi.
Bet tas vÄl nav viss. Katram procesora kodolam var bÅ«t vairÄki stÄvokļi, piemÄram, dÄ«kstÄve, kad tas ir dÄ«kstÄvÄ. Un arÄ« strÄdÄt lietotÄju telpÄ, strÄdÄt kodola telpÄ un citos stÄvokļos. Un katru Å”Ädu stÄvokli var arÄ« izmÄrÄ«t kÄ atseviŔķu laikrindu. Tas papildus palielina rindu skaitu 7-8 reizes.
No vienas metrikas mÄs saÅÄmÄm 40 x 8 = 320 metriku tikai vienam datoram. Reizinot ar 100, mÄs iegÅ«stam 32 000, nevis 400.
Tad nÄca Kubernetes. Un tas kļuva sliktÄks, jo Kubernetes var mitinÄt daudz dažÄdu pakalpojumu. Katrs pakalpojums Kubernetes sastÄv no daudzÄm pÄkstÄ«m. Un tas viss ir jÄuzrauga. TurklÄt mÄs pastÄvÄ«gi izvietojam jaunas jÅ«su pakalpojumu versijas. Katrai jaunai versijai ir jÄizveido jaunas laikrindas. RezultÄtÄ laikrindu skaits pieaug eksponenciÄli, un mÄs saskaramies ar liela skaita laikrindu problÄmu, ko sauc par augstu kardinalitÄti. VictoriaMetrics ar to tiek galÄ veiksmÄ«gi, salÄ«dzinot ar citÄm laikrindu datu bÄzÄm.
ApskatÄ«sim tuvÄk augsto atteikÅ”anÄs lÄ«meni. Kas izraisa augstu ražoÅ”anas pÄrtraukÅ”anas lÄ«meni? Jo dažas etiÄ·eÅ”u un tagu nozÄ«mes pastÄvÄ«gi mainÄs.
PiemÄram, Åemam Kubernetes, kurai ir koncepcija deployment
, t.i., kad tiek izlaista jauna lietojumprogrammas versija. KÄdu iemeslu dÄļ Kubernetes izstrÄdÄtÄji nolÄma etiÄ·etei pievienot izvietoÅ”anas ID.
Pie kÄ tas noveda? TurklÄt ar katru jaunu izvietoÅ”anu visas vecÄs laikrindas tiek pÄrtrauktas, un to vietÄ sÄkas jaunas laikrindas ar jaunu etiÄ·etes vÄrtÄ«bu. deployment_id
. Å Ädu rindu var bÅ«t simtiem tÅ«kstoÅ”u un pat miljonu.
SvarÄ«gi Å”ajÄ visÄ ir tas, ka kopÄjais laikrindu skaits pieaug, bet to laikrindu skaits, kuras paÅ”laik ir aktÄ«vas un saÅem datus, paliek nemainÄ«gs. Å o stÄvokli sauc par augstu atteikÅ”anÄs Ätrumu.
GalvenÄ problÄma, kas saistÄ«ta ar lielu novirzÄ«Å”anas Ätrumu, ir nodroÅ”inÄt nemainÄ«gu meklÄÅ”anas Ätrumu visÄm laikrindÄm noteiktai etiÄ·eÅ”u kopai noteiktÄ laika intervÄlÄ. Parasti tas ir pÄdÄjÄs stundas vai pÄdÄjÄs dienas laika intervÄls.
KÄ atrisinÄt Å”o problÄmu? Å eit ir pirmÄ iespÄja. Tas ir paredzÄts, lai laika gaitÄ sadalÄ«tu apgriezto indeksu neatkarÄ«gÄs daļÄs. Tas ir, paiet kÄds laika intervÄls, mÄs pabeidzam darbu ar paÅ”reizÄjo apgriezto indeksu. Un izveidojiet jaunu apgrieztu indeksu. Paiet cits laika intervÄls, mÄs veidojam vÄl vienu un vÄl vienu.
Un, veicot izlasi no Å”iem apgrieztajiem indeksiem, mÄs atrodam apgriezto indeksu kopu, kas ietilpst dotajÄ intervÄlÄ. Un attiecÄ«gi mÄs no turienes izvÄlamies laikrindas ID.
Tas ietaupa resursus, jo mums nav jÄmeklÄ daļas, kas neietilpst dotajÄ intervÄlÄ. Tas ir, parasti, ja atlasÄm datus par pÄdÄjo stundu, tad iepriekÅ”Äjos laika intervÄlos mÄs izlaižam pieprasÄ«jumus.
Ir vÄl viena iespÄja atrisinÄt Å”o problÄmu. Tas ir paredzÄts, lai katrai dienai saglabÄtu atseviŔķu tajÄ dienÄ notikuÅ”o laikrindu ID sarakstu.
Å Ä« risinÄjuma priekÅ”rocÄ«ba salÄ«dzinÄjumÄ ar iepriekÅ”Äjo risinÄjumu ir tÄda, ka mÄs nedublÄjam laikrindu informÄciju, kas laika gaitÄ nepazÅ«d. ViÅi pastÄvÄ«gi atrodas un nemainÄs.
TrÅ«kums ir tÄds, ka Å”Ädu risinÄjumu ir grÅ«tÄk ieviest un grÅ«tÄk atkļūdot. Un VictoriaMetrics izvÄlÄjÄs Å”o risinÄjumu. TÄ tas notika vÄsturiski. Å is risinÄjums arÄ« darbojas labi, salÄ«dzinot ar iepriekÅ”Äjo. Jo Å”is risinÄjums netika ieviests tÄpÄc, ka ir nepiecieÅ”ams dublÄt datus katrÄ nodalÄ«jumÄ laikrindÄm, kuras nemainÄs, t.i., kas laika gaitÄ nepazÅ«d. VictoriaMetrics galvenokÄrt tika optimizÄts diska vietas patÄriÅam, un iepriekÅ”ÄjÄ ievieÅ”ana pasliktinÄja diska vietas patÄriÅu. Bet Ŕī ievieÅ”ana ir labÄk piemÄrota diska vietas patÄriÅa samazinÄÅ”anai, tÄpÄc tÄ tika izvÄlÄta.
Man bija jÄcÄ«nÄs ar viÅu. CÄ«Åa bija tÄda, ka Å”ajÄ Ä«stenoÅ”anÄ jums joprojÄm ir jÄizvÄlas daudz lielÄks skaits timeseries_ids
datiem nekÄ tad, ja apgrieztais indekss ir sadalÄ«ts laikÄ.
KÄ mÄs atrisinÄjÄm Å”o problÄmu? MÄs to atrisinÄjÄm oriÄ£inÄlÄ veidÄ ā katrÄ apgrieztÄ indeksa ierakstÄ saglabÄjot vairÄkus laikrindu identifikatorus viena identifikatora vietÄ. Tas ir, mums ir atslÄga label=value
, kas notiek katrÄ laika rindÄ. Un tagad mÄs saglabÄjam vairÄkus timeseries_ids
vienÄ ierakstÄ.
Å eit ir piemÄrs. IepriekÅ” mums bija N ieraksti, bet tagad mums ir viens ieraksts, kura prefikss ir tÄds pats kÄ visiem pÄrÄjiem. IepriekÅ”ÄjÄ ieraksta vÄrtÄ«bÄ ir ietverti visi laikrindu ID.
Tas ļÄva palielinÄt Å”Äda apgrieztÄ indeksa skenÄÅ”anas Ätrumu lÄ«dz 10 reizÄm. Un tas ļÄva mums samazinÄt atmiÅas patÄriÅu keÅ”atmiÅai, jo tagad mÄs saglabÄjam virkni label=value
tikai vienu reizi keÅ”atmiÅÄ kopÄ N reizes. Un Ŕī rinda var bÅ«t liela, ja savos tagos un etiÄ·etÄs glabÄjat garas rindas, kuras Kubernetes labprÄt tur iespiež.
VÄl viena iespÄja, lai paÄtrinÄtu meklÄÅ”anu apgrieztÄ rÄdÄ«tÄjÄ, ir sadalÄ«Å”ana. VairÄku apgrieztu indeksu izveidoÅ”ana viena vietÄ un datu sadalÄ«Å”ana starp tiem pÄc atslÄgas. Å is ir komplekts key=value
tvaiks. Tas ir, mÄs iegÅ«stam vairÄkus neatkarÄ«gus apgrieztus indeksus, kurus varam veikt paralÄli vairÄkos procesoros. IepriekÅ”ÄjÄs ievieÅ”anas ļÄva darboties tikai viena procesora režīmÄ, t.i., skenÄt datus tikai vienÄ kodolÄ. Å is risinÄjums ļauj skenÄt datus vairÄkos kodolos vienlaikus, kÄ tas patÄ«k ClickHouse. Tas ir tas, ko mÄs plÄnojam Ä«stenot.
Tagad atgriezÄ«simies pie mÅ«su aitÄm ā pie krustojuma funkcijas timeseries_ids
. ApsvÄrsim, kÄdi varianti var bÅ«t. Å Ä« funkcija ļauj atrast timeseries_ids
noteiktam komplektam label=value
.
PirmÄ iespÄja ir naiva Ä«stenoÅ”ana. Divas ligzdotas cilpas. Å eit mÄs iegÅ«stam funkcijas ievadi intersectInts
divas ŔķÄles - a
Šø b
. IzejÄ tai vajadzÄtu atgriezties pie mums Å”o ŔķÄlumu krustpunktÄ.
Naiva Ä«stenoÅ”ana izskatÄs Å”Ädi. MÄs atkÄrtojam visas vÄrtÄ«bas no ŔķÄluma a
, Å”ajÄ cilpÄ mÄs ejam cauri visÄm ŔķÄluma vÄrtÄ«bÄm b
. Un mÄs tos salÄ«dzinÄm. Ja tie sakrÄ«t, tad esam atraduÅ”i krustojumu. Un saglabÄjiet to result
.
KÄdi ir trÅ«kumi? KvadrÄtiskÄ sarežģītÄ«ba ir tÄs galvenais trÅ«kums. PiemÄram, ja jÅ«su izmÄri ir ŔķÄle a
Šø b
vienu miljonu vienlaikus, tad Ŕī funkcija nekad neatgriezÄ«s jums atbildi. Jo tam bÅ«s jÄveic triljons iterÄciju, kas ir daudz pat mÅ«sdienu datoriem.
OtrÄ ievieÅ”ana ir balstÄ«ta uz karti. MÄs veidojam karti. MÄs ievietojÄm visas vÄrtÄ«bas no ŔķÄles Å”ajÄ kartÄ a
. Tad mÄs ejam cauri ŔķÄlei atseviÅ”Ä·Ä cilpÄ b
. Un mÄs pÄrbaudÄm, vai Ŕī vÄrtÄ«ba ir no ŔķÄles b
kartÄ. Ja tas pastÄv, pievienojiet to rezultÄtam.
KÄdi ir ieguvumi? PriekÅ”rocÄ«ba ir tÄda, ka ir tikai lineÄra sarežģītÄ«ba. Tas nozÄ«mÄ, ka lielÄkÄm ŔķÄlÄ«tÄm funkcija tiks izpildÄ«ta daudz ÄtrÄk. Miljona lieluma ŔķÄlei Ŕī funkcija tiks izpildÄ«ta 2 miljonos iterÄciju, pretstatÄ triljoniem iepriekÅ”ÄjÄs funkcijas iterÄciju.
NegatÄ«vie ir tas, ka Å”ai funkcijai ir nepiecieÅ”ams vairÄk atmiÅas, lai izveidotu Å”o karti.
Otrs trÅ«kums ir lielas jaukÅ”anas izmaksas. Å is trÅ«kums nav Ä«paÅ”i acÄ«mredzams. Un mums tas arÄ« nebija Ä«paÅ”i acÄ«mredzami, tÄpÄc sÄkumÄ VictoriaMetrics krustojuma ievieÅ”ana notika ar kartes palÄ«dzÄ«bu. Bet tad profilÄÅ”ana parÄdÄ«ja, ka galvenÄ procesora laiks tiek pavadÄ«ts, rakstot uz karti un pÄrbaudot, vai Å”ajÄ kartÄ ir kÄda vÄrtÄ«ba.
KÄpÄc Å”ajÄs vietÄs tiek tÄrÄts CPU laiks? TÄ kÄ Go Å”ajÄs rindÄs veic jaukÅ”anas darbÄ«bu. Tas nozÄ«mÄ, ka tas aprÄÄ·ina atslÄgas jaucÄjvÄrtÄ«bu, lai pÄc tam piekļūtu tai noteiktÄ indeksÄ HashMap. JaukÅ”anas aprÄÄ·ina darbÄ«ba tiek pabeigta desmitos nanosekundÄs. VictoriaMetrics tas ir lÄns.
Es nolÄmu ieviest bitkopu, kas optimizÄta Ä«paÅ”i Å”im gadÄ«jumam. Å Ädi tagad izskatÄs divu ŔķÄlumu krustpunkts. Å eit mÄs izveidojam bitkopu. MÄs tam pievienojam elementus no pirmÄs ŔķÄles. PÄc tam mÄs pÄrbaudÄm Å”o elementu klÄtbÅ«tni otrajÄ Å”Ä·ÄlÄ. Un pievienojiet tos rezultÄtam. Tas ir, tas gandrÄ«z neatŔķiras no iepriekÅ”ÄjÄ piemÄra. VienÄ«gais Å”eit ir tas, ka mÄs aizstÄjÄm piekļuvi kartei ar pielÄgotÄm funkcijÄm add
Šø has
.
No pirmÄ acu uzmetiena Ŕķiet, ka Å”im vajadzÄtu darboties lÄnÄk, ja iepriekÅ” tur tika izmantota standarta karte, un tad tiek izsauktas vÄl kÄdas funkcijas, bet profilÄÅ”ana parÄda, ka Ŕī lieta darbojas 10 reizes ÄtrÄk nekÄ standarta karte VictoriaMetrics gadÄ«jumÄ.
TurklÄt tas izmanto daudz mazÄk atmiÅas, salÄ«dzinot ar kartes ievieÅ”anu. Jo mÄs Å”eit glabÄjam bitus, nevis astoÅu baitu vÄrtÄ«bas.
Å Ä«s ievieÅ”anas trÅ«kums ir tÄds, ka tas nav tik acÄ«mredzams, nav triviÄls.
VÄl viens trÅ«kums, ko daudzi var nepamanÄ«t, ir tas, ka Ŕī ievieÅ”ana dažos gadÄ«jumos var nedarboties labi. Tas ir, tas ir optimizÄts konkrÄtam gadÄ«jumam, Å”im VictoriaMetrics laika rindu ID krustoÅ”anÄs gadÄ«jumam. Tas nenozÄ«mÄ, ka tas ir piemÄrots visiem gadÄ«jumiem. Ja tas tiek izmantots nepareizi, mÄs neiegÅ«sim veiktspÄjas pieaugumu, bet gan kļūdu, kurÄ pietrÅ«ks atmiÅa, un veiktspÄjas palÄninÄÅ”anos.
ApsvÄrsim Ŕīs struktÅ«ras ievieÅ”anu. Ja vÄlaties meklÄt, tas atrodas VictoriaMetrics avotos, mapÄ timeseries_id
ir 64 bitu vÄrtÄ«ba, kur pirmie 32 biti pamatÄ ir nemainÄ«gi un mainÄs tikai pÄdÄjie 32 biti.
Å Ä« datu struktÅ«ra netiek saglabÄta diskÄ, tÄ darbojas tikai atmiÅÄ.
Å eit ir tÄ API. Tas nav Ä«paÅ”i sarežģīti. API ir Ä«paÅ”i pielÄgota konkrÄtam VictoriaMetrics izmantoÅ”anas piemÄram. Tas ir, Å”eit nav nevajadzÄ«gu funkciju. Å eit ir funkcijas, kuras Ä«paÅ”i izmanto VictoriaMetrics.
Ir funkcijas add
, kas pievieno jaunas vÄrtÄ«bas. Ir funkcija has
, kas pÄrbauda jaunas vÄrtÄ«bas. Un ir funkcija del
, kas noÅem vÄrtÄ«bas. Ir palÄ«gfunkcija len
, kas atgriež komplekta izmÄru. Funkcija clone
klonÄ daudz. Un funkcija appendto
pÄrvÄrÅ” Å”o kopu par ŔķÄli timeseries_ids
.
Å Ädi izskatÄs Ŕīs datu struktÅ«ras ievieÅ”ana. komplektÄ ir divi elementi:
-
ItemsCount
ir palÄ«glauks, lai Ätri atgrieztu kopas elementu skaitu. VarÄtu iztikt arÄ« bez Ŕī palÄ«glauka, taÄu tas Å”eit bija jÄpievieno, jo VictoriaMetrics savos algoritmos bieži vaicÄ bitkopas garumu. -
Otrais lauks ir
buckets
. Šī ir struktūras daļabucket32
. Katra struktÅ«ra uzglabÄhi
lauks. Tie ir augÅ”Äjie 32 biti. Un divas ŔķÄles -b16his
Šøbuckets
nobucket16
struktūras.
Å eit tiek glabÄti 16 bitu struktÅ«ras otrÄs daļas 64 augÅ”Äjie biti. Un Å”eit bitkopas tiek saglabÄtas katra baita apakÅ”Äjiem 16 bitiem.
Bucket64
sastÄv no masÄ«va uint64
. Garumu aprÄÄ·ina, izmantojot Ŕīs konstantes. VienÄ bucket16
maksimÄli var uzglabÄt 2^16=65536
mazliet. Ja jÅ«s to dalÄt ar 8, tas ir 8 kilobaiti. Ja jÅ«s vÄlreiz dalÄt ar 8, tas ir 1000 uint64
nozÄ«mÄ. Tas ir Bucket16
ā Ŕī ir mÅ«su 8 kilobaitu struktÅ«ra.
ApskatÄ«sim, kÄ tiek realizÄta viena no Ŕīs struktÅ«ras metodÄm jaunas vÄrtÄ«bas pievienoÅ”anai.
Viss sÄkas ar uint64
nozÄ«mes. MÄs aprÄÄ·inÄm augÅ”Äjos 32 bitus, mÄs aprÄÄ·inÄm apakÅ”Äjos 32 bitus. Ejam cauri visam buckets
. MÄs salÄ«dzinÄm labÄkos 32 bitus katrÄ segmentÄ ar pievienoto vÄrtÄ«bu. Un, ja tie sakrÄ«t, mÄs izsaucam funkciju add
struktÅ«rÄ b32 buckets
. Un pievienojiet tur zemÄkos 32 bitus. Un ja tas atgrieztos true
, tad tas nozÄ«mÄ, ka mÄs tur pievienojÄm Å”Ädu vÄrtÄ«bu un mums tÄdas vÄrtÄ«bas nebija. Ja tas atgriežas false
, tad tÄda nozÄ«me jau pastÄvÄja. Tad mÄs palielinÄm elementu skaitu struktÅ«rÄ.
Ja neesam atraduŔi vajadzīgo bucket
ar nepiecieÅ”amo hi-value, tad mÄs izsaucam funkciju addAlloc
, kas radīs jaunu bucket
, pievienojot to kausa struktūrai.
TÄ ir funkcijas Ä«stenoÅ”ana b32.add
. Tas ir lÄ«dzÄ«gs iepriekÅ”Äjai ievieÅ”anai. MÄs aprÄÄ·inÄm visnozÄ«mÄ«gÄkos 16 bitus, vismazÄk nozÄ«mÄ«gos 16 bitus.
Tad mÄs ejam cauri visiem augÅ”Äjiem 16 bitiem. MÄs atrodam sÄrkociÅus. Un, ja ir atbilstÄ«ba, mÄs izsaucam pievienoÅ”anas metodi, ko mÄs apsvÄrsim nÄkamajÄ lapÄ bucket16
.
Un Å”eit ir zemÄkais lÄ«menis, kuru vajadzÄtu maksimÄli optimizÄt. MÄs aprÄÄ·inÄm par uint64
id vÄrtÄ«ba slice bitÄ un arÄ« bitmask
. Å Ä« ir maska āānoteiktai 64 bitu vÄrtÄ«bai, ko var izmantot, lai pÄrbaudÄ«tu Ŕī bita klÄtbÅ«tni vai iestatÄ«tu to. MÄs pÄrbaudÄm, vai Å”is bits ir iestatÄ«ts, iestatÄm to un atgriežam klÄtbÅ«tni. Å Ä« ir mÅ«su ievieÅ”ana, kas ļÄva mums paÄtrinÄt laika rindu krustojoÅ”o ID darbÄ«bu 10 reizes, salÄ«dzinot ar parastajÄm kartÄm.
Papildus Å”ai optimizÄcijai VictoriaMetrics piedÄvÄ daudzas citas optimizÄcijas. LielÄkÄ daļa Å”o optimizÄciju tika pievienotas iemesla dÄļ, bet pÄc koda profilÄÅ”anas ražoÅ”anÄ.
Å is ir galvenais optimizÄcijas noteikums ā nepievienojiet optimizÄciju, pieÅemot, ka Å”eit bÅ«s saÅ”aurinÄjums, jo var izrÄdÄ«ties, ka tÄ nebÅ«s. OptimizÄcija parasti pasliktina koda kvalitÄti. TÄpÄc optimizÄt ir vÄrts tikai pÄc profilÄÅ”anas un vÄlams ražoÅ”anÄ, lai tie bÅ«tu reÄli dati. Ja kÄdu interesÄ, varat apskatÄ«t VictoriaMetrics avota kodu un izpÄtÄ«t citas tur esoÅ”Äs optimizÄcijas.
Man ir jautÄjums par bitset. Ä»oti lÄ«dzÄ«gs C++ vektora bool ievieÅ”anai, optimizÄta bitkopa. Vai ievieÅ”anu pÄrÅÄmÄt no turienes?
NÄ, ne no turienes. IevieÅ”ot Å”o bitkopu, es vadÄ«jos pÄc zinÄÅ”anÄm par Å”o ids laikrindu struktÅ«ru, kuras tiek izmantotas VictoriaMetrics. Un to struktÅ«ra ir tÄda, ka augÅ”Äjie 32 biti bÅ«tÄ«bÄ ir nemainÄ«gi. ApakÅ”Äjie 32 biti var tikt mainÄ«ti. Jo zemÄks uzgalis, jo biežÄk tas var mainÄ«ties. TÄpÄc Ŕī ievieÅ”ana ir Ä«paÅ”i optimizÄta Å”ai datu struktÅ«rai. C++ ievieÅ”ana, cik man zinÄms, ir optimizÄta vispÄrÄjam gadÄ«jumam. Ja optimizÄjat vispÄrÄjam gadÄ«jumam, tas nozÄ«mÄ, ka konkrÄtajam gadÄ«jumam tas nebÅ«s optimÄlÄkais.
Iesaku noskatÄ«ties arÄ« Alekseja Milovida reportÄžu. ApmÄram pirms mÄneÅ”a viÅÅ” runÄja par ClickHouse optimizÄciju konkrÄtÄm specializÄcijÄm. ViÅÅ” tikai saka, ka vispÄrÄ«gÄ gadÄ«jumÄ C++ vai kÄda cita implementÄcija ir pielÄgota tÄ, lai tÄ vidÄji labi darbotos slimnÄ«cÄ. Tas var darboties sliktÄk nekÄ zinÄÅ”anÄm specifiska ievieÅ”ana, piemÄram, mÅ«su, kur mÄs zinÄm, ka galvenie 32 biti lielÄkoties ir nemainÄ«gi.
Man ir otrs jautÄjums. KÄda ir bÅ«tiska atŔķirÄ«ba no InfluxDB?
Ir daudz bÅ«tisku atŔķirÄ«bu. RunÄjot par veiktspÄju un atmiÅas patÄriÅu, InfluxDB testos parÄda 10 reizes lielÄku atmiÅas patÄriÅu augstas kardinalitÄtes laikrindÄm, ja jums to ir daudz, piemÄram, miljoni. PiemÄram, VictoriaMetrics patÄrÄ 1 GB uz miljonu aktÄ«vo rindu, bet InfluxDB patÄrÄ 10 GB. Un tÄ ir liela atŔķirÄ«ba.
Otra bÅ«tiskÄ atŔķirÄ«ba ir tÄ, ka InfluxDB ir dÄ«vainas vaicÄjumu valodas - Flux un InfluxQL. Tie nav Ä«paÅ”i Ärti darbam ar laika rindÄm, salÄ«dzinot ar
Un vÄl viena atŔķirÄ«ba ir tÄ, ka InfluxDB ir nedaudz dÄ«vains datu modelis, kur katrÄ rindÄ var saglabÄt vairÄkus laukus ar atŔķirÄ«gu tagu komplektu. Å Ä«s rindas tÄlÄk ir sadalÄ«tas dažÄdÄs tabulÄs. Å Ä«s papildu komplikÄcijas sarežģī turpmÄko darbu ar Å”o datubÄzi. GrÅ«ti atbalstÄ«t un saprast.
VictoriaMetrics viss ir daudz vienkÄrÅ”Äk. Tur katra laikrinda ir atslÄgas vÄrtÄ«ba. VÄrtÄ«ba ir punktu kopa - (timestamp, value)
, un galvenais ir komplekts label=value
. Nav atdalÄ«Å”anas starp laukiem un mÄrÄ«jumiem. Tas ļauj atlasÄ«t jebkurus datus un pÄc tam apvienot, pievienot, atÅemt, reizinÄt, dalÄ«t, atŔķirÄ«bÄ no InfluxDB, kur, cik man zinÄms, aprÄÄ·ini starp dažÄdÄm rindÄm joprojÄm nav ieviesti. Pat ja tie ir ieviesti, tas ir grÅ«ti, jums ir jÄraksta daudz koda.
Man ir precizÄjoÅ”s jautÄjums. Vai es pareizi sapratu, ka ir kaut kÄda problÄma, par kuru jÅ«s runÄjÄt, ka Å”is apgrieztais indekss neiederas atmiÅÄ, tÄpÄc tur ir nodalÄ«jums?
PirmkÄrt, es parÄdÄ«ju naivu apgrieztÄ indeksa ievieÅ”anu standarta Go kartÄ. Å Ä« ievieÅ”ana nav piemÄrota datu bÄzÄm, jo āāÅ”is apgrieztais indekss netiek saglabÄts diskÄ, un datu bÄze ir jÄsaglabÄ diskÄ, lai Å”ie dati bÅ«tu pieejami pÄc restartÄÅ”anas. Å ajÄ ievieÅ”anÄ, restartÄjot lietojumprogrammu, jÅ«su apgrieztais indekss pazudÄ«s. Un jÅ«s zaudÄsit piekļuvi visiem datiem, jo āānevarÄsit tos atrast.
Sveiki! Paldies par ziÅojumu! Mani sauc PÄvels. Es esmu no Wildberries. Man jums ir daži jautÄjumi. Pirmais jautÄjums. Vai jÅ«s domÄjat, ka, ja jÅ«s, veidojot savas lietojumprogrammas arhitektÅ«ru, bÅ«tu izvÄlÄjies citu principu un laika gaitÄ sadalÄ«jis datus, tad, iespÄjams, meklÄjot datus bÅ«tu varÄjis krustot, pamatojoties tikai uz to, ka vienÄ nodalÄ«jumÄ ir dati par vienu laika periodÄ, tas ir, vienÄ laika intervÄlÄ, un jums nebÅ«tu jÄuztraucas par to, ka jÅ«su gabali ir izkaisÄ«ti atŔķirÄ«gi? JautÄjums numur 2 - tÄ kÄ jÅ«s ievieÅ”at lÄ«dzÄ«gu algoritmu ar bitu kopu un visu pÄrÄjo, tad varbÅ«t mÄÄ£inÄjÄt izmantot procesora instrukcijas? VarbÅ«t esat mÄÄ£inÄjuÅ”i Å”Ädas optimizÄcijas?
Uz otro atbildÄÅ”u uzreiz. MÄs vÄl neesam tikuÅ”i lÄ«dz tam. Bet, ja vajadzÄs, mÄs tur tiksim. Un pirmais, kÄds bija jautÄjums?
JÅ«s apspriedÄt divus scenÄrijus. Un viÅi teica, ka izvÄlÄjÄs otro ar sarežģītÄku ievieÅ”anu. Un viÅi nevÄlÄjÄs pirmo, kur dati ir sadalÄ«ti pÄc laika.
JÄ. PirmajÄ gadÄ«jumÄ kopÄjais indeksa apjoms bÅ«tu lielÄks, jo katrÄ nodalÄ«jumÄ mums bÅ«tu jÄuzglabÄ dublÄti dati par tÄm laikrindÄm, kas turpinÄs cauri visÄm Ŕīm sadaļÄm. Un, ja jÅ«su laikrindu maiÅas Ätrums ir mazs, t.i., pastÄvÄ«gi tiek izmantotas vienas un tÄs paÅ”as rindas, tad pirmajÄ gadÄ«jumÄ mÄs zaudÄtu daudz vairÄk diska aizÅemtÄs vietas, salÄ«dzinot ar otro gadÄ«jumu.
Un tÄ - jÄ, laika sadalÄ«Å”ana ir labs risinÄjums. Prometejs to izmanto. Bet Prometejam ir vÄl viens trÅ«kums. Apvienojot Ŕīs datu daļas, tai ir jÄsaglabÄ visu etiÄ·eÅ”u un laikrindu metainformÄcija. TÄpÄc, ja tajÄ apvienotie datu gabali ir lieli, atmiÅas patÄriÅÅ” apvienoÅ”anas laikÄ ievÄrojami palielinÄs, atŔķirÄ«bÄ no VictoriaMetrics. Apvienojot, VictoriaMetrics vispÄr nepatÄrÄ atmiÅu; tiek patÄrÄti tikai daži kilobaiti neatkarÄ«gi no sapludinÄto datu lieluma.
Izmantotais algoritms izmanto atmiÅu. Tas iezÄ«mÄ laikrindas tagus, kas satur vÄrtÄ«bas. Un Å”ÄdÄ veidÄ jÅ«s pÄrbaudÄt klÄtbÅ«tni pÄrÄ« vienÄ datu masÄ«vÄ un citÄ. Un jÅ«s saprotat, vai krustojums ir noticis vai nÄ. Parasti datu bÄzÄs tiek ieviesti kursori un iteratori, kas saglabÄ to paÅ”reizÄjo saturu un pÄrlaiž sakÄrtotos datus Å”o darbÄ«bu vienkÄrÅ”Äs sarežģītÄ«bas dÄļ.
KÄpÄc mÄs neizmantojam kursorus datu ŔķÄrsoÅ”anai?
JÄ.
MÄs glabÄjam sakÄrtotÄs rindas LevelDB vai mergeset. MÄs varam pÄrvietot kursoru un atrast krustojumu. KÄpÄc mÄs to neizmantojam? Jo tas ir lÄns. Jo kursori nozÄ«mÄ, ka katrai rindai ir jÄizsauc funkcija. Funkcijas izsaukums ir 5 nanosekundes. Un, ja jums ir 100 000 000 lÄ«niju, tad izrÄdÄs, ka mÄs pavadÄm pussekundi tikai funkcijas izsaukÅ”anai.
Ir tÄda lieta, jÄ. Un mans pÄdÄjais jautÄjums. JautÄjums var izklausÄ«ties nedaudz dÄ«vaini. KÄpÄc datu saÅemÅ”anas brÄ«dÄ« nav iespÄjams nolasÄ«t visus nepiecieÅ”amos apkopojumus un saglabÄt tos vajadzÄ«gajÄ formÄ? KÄpÄc ietaupÄ«t milzÄ«gus apjomus dažÄs sistÄmÄs, piemÄram, VictoriaMetrics, ClickHouse utt., un pÄc tam tÄrÄt tÄm daudz laika?
Es sniegÅ”u piemÄru, lai tas bÅ«tu skaidrÄks. Teiksim, kÄ darbojas mazs rotaļlietas spidometrs? Tas reÄ£istrÄ jÅ«su nobraukto attÄlumu, visu laiku pievienojot to vienai vÄrtÄ«bai, bet otrajÄ - laikam. Un sadala. Un iegÅ«st vidÄjo Ätrumu. JÅ«s varat darÄ«t apmÄram to paÅ”u. Saskaitiet visus nepiecieÅ”amos faktus.
Labi, es saprotu jautÄjumu. JÅ«su piemÄram ir sava vieta. Ja zinÄt, kÄdi agregÄti jums nepiecieÅ”ami, Ŕī ir labÄkÄ ievieÅ”ana. Bet problÄma ir tÄ, ka cilvÄki saglabÄ Å”os rÄdÄ«tÄjus, dažus datus pakalpojumÄ ClickHouse, un viÅi vÄl nezina, kÄ tos apkopos un filtrÄs nÄkotnÄ, tÄpÄc viÅiem ir jÄsaglabÄ visi neapstrÄdÄtie dati. Bet, ja zinÄt, ka kaut kas ir jÄaprÄÄ·ina vidÄji, tad kÄpÄc gan to nerÄÄ·inÄt, nevis glabÄt tur virkni neapstrÄdÄtu vÄrtÄ«bu? Bet tas ir tikai tad, ja jÅ«s precÄ«zi zinÄt, kas jums nepiecieÅ”ams.
Starp citu, datu bÄzes laikrindu glabÄÅ”anai atbalsta agregÄtu skaitÄ«Å”anu. PiemÄram, Prometheus atbalsta
PiemÄram, manÄ iepriekÅ”ÄjÄ darbÄ man vajadzÄja saskaitÄ«t notikumu skaitu bÄ«dÄmajÄ logÄ pÄdÄjÄs stundas laikÄ. ProblÄma ir tÄda, ka man bija jÄizveido pielÄgota ievieÅ”ana Go, t.i., pakalpojums Ŕīs lietas skaitÄ«Å”anai. Å is pakalpojums galu galÄ nebija triviÄls, jo to ir grÅ«ti aprÄÄ·inÄt. IevieÅ”ana var bÅ«t vienkÄrÅ”a, ja jums ir jÄsaskaita daži apkopojumi noteiktos laika intervÄlos. Ja vÄlaties skaitÄ«t notikumus bÄ«dÄmÄ logÄ, tad tas nav tik vienkÄrÅ”i, kÄ Å”Ä·iet. Es domÄju, ka tas vÄl nav ieviests ClickHouse vai laikrindu datubÄzÄs, jo to ir grÅ«ti ieviest.
Un vÄl viens jautÄjums. MÄs tikai runÄjÄm par vidÄjo rÄdÄ«tÄju, un es atcerÄjos, ka kÄdreiz bija tÄda lieta kÄ Graphite ar oglekļa aizmuguri. Un viÅÅ” prata retinÄt vecos datus, tas ir, atstÄt vienu punktu minÅ«tÄ, vienu punktu stundÄ utt. PrincipÄ tas ir diezgan Ärti, ja mums ir nepiecieÅ”ami neapstrÄdÄti dati, nosacÄ«ti runÄjot, par mÄnesi, un viss pÄrÄjais var tikt atŔķaidÄ«tam. Bet Prometheus un VictoriaMetrics neatbalsta Å”o funkcionalitÄti. Vai ir plÄnots to atbalstÄ«t? Ja nÄ, kÄpÄc ne?
Paldies par jautÄjumu. MÅ«su lietotÄji periodiski uzdod Å”o jautÄjumu. ViÅi jautÄ, kad mÄs pievienosim atbalstu samazinÄjumam. Å eit ir vairÄkas problÄmas. PirmkÄrt, katrs lietotÄjs to saprot downsampling
kaut kas cits: kÄds vÄlas iegÅ«t jebkuru patvaļīgu punktu noteiktÄ intervÄlÄ, kÄds vÄlas maksimÄlÄs, minimÄlÄs, vidÄjÄs vÄrtÄ«bas. Ja daudzas sistÄmas ieraksta datus jÅ«su datu bÄzÄ, jÅ«s tos nevarat apvienot. Var gadÄ«ties, ka katrai sistÄmai nepiecieÅ”ama atŔķirÄ«ga retinÄÅ”ana. Un to ir grÅ«ti Ä«stenot.
Un otrÄ lieta ir tÄda, ka VictoriaMetrics, tÄpat kÄ ClickHouse, ir optimizÄts darbam ar lieliem neapstrÄdÄtu datu apjomiem, tÄpÄc tas var izvilkt miljardu rindu mazÄk nekÄ sekundÄ, ja jÅ«su sistÄmÄ ir daudz kodolu. Laika rindu punktu skenÄÅ”ana programmÄ VictoriaMetrics ā 50 000 000 punkti sekundÄ uz vienu kodolu. Un Ŕī veiktspÄja tiek pielÄgota esoÅ”ajiem kodoliem. Tas ir, ja jums ir, piemÄram, 20 kodoli, jÅ«s skenÄsit miljardu punktu sekundÄ. Un Ŕī VictoriaMetrics un ClickHouse Ä«paŔība samazina vajadzÄ«bu pÄc izlases samazinÄÅ”anas.
VÄl viena iezÄ«me ir tÄda, ka VictoriaMetrics efektÄ«vi saspiež Å”os datus. SaspieÅ”ana vidÄji ražoÅ”anÄ ir no 0,4 lÄ«dz 0,8 baitiem uz punktu. Katrs punkts ir laikspiedols + vÄrtÄ«ba. Un tas vidÄji tiek saspiests mazÄk nekÄ vienÄ baitÄ.
Sergejs. Man ir jautÄjums. KÄds ir minimÄlais ierakstÄ«Å”anas laika kvants?
Viena milisekunde. Nesen mums bija saruna ar citiem laikrindu datu bÄzes izstrÄdÄtÄjiem. ViÅu minimÄlais laika posms ir viena sekunde. Un, piemÄram, grafÄ«tÄ tÄ ir arÄ« viena sekunde. OpenTSDB tÄ ir arÄ« viena sekunde. InfluxDB ir nanosekunžu precizitÄte. VictoriaMetrics tÄ ir viena milisekunde, jo PrometejÄ tÄ ir viena milisekunde. Un VictoriaMetrics sÄkotnÄji tika izstrÄdÄts kÄ Prometheus attÄlÄ krÄtuve. Bet tagad tas var saglabÄt datus no citÄm sistÄmÄm.
Persona, ar kuru es runÄju, saka, ka viÅiem ir precizitÄte no sekundes lÄ«dz sekundei ā viÅiem ar to pietiek, jo tas ir atkarÄ«gs no datu veida, kas tiek glabÄti laikrindu datu bÄzÄ. Ja tie ir DevOps dati vai dati no infrastruktÅ«ras, kur tos savÄcat ik pÄc 30 sekundÄm minÅ«tÄ, tad pietiek ar sekundes precizitÄti, neko mazÄk nevajag. Un, ja jÅ«s apkopojat Å”os datus no augstas frekvences tirdzniecÄ«bas sistÄmÄm, tad jums ir nepiecieÅ”ama nanosekundes precizitÄte.
Milisekundes precizitÄte programmÄ VictoriaMetrics ir piemÄrota arÄ« DevOps gadÄ«jumam, un tÄ var bÅ«t piemÄrota lielÄkajai daļai gadÄ«jumu, ko minÄju ziÅojuma sÄkumÄ. VienÄ«gais, kam tas var nebÅ«t piemÄrots, ir augstas frekvences tirdzniecÄ«bas sistÄmas.
Paldies! Un vÄl jautÄjums. Kas ir PromQL saderÄ«ba?
Pilna atpakaļejoÅ”a saderÄ«ba. VictoriaMetrics pilnÄ«bÄ atbalsta PromQL. TurklÄt tas pievieno papildu uzlaboto funkcionalitÄti PromQL, ko sauc
Telegrammas kanÄls
AptaujÄ var piedalÄ«ties tikai reÄ£istrÄti lietotÄji.
Kas jums traucÄ pÄriet uz VictoriaMetrics kÄ Prometheus ilgtermiÅa krÄtuvi? (Raksti komentÄros, pievienoÅ”u aptaujai))
-
71,4%Es neizmantoju Prometheus5
-
28,6%NezinÄju par VictoriaMetrics2
Nobalsoja 7 lietotÄji. 12 lietotÄji atturÄjÄs.
Avots: www.habr.com