Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Mi sugestas vin legi la transskribon de la malfrua 2019-raporto de Alexander Valyalkin "Iru optimumigojn en VictoriaMetrics"

VictoriaMetrics - rapida kaj skalebla DBMS por stoki kaj prilabori datumojn en formo de temposerio (la rekordo formas tempon kaj aron de valoroj respondaj al ĉi tiu tempo, ekzemple, akiritaj per perioda balotado de la statuso de sensiloj aŭ kolekto de metriko).

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Jen ligo al la video de ĉi tiu raporto - https://youtu.be/MZ5P21j_HLE

Diapozitivoj

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Rakontu al ni pri vi mem. Mi estas Aleksandro Valyalkin. Jen mia GitHub-konto. Mi estas pasiigita pri Go kaj agado-optimumigo. Mi verkis multajn utilajn kaj ne tiom utilajn bibliotekojn. Ili komencas per ambaŭ fast, aŭ kun quick Prefikso.

Mi nuntempe laboras pri VictoriaMetrics. Kio estas kaj kion mi faras tie? Mi parolos pri tio en ĉi tiu prezento.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

La skizo de la raporto estas jena:

  • Unue, mi diros al vi, kio estas VictoriaMetrics.
  • Tiam mi diros al vi, kiaj temposerio estas.
  • Tiam mi rakontos al vi kiel funkcias tempseria datumbazo.
  • Poste, mi rakontos al vi pri la datumbaza arkitekturo: el kio ĝi konsistas.
  • Kaj tiam ni transiru al la optimumigoj kiujn VictoriaMetrics havas. Ĉi tio estas optimumigo por la inversa indekso kaj optimumigo por la efektivigo de bitsetoj en Go.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ĉu iu el la spektantaro scias, kio estas VictoriaMetrics? Ve, multaj homoj jam scias. Estas bona novaĵo. Por tiuj, kiuj ne scias, ĉi tio estas temp-seriodatumbazo. Ĝi estas bazita sur la ClickHouse-arkitekturo, sur kelkaj detaloj de la ClickHouse-efektivigo. Ekzemple, pri kiel ekzemple: MergeTree, paralela kalkulo sur ĉiuj disponeblaj procesorkernoj kaj rendimentooptimumigo laborante pri datumblokoj kiuj estas metitaj en la procesorkaŝmemoro.

VictoriaMetrics disponigas pli bonan datumkunpremadon ol aliaj tempserialaj datumbazoj.

Ĝi skalas vertikale - tio estas, vi povas aldoni pli da procesoroj, pli da RAM sur unu komputilo. VictoriaMetrics sukcese utiligos ĉi tiujn disponeblajn rimedojn kaj plibonigos linearan produktivecon.

VictoriaMetrics ankaŭ skalas horizontale - tio estas, vi povas aldoni pliajn nodojn al la VictoriaMetrics-grupo, kaj ĝia rendimento pliiĝos preskaŭ linie.

Kiel vi divenis, VictoriaMetrics estas rapida datumbazo, ĉar mi ne povas skribi aliajn. Kaj ĝi estas skribita en Go, do mi parolas pri ĝi ĉe ĉi tiu renkontiĝo.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kiu scias, kio estas temposerio? Li ankaŭ konas multajn homojn. Temposerio estas serio de paroj (timestamp, значение), kie ĉi tiuj paroj estas ordigitaj laŭ tempo. La valoro estas glitkoma nombro - float64.

Ĉiu temposerio estas unike identigita per ŝlosilo. El kio konsistas ĉi tiu ŝlosilo? Ĝi konsistas el nemalplena aro de ŝlosil-valoraj paroj.

Jen ekzemplo de temposerio. La ŝlosilo de ĉi tiu serio estas listo de paroj: __name__="cpu_usage" estas la nomo de la metriko, instance="my-server" - ĉi tiu estas la komputilo sur kiu ĉi tiu metriko estas kolektita, datacenter="us-east" - ĉi tiu estas la datumcentro kie ĉi tiu komputilo troviĝas.

Ni finis kun temposerionomo konsistanta el tri ŝlosil-valoraj paroj. Ĉi tiu ŝlosilo respondas al listo de paroj (timestamp, value). t1, t3, t3, ..., tN - ĉi tiuj estas tempomarkoj, 10, 20, 12, ..., 15 — la respondaj valoroj. Ĉi tio estas la CPU-uzo en difinita tempo por antaŭfiksita serio.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kie temposerio povas esti uzata? Ĉu iu havas ideon?

  • En DevOps, vi povas mezuri CPU, RAM, reton, rps, nombron da eraroj ktp.
  • IoT - ni povas mezuri temperaturon, premon, geokoordinatojn kaj ion alian.
  • Ankaŭ financo - ni povas kontroli prezojn por ĉiaj akcioj kaj valutoj.
  • Krome, temposerio povas esti uzata en monitorado de produktadaj procezoj en fabrikoj. Ni havas uzantojn, kiuj uzas VictoriaMetrics por monitori ventoturbinojn, por robotoj.
  • Temposerioj ankaŭ estas utilaj por kolekti informojn de sensiloj de diversaj aparatoj. Ekzemple, por motoro; por mezuri pneŭpremon; por mezuri rapidecon, distancon; por mezuri benzinkonsumon, ktp.
  • Temposerio ankaŭ povas esti uzata por monitori aviadilojn. Ĉiu aviadilo havas nigran skatolon kiu kolektas temposerion por diversaj parametroj de la sano de la aviadilo. Temposerioj ankaŭ estas uzitaj en la aerspaca industrio.
  • Sanservo estas sangopremo, pulso, ktp.

Eble estas pli da aplikaĵoj pri kiuj mi forgesis, sed mi esperas, ke vi komprenas, ke temposerio estas aktive uzataj en la moderna mondo. Kaj la volumo de ilia uzo kreskas ĉiujare.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kial vi bezonas tempserian datumbazon? Kial vi ne povas uzi regulan rilatan datumbazon por stoki temposerion?

Ĉar temposerio kutime enhavas grandan kvanton da informoj, kiujn malfacilas stoki kaj prilabori en konvenciaj datumbazoj. Tial aperis fakaj datumbazoj por temposerio. Ĉi tiuj bazoj efike stokas punktojn (timestamp, value) per la donita ŝlosilo. Ili provizas API por legi konservitajn datumojn per ŝlosilo, per ununura ŝlosil-valora paro, aŭ per multoblaj ŝlosil-valoraj paroj, aŭ per regexp. Ekzemple, vi volas trovi la CPU-ŝarĝon de ĉiuj viaj servoj en datumcentro en Ameriko, tiam vi devas uzi ĉi tiun pseŭdo-demandon.

Kutime tempseriaj datumbazoj disponigas specialajn demandlingvojn ĉar temposerio SQL ne tre taŭgas. Kvankam ekzistas datumbazoj kiuj subtenas SQL, ĝi ne estas tre taŭga. Pridemandu lingvojn kiel ekzemple PromQL, InfluxQL, fluo, Q. Mi esperas, ke iu aŭdis almenaŭ unu el ĉi tiuj lingvoj. Multaj homoj verŝajne aŭdis pri PromQL. Ĉi tiu estas la demandlingvo de Prometheus.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Jen kiel aspektas moderna datumbaza arkitekturo de temposerio uzante VictoriaMetrics kiel ekzemplon.

Ĝi konsistas el du partoj. Ĉi tio estas stokado por la inversa indekso kaj stokado por temposeriovaloroj. Ĉi tiuj deponejoj estas apartigitaj.

Kiam nova rekordo alvenas en la datumbazon, ni unue aliras la inversan indekson por trovi la tempserian identigilon por donita aro. label=value por donita metriko. Ni trovas ĉi tiun identigilon kaj konservas la valoron en la datumvendejo.

Kiam peto venas por preni datumojn de TSDB, ni unue iras al la inversa indekso. Ni ricevu ĉion timeseries_ids rekordoj kiuj kongruas kun ĉi tiu aro label=value. Kaj tiam ni ricevas ĉiujn necesajn datumojn de la datumstokejo, indeksitaj de timeseries_ids.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni rigardu ekzemplon de kiel temposeriodatumbazo prilaboras envenantan elektan demandon.

  • Antaŭ ĉio ŝi ricevas ĉion timeseries_ids de inversa indekso kiu enhavas la donitajn parojn label=value, aŭ kontentigi donitan regulan esprimon.
  • Tiam ĝi reakiras ĉiujn datumpunktojn el la datumstokado je difinita tempointervalo por la trovitaj timeseries_ids.
  • Post tio, la datumbazo faras kelkajn kalkulojn sur ĉi tiuj datumpunktoj, laŭ la peto de la uzanto. Kaj post tio ĝi resendas la respondon.

En ĉi tiu prezento mi rakontos al vi pri la unua parto. Ĉi tio estas serĉo timeseries_ids per inversa indekso. Pri la dua parto kaj la tria parto vi povas rigardi poste VictoriaMetrics-fontoj, aŭ atendu ĝis mi preparos aliajn raportojn :)

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni transiru al la inversa indekso. Multaj eble pensas, ke ĉi tio estas simpla. Kiu scias, kio estas inversa indekso kaj kiel ĝi funkcias? Ho, ne plu tiom da homoj. Ni provu kompreni, kio ĝi estas.

Ĝi estas efektive simpla. Ĝi estas simple vortaro, kiu mapas ŝlosilon al valoro. Kio estas ŝlosilo? Ĉi tiu paro label=valuekie label и value - ĉi tiuj estas linioj. Kaj la valoroj estas aro timeseries_ids, kiu inkluzivas la donitan paron label=value.

Inversa indekso permesas vin rapide trovi ĉion timeseries_ids, kiuj donis label=value.

Ĝi ankaŭ permesas vin rapide trovi timeseries_ids temposerio por pluraj paroj label=value, aŭ por paroj label=regexp. Kiel tio okazas? Trovante la intersekciĝon de la aro timeseries_ids por ĉiu paro label=value.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni rigardu diversajn efektivigojn de la inversa indekso. Ni komencu per la plej simpla naiva efektivigo. Ŝi aspektas tiel.

funkcio getMetricIDs ricevas liston de ŝnuroj. Ĉiu linio enhavas label=value. Ĉi tiu funkcio liveras liston metricIDs.

Kiel ĝi funkcias? Ĉi tie ni havas tutmondan variablon nomitan invertedIndex. Ĉi tio estas regula vortaro (map), kiu mapos la ŝnuron por tranĉi intojn. La linio enhavas label=value.

Funkcia efektivigo: get metricIDs por la unua label=value, tiam ni trapasas ĉion alian label=value, ni ricevas ĝin metricIDs por ili. Kaj voku la funkcion intersectInts, kiu estos diskutita malsupre. Kaj ĉi tiu funkcio redonas la intersekcon de ĉi tiuj listoj.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kiel vi povas vidi, efektivigi inversan indekson ne estas tre komplika. Sed ĉi tio estas naiva efektivigo. Kiajn malavantaĝojn ĝi havas? La ĉefa malavantaĝo de la naiva efektivigo estas, ke tia inversa indekso estas stokita en RAM. Post rekomenco de la aplikaĵo ni perdas ĉi tiun indekson. Ne estas konservado de ĉi tiu indekso al disko. Tia inversa indekso verŝajne ne taŭgas por datumbazo.

La dua malavantaĝo ankaŭ rilatas al memoro. La inversa indekso devas konveni en RAM. Se ĝi superas la grandecon de RAM, tiam evidente ni eliros - el memoro eraro. Kaj la programo ne funkcios.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ĉi tiu problemo povas esti solvita uzante pretajn solvojn kiel ekzemple LevelDBRocksDB.

Resume, ni bezonas datumbazon, kiu ebligas al ni fari tri operaciojn rapide.

  • La unua operacio estas registrado ключ-значение al ĉi tiu datumbazo. Ŝi faras tion tre rapide, kie ключ-значение estas arbitraj ŝnuroj.
  • La dua operacio estas rapida serĉo de valoro uzante donitan ŝlosilon.
  • Kaj la tria operacio estas rapida serĉo por ĉiuj valoroj per donita prefikso.

LevelDB kaj RocksDB - ĉi tiuj datumbazoj estis evoluigitaj de Google kaj Facebook. Unue venis LevelDB. Tiam la uloj de Facebook prenis LevelDB kaj komencis plibonigi ĝin, ili faris RocksDB. Nun preskaŭ ĉiuj internaj datumbazoj funkcias sur RocksDB ene de Facebook, inkluzive de tiuj, kiuj estis translokigitaj al RocksDB kaj MySQL. Ili nomis lin MiajRokoj.

Inversa indekso povas esti efektivigita uzante LevelDB. Kiel fari ĝin? Ni konservas kiel ŝlosilon label=value. Kaj la valoro estas la identigilo de la temposerio kie la paro ĉeestas label=value.

Se ni havas multajn tempajn seriojn kun donita paro label=value, tiam estos multaj vicoj en ĉi tiu datumbazo kun la sama ŝlosilo kaj malsama timeseries_ids. Por ricevi liston de ĉiuj timeseries_ids, kiuj komenciĝas per ĉi tio label=prefix, ni faras intervalan skanadon por kiu ĉi tiu datumbazo estas optimumigita. Tio estas, ni elektas ĉiujn liniojn, kiuj komenciĝas per label=prefix kaj akiru la necesajn timeseries_ids.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Jen ekzempla efektivigo de kiel ĝi aspektus en Go. Ni havas inversan indekson. Ĉi tio estas LevelDB.

La funkcio estas la sama kiel por la naiva efektivigo. Ĝi ripetas la naivan efektivigon preskaŭ linion post linio. La sola punkto estas, ke anstataŭ turni sin al map ni aliras la inversan indekson. Ni ricevas ĉiujn valorojn por la unua label=value. Poste ni trarigardas ĉiujn ceterajn parojn label=value kaj ricevu la respondajn arojn de metrikaj ID por ili. Tiam ni trovas la intersekciĝon.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ĉio ŝajnas esti bona, sed estas malavantaĝoj al ĉi tiu solvo. VictoriaMetrics komence efektivigis inversan indekson bazitan sur LevelDB. Sed fine mi devis rezigni ĝin.

Kial? Ĉar LevelDB estas pli malrapida ol la naiva efektivigo. En naiva efektivigo, donita donita ŝlosilo, ni tuj reakiras la tutan tranĉaĵon metricIDs. Ĉi tio estas tre rapida operacio - la tuta tranĉaĵo estas preta por uzo.

En LevelDB, ĉiufoje kiam funkcio estas vokita GetValues vi devas trairi ĉiujn liniojn, kiuj komenciĝas per label=value. Kaj ricevu la valoron por ĉiu linio timeseries_ids. De tia timeseries_ids kolektu tranĉaĵon de ĉi tiuj timeseries_ids. Evidente, ĉi tio estas multe pli malrapida ol simple aliri regulan mapon per klavo.

La dua malavantaĝo estas, ke LevelDB estas skribita en C. Voki C-funkciojn de Go ne estas tre rapida. Ĝi bezonas centojn da nanosekundoj. Ĉi tio ne estas tre rapida, ĉar kompare kun regula funkcio voko skribita en go, kiu daŭras 1-5 nanosekundojn, la diferenco en rendimento estas dekoble. Por VictoriaMetrics tio estis mortiga difekto :)

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Do mi skribis mian propran efektivigon de la inversa indekso. Kaj li vokis ŝin mergeset.

Mergeset estas bazita sur la MergeTree-datumstrukturo. Ĉi tiu datuma strukturo estas pruntita de ClickHouse. Evidente, mergeset devus esti optimumigita por rapida serĉado timeseries_ids laŭ la donita ŝlosilo. Mergeset estas skribita tute en Go. Vi povas vidi VictoriaMetrics-fontoj en GitHub. La efektivigo de mergeset estas en la dosierujo /lib/mergeset. Vi povas provi eltrovi kio okazas tie.

La mergeset API estas tre simila al LevelDB kaj RocksDB. Tio estas, ĝi permesas vin rapide konservi novajn rekordojn tie kaj rapide elekti rekordojn per donita prefikso.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Pri la malavantaĝoj de mergeset ni parolos poste. Nun ni parolu pri kiaj problemoj ekestis kun VictoriaMetrics en produktado dum efektivigo de inversa indekso.

Kial ili ekestis?

La unua kialo estas la alta churn-procento. Tradukita en la rusan, tio estas ofta ŝanĝo en temposerio. Jen kiam temposerio finiĝas kaj nova serio komenciĝas, aŭ multaj novaj temposerio komenciĝas. Kaj ĉi tio okazas ofte.

La dua kialo estas la granda nombro da temposerio. En la komenco, kiam monitorado akiris popularecon, la nombro da temposerio estis malgranda. Ekzemple, por ĉiu komputilo vi devas monitori CPU, memoron, reton kaj diskŝarĝon. 4 temposerio per komputilo. Ni diru, ke vi havas 100 komputilojn kaj 400 temposerion. Ĉi tio estas tre malmulte.

Kun la tempo, homoj komprenis, ke ili povas mezuri pli granulajn informojn. Ekzemple, mezuru la ŝarĝon ne de la tuta procesoro, sed aparte de ĉiu procesoro-kerno. Se vi havas 40 procesorajn kernojn, tiam vi havas 40 fojojn pli da temposerio por mezuri procesoran ŝarĝon.

Sed tio ne estas ĉio. Ĉiu procesorkerno povas havi plurajn statojn, kiel ekzemple neaktiva, kiam ĝi estas neaktiva. Kaj ankaŭ labori en uzantspaco, labori en kernspaco kaj aliaj ŝtatoj. Kaj ĉiu tia stato ankaŭ povas esti mezurita kiel aparta temposerio. Ĉi tio aldone pliigas la nombron da vicoj je 7-8 fojojn.

De unu metriko ni ricevis 40 x 8 = 320 metrikoj por nur unu komputilo. Multipliku per 100, ni ricevas 32 anstataŭ 000.

Tiam venis Kubernetes. Kaj ĝi plimalboniĝis ĉar Kubernetes povas gastigi multajn malsamajn servojn. Ĉiu servo en Kubernetes konsistas el multaj balgoj. Kaj ĉio ĉi devas esti monitorita. Krome, ni havas konstantan deplojon de novaj versioj de viaj servoj. Por ĉiu nova versio, nova temposerio devas esti kreita. Kiel rezulto, la nombro da temposerio kreskas eksponente kaj ni estas antaŭ la problemo de granda nombro da temposerio, kiu estas nomita alt-kardinaleco. VictoriaMetrics traktas ĝin sukcese kompare kun aliaj tempseriaj datumbazoj.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni rigardu pli detale la altan forton. Kio kaŭzas altan faloprocenton en produktado? Ĉar iuj signifoj de etikedoj kaj etikedoj konstante ŝanĝiĝas.

Ekzemple, prenu Kubernetes, kiu havas la koncepton deployment, t.e. kiam nova versio de via aplikaĵo estas lanĉita. Ial, la programistoj de Kubernetes decidis aldoni la deplojan identigilon al la etikedo.

Al kio ĉi tio kondukis? Plie, kun ĉiu nova deplojo, ĉiuj malnovaj temposerio estas interrompitaj, kaj anstataŭ ili, novaj temposerio komenciĝas per nova etikedvaloro. deployment_id. Povas esti centoj da miloj kaj eĉ milionoj da tiaj vicoj.

La grava afero pri ĉio ĉi estas, ke la tuta nombro da temposerio kreskas, sed la nombro da temposerio, kiuj estas nuntempe aktivaj kaj ricevantaj datumoj, restas konstanta. Ĉi tiu stato estas nomita alta churn-indico.

La ĉefproblemo de alta ĉagreno estas certigi konstantan serĉrapidecon por ĉiuj temposerio por antaŭfiksita aro de etikedoj dum certa tempointervalo. Tipe ĉi tio estas la tempointervalo por la lasta horo aŭ la lasta tago.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kiel solvi ĉi tiun problemon? Jen la unua opcio. Ĉi tio estas dividi la inversan indekson en sendependajn partojn laŭlonge de la tempo. Tio estas, iom da tempointervalo pasas, ni finas labori kun la nuna inversa indekso. Kaj kreu novan inversan indekson. Alia tempintervalo pasas, ni kreas alian kaj alian.

Kaj dum specimenigo de ĉi tiuj inversaj indeksoj, ni trovas aron de inversaj indeksoj kiuj falas ene de la donita intervalo. Kaj, sekve, ni elektas la id de la temposerio de tie.

Ĉi tio ŝparas rimedojn ĉar ni ne devas rigardi partojn kiuj ne falas en la donita intervalo. Tio estas, kutime, se ni elektas datumojn por la lasta horo, tiam por antaŭaj tempintervaloj ni preterlasas petojn.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Estas alia eblo por solvi ĉi tiun problemon. Ĉi tio estas por stoki por ĉiu tago apartan liston de identigiloj de temposerio kiuj okazis en tiu tago.

La avantaĝo de ĉi tiu solvo super la antaŭa solvo estas, ke ni ne duobligas tempajn informojn, kiuj ne malaperas kun la tempo. Ili konstante ĉeestas kaj ne ŝanĝiĝas.

La malavantaĝo estas, ke tia solvo estas pli malfacile efektivigebla kaj pli malfacile sencimebla. Kaj VictoriaMetrics elektis ĉi tiun solvon. Tiel okazis historie. Ĉi tiu solvo ankaŭ funkcias bone kompare kun la antaŭa. Ĉar ĉi tiu solvo ne estis efektivigita pro tio, ke necesas duobligi datumojn en ĉiu subdisko por temposerio, kiuj ne ŝanĝas, t.e. kiuj ne malaperas kun la tempo. VictoriaMetrics estis ĉefe optimumigita por diskspackonsumo, kaj la antaŭa efektivigo igis diskspackonsumon pli malbona. Sed ĉi tiu efektivigo pli taŭgas por minimumigi konsumon de diskspaco, do ĝi estis elektita.

Mi devis kontraŭbatali ŝin. La lukto estis, ke en ĉi tiu efektivigo vi ankoraŭ bezonas elekti multe pli grandan nombron timeseries_ids por datenoj ol kiam la inversa indekso estas tempe dividita.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kiel ni solvis ĉi tiun problemon? Ni solvis ĝin en originala maniero - stokante plurajn tempserio-identigilojn en ĉiu inversa indeksaĵo anstataŭ unu identigilo. Tio estas, ni havas ŝlosilon label=value, kiu okazas en ĉiu temposerio. Kaj nun ni savas plurajn timeseries_ids en unu eniro.

Jen ekzemplo. Antaŭe ni havis N enskribojn, sed nun ni havas unu enskribon, kies prefikso estas la sama kiel ĉiuj aliaj. Por la antaŭa enskribo, la valoro enhavas ĉiujn tempseriajn idojn.

Ĉi tio ebligis pliigi la skanan rapidon de tia inversa indekso ĝis 10 fojojn. Kaj ĝi permesis al ni redukti memorkonsumon por la kaŝmemoro, ĉar nun ni stokas la ŝnuron label=value nur unufoje en la kaŝmemoro kune N fojojn. Kaj ĉi tiu linio povas esti granda se vi stokas longajn liniojn en viaj etikedoj kaj etikedoj, kiujn Kubernetes ŝatas ŝovi tien.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Alia opcio por akceli serĉadon sur inversa indekso estas sharding. Krei plurajn inversajn indeksojn anstataŭ unu kaj dividi datumojn inter ili per ŝlosilo. Ĉi tio estas aro key=value vaporo. Tio estas, ni ricevas plurajn sendependajn inversajn indeksojn, kiujn ni povas konsulti paralele sur pluraj procesoroj. Antaŭaj efektivigoj nur permesis operacion en unu-procesora reĝimo, t.e., skanante datenojn sur nur unu kerno. Ĉi tiu solvo ebligas al vi skani datumojn sur pluraj kernoj samtempe, kiel ClickHouse ŝatas fari. Jen kion ni planas efektivigi.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Nun ni revenu al niaj ŝafoj - al la intersekca funkcio timeseries_ids. Ni konsideru, kiaj efektivigoj povas esti. Ĉi tiu funkcio permesas trovi timeseries_ids por donita aro label=value.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

La unua opcio estas naiva efektivigo. Du nestitaj bukloj. Ĉi tie ni ricevas la funkcion enigo intersectInts du tranĉaĵoj - a и b. Ĉe la eligo, ĝi devus redoni al ni la intersekciĝon de ĉi tiuj tranĉaĵoj.

Naiva efektivigo aspektas tiel. Ni ripetas super ĉiuj valoroj de tranĉaĵo a, ene de ĉi tiu buklo ni ekzamenas ĉiujn valorojn de tranĉaĵo b. Kaj ni komparas ilin. Se ili kongruas, tiam ni trovis intersekciĝon. Kaj konservu ĝin enen result.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kio estas la malavantaĝoj? Kvadrata komplekseco estas ĝia ĉefa malavantaĝo. Ekzemple, se viaj dimensioj estas tranĉaĵo a и b unu miliono samtempe, tiam ĉi tiu funkcio neniam resendos al vi respondon. Ĉar ĝi devos fari unu duilionon da ripetoj, kio estas multe eĉ por modernaj komputiloj.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

La dua efektivigo baziĝas sur mapo. Ni kreas mapon. Ni metas ĉiujn valorojn de tranĉaĵo en ĉi tiun mapon a. Poste ni trapasas tranĉaĵon en aparta buklo b. Kaj ni kontrolas ĉu ĉi tiu valoro estas de tranĉaĵo b en mapo. Se ĝi ekzistas, tiam aldonu ĝin al la rezulto.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kio estas la avantaĝoj? La avantaĝo estas ke ekzistas nur linia komplekseco. Tio estas, la funkcio efektiviĝos multe pli rapide por pli grandaj tranĉaĵoj. Por miliongranda tranĉaĵo, ĉi tiu funkcio efektiviĝos en 2 milionoj da ripetoj, kontraste al la duilionoj da ripetoj de la antaŭa funkcio.

La malavantaĝo estas, ke ĉi tiu funkcio postulas pli da memoro por krei ĉi tiun mapon.

La dua malavantaĝo estas la granda supre por hashing. Ĉi tiu malavantaĝo ne estas tre evidenta. Kaj por ni ankaŭ ne estis tre evidenta, do komence en VictoriaMetrics la efektivigo de intersekco estis per mapo. Sed tiam profilado montris, ke la ĉefa procesora tempo estas pasigita skribante al la mapo kaj kontrolante la ĉeeston de valoro en ĉi tiu mapo.

Kial CPU-tempo malŝparas en ĉi tiuj lokoj? Ĉar Go faras haŝan operacion sur ĉi tiuj linioj. Tio estas, ĝi kalkulas la hash de la ŝlosilo por tiam aliri ĝin ĉe donita indekso en la HashMap. La hash-kalkuloperacio finiĝas en dekoj da nanosekundoj. Ĉi tio estas malrapida por VictoriaMetrics.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Mi decidis efektivigi bitset optimumigitan specife por ĉi tiu kazo. Jen kiel aspektas nun la intersekco de du tranĉaĵoj. Ĉi tie ni kreas bitset. Ni aldonas elementojn de la unua tranĉaĵo al ĝi. Tiam ni kontrolas la ĉeeston de ĉi tiuj elementoj en la dua tranĉaĵo. Kaj aldonu ilin al la rezulto. Tio estas, ĝi preskaŭ ne diferencas de la antaŭa ekzemplo. La sola afero ĉi tie estas, ke ni anstataŭigis aliron al mapo per kutimaj funkcioj add и has.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Unuavide, ŝajnas, ke ĉi tio devus funkcii pli malrapide, se antaŭe oni uzis tie norman mapo, kaj tiam iuj aliaj funkcioj estas nomitaj, sed profilado montras, ke ĉi tiu afero funkcias 10 fojojn pli rapide ol la norma mapo en la kazo de VictoriaMetrics.

Krome, ĝi uzas multe malpli da memoro kompare kun la map-efektivigo. Ĉar ni stokas bitojn ĉi tie anstataŭ ok-bajtaj valoroj.

La malavantaĝo de ĉi tiu efektivigo estas ke ĝi ne estas tiel evidenta, ne bagatela.

Alia malavantaĝo, kiun multaj eble ne rimarkas, estas, ke ĉi tiu efektivigo eble ne funkcias bone en iuj kazoj. Tio estas, ĝi estas optimumigita por specifa kazo, por ĉi tiu kazo de intersekco de VictoriaMetrics temposerio-identigiloj. Ĉi tio ne signifas, ke ĝi taŭgas por ĉiuj kazoj. Se ĝi estas uzata malĝuste, ni ne ricevos rendimenton pliiĝon, sed malplenan memoran eraron kaj malrapidiĝon de rendimento.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni konsideru la efektivigon de ĉi tiu strukturo. Se vi volas rigardi, ĝi troviĝas en la fontoj de VictoriaMetrics, en la dosierujo lib/uint64set. Ĝi estas optimumigita specife por la kazo VictoriaMetrics, kie timeseries_id estas 64-bita valoro, kie la unuaj 32 bitoj estas baze konstantaj kaj nur la lastaj 32 bitoj ŝanĝiĝas.

Ĉi tiu datumstrukturo ne estas stokita sur disko, ĝi nur funkcias en memoro.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Jen ĝia API. Ĝi ne estas tre komplika. La API estas adaptita specife al specifa ekzemplo de uzado de VictoriaMetrics. Tio estas, ĉi tie ne estas nenecesaj funkcioj. Jen la funkcioj eksplicite uzataj de VictoriaMetrics.

Estas funkcioj add, kiu aldonas novajn valorojn. Estas funkcio has, kiu kontrolas novajn valorojn. Kaj estas funkcio del, kiu forigas valorojn. Estas helpa funkcio len, kiu resendas la grandecon de la aro. Funkcio clone klonas multe. Kaj funkcio appendto konvertas ĉi tiun aron al tranĉaĵo timeseries_ids.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Jen kiel aspektas la efektivigo de ĉi tiu datuma strukturo. aro havas du elementojn:

  • ItemsCount estas helpkampo por rapide resendi la nombron da elementoj en aro. Eblus malhavi ĉi tiun helpan kampon, sed ĝi devis esti aldonita ĉi tie ĉar VictoriaMetrics ofte demandas la longecon de bitseto en siaj algoritmoj.

  • La dua kampo estas buckets. Ĉi tio estas tranĉaĵo de la strukturo bucket32. Ĉiu strukturo stokas hi kampo. Ĉi tiuj estas la supraj 32 bitoj. Kaj du tranĉaĵoj - b16his и buckets el bucket16 strukturoj.

La supraj 16 bitoj de la dua parto de la 64-bita strukturo estas stokitaj ĉi tie. Kaj ĉi tie bitoj estas stokitaj por la pli malaltaj 16 bitoj de ĉiu bajto.

Bucket64 konsistas el tabelo uint64. La longo estas kalkulita uzante ĉi tiujn konstantojn. En unu bucket16 maksimumo povas esti stokita 2^16=65536 iom. Se vi dividas ĉi tion per 8, tiam ĝi estas 8 kilobajtoj. Se vi denove dividas per 8, ĝi estas 1000 uint64 signifo. Tio estas Bucket16 – jen nia 8-kilobajta strukturo.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ni rigardu kiel unu el la metodoj de ĉi tiu strukturo por aldoni novan valoron estas efektivigita.

Ĉio komenciĝas per uint64 signifoj. Ni kalkulas la suprajn 32 bitojn, ni kalkulas la malsuperajn 32 bitojn. Ni trairu ĉion buckets. Ni komparas la suprajn 32 bitojn en ĉiu sitelo kun la valoro aldonita. Kaj se ili kongruas, tiam ni nomas la funkcion add en strukturo b32 buckets. Kaj aldonu la pli malaltajn 32 bitojn tie. Kaj se ĝi revenus true, tiam tio signifas, ke ni aldonis tian valoron tie kaj ni ne havis tian valoron. Se ĝi revenas false, tiam tia signifo jam ekzistis. Tiam ni pliigas la nombron da elementoj en la strukturo.

Se ni ne trovis tiun, kiun vi bezonas bucket kun la bezonata hi-valoro, tiam ni nomas la funkcion addAlloc, kiu produktos novan bucket, aldonante ĝin al la sitela strukturo.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Ĉi tio estas la efektivigo de la funkcio b32.add. Ĝi estas simila al la antaŭa efektivigo. Ni kalkulas la plej signifajn 16 bitojn, la malplej signifajn 16 bitojn.

Poste ni trapasas ĉiujn suprajn 16 bitojn. Ni trovas alumetojn. Kaj se estas kongruo, ni nomas la aldonan metodon, pri kiu ni konsideros en la sekva paĝo bucket16.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Kaj jen la plej malalta nivelo, kiu devus esti optimumigita kiel eble plej multe. Ni kalkulas por uint64 id valoro en tranĉaĵo bito kaj ankaŭ bitmask. Ĉi tio estas masko por donita 64-bita valoro, kiu povas esti uzata por kontroli la ĉeeston de ĉi tiu bito, aŭ agordi ĝin. Ni kontrolas ĉu ĉi tiu bito estas agordita kaj agordi ĝin, kaj redoni ĉeeston. Ĉi tio estas nia efektivigo, kiu ebligis al ni akceli la operacion de intersekcaj identigiloj de temposerio je 10 fojojn kompare kun konvenciaj mapoj.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Krom ĉi tiu optimumigo, VictoriaMetrics havas multajn aliajn optimumigojn. Plej multaj el ĉi tiuj optimumigoj estis aldonitaj ial, sed post profilado de la kodo en produktado.

Ĉi tio estas la ĉefa regulo de optimumigo - ne aldonu optimumigon, supozante, ke ĉi tie estos botelkolo, ĉar eble ne estos botelkolo tie. Optimumigo kutime degradas la kvaliton de la kodo. Tial indas optimumigi nur post profilado kaj prefere en produktado, por ke ĉi tio estu realaj datumoj. Se iu interesiĝas, vi povas rigardi la fontkodon de VictoriaMetrics kaj esplori aliajn optimumojn, kiuj ekzistas.

Iru optimumigojn en VictoriaMetrics. Aleksandro Valyalkin

Mi havas demandon pri bitset. Tre simila al la C++ vektora bool-efektivigo, optimumigita bitaro. Ĉu vi prenis la efektivigon de tie?

Ne, ne de tie. Dum la efektivigo de ĉi tiu bitaro, mi estis gvidita de scio pri la strukturo de ĉi tiuj id-aj temposerioj, kiuj estas uzataj en VictoriaMetrics. Kaj ilia strukturo estas tia, ke la supraj 32 bitoj estas esence konstantaj. La pli malaltaj 32 bitoj povas ŝanĝiĝi. Ju pli malalta estas la bito, des pli ofte ĝi povas ŝanĝiĝi. Tial ĉi tiu efektivigo estas specife optimumigita por ĉi tiu datuma strukturo. La efektivigo de C++, laŭ mia scio, estas optimumigita por la ĝenerala kazo. Se vi optimumigas por la ĝenerala kazo, tio signifas, ke ĝi ne estos la plej optimuma por specifa kazo.

Mi ankaŭ konsilas al vi spekti la raporton de Aleksej Milovid. Antaŭ proksimume monato, li parolis pri optimumigo en ClickHouse por specifaj specialaĵoj. Li nur diras, ke en la ĝenerala kazo, C++-efektivigo aŭ iu alia efektivigo estas tajlorita por bone funkcii averaĝe en hospitalo. Ĝi povas rezulti pli malbone ol scio-specifa efektivigo kiel la nia, kie ni scias, ke la supraj 32 bitoj estas plejparte konstantaj.

Mi havas duan demandon. Kio estas la fundamenta diferenco de InfluxDB?

Estas multaj fundamentaj diferencoj. Koncerne rendimenton kaj memorkonsumon, InfluxDB en testoj montras 10 fojojn pli da memorkonsumo por alta kardinaleca temposerio, kiam vi havas multajn el ili, ekzemple, milionojn. Ekzemple, VictoriaMetrics konsumas 1 GB per miliono da aktivaj vicoj, dum InfluxDB konsumas 10 GB. Kaj tio estas granda diferenco.

La dua fundamenta diferenco estas, ke InfluxDB havas strangajn demandlingvojn - Flux kaj InfluxQL. Ili ne estas tre oportunaj por labori kun temposerio kompare kun PromQL, kiu estas subtenata de VictoriaMetrics. PromQL estas demandolingvo de Prometheus.

Kaj plia diferenco estas, ke InfluxDB havas iomete strangan datummodelon, kie ĉiu linio povas stoki plurajn kampojn kun malsama aro de etikedoj. Ĉi tiuj linioj estas plue dividitaj en diversajn tabelojn. Ĉi tiuj pliaj komplikaĵoj malfaciligas la postan laboron kun ĉi tiu datumbazo. Estas malfacile subteni kaj kompreni.

En VictoriaMetrics ĉio estas multe pli simpla. Tie, ĉiu temposerio estas ŝlosilvaloro. La valoro estas aro de punktoj - (timestamp, value), kaj la ŝlosilo estas la aro label=value. Ne estas apartigo inter kampoj kaj mezuradoj. Ĝi permesas vin elekti ajnajn datumojn kaj poste kombini, aldoni, subtrahi, multobligi, dividi, male al InfluxDB, kie kalkuloj inter malsamaj vicoj ankoraŭ ne estas efektivigitaj laŭ mia scio. Eĉ se ili estas efektivigitaj, estas malfacile, vi devas skribi multe da kodo.

Mi havas klarigantan demandon. Ĉu mi ĝuste komprenis, ke estis ia problemo, pri kiu vi parolis, ke tiu ĉi renversita indekso ne taŭgas en memoron, do tie estas dispartigo?

Unue, mi montris naivan efektivigon de inversa indekso sur norma Go-mapo. Ĉi tiu efektivigo ne taŭgas por datumbazoj ĉar ĉi tiu inversa indekso ne estas konservita al disko, kaj la datumbazo devas konservi al disko por ke ĉi tiuj datumoj restu disponeblaj post rekomenco. En ĉi tiu efektivigo, kiam vi rekomencas la aplikaĵon, via inversa indekso malaperos. Kaj vi perdos aliron al ĉiuj datumoj ĉar vi ne povos trovi ĝin.

Saluton! Dankon pro la raporto! Mia nomo estas Pavel. Mi estas de Wildberries. Mi havas kelkajn demandojn por vi. Demando unu. Ĉu vi pensas, ke se vi elektus alian principon dum konstruado de la arkitekturo de via aplikaĵo kaj dispartigus la datumojn laŭlonge de la tempo, tiam eble vi estus povinta intersekci datumojn dum serĉado, surbaze nur de tio, ke unu sekcio enhavas datumojn por unu. tempodaŭro , tio estas, en unu tempa intervalo kaj vi ne devus zorgi pri la fakto, ke viaj pecoj estas disaj malsame? Demando numero 2 - ĉar vi efektivigas similan algoritmon kun bitset kaj ĉio alia, do eble vi provis uzi procesorajn instrukciojn? Eble vi provis tiajn optimumojn?

Mi tuj respondos la duan. Ni ankoraŭ ne alvenis al tiu punkto. Sed se necese, ni alvenos tien. Kaj la unua, kio estis la demando?

Vi diskutis du scenarojn. Kaj ili diris, ke ili elektis la duan kun pli kompleksa efektivigo. Kaj ili ne preferis la unuan, kie la datumoj estas dividitaj laŭ tempo.

Jes. En la unua kazo, la totala volumo de la indekso estus pli granda, ĉar en ĉiu sekcio ni devus stoki duplikatajn datumojn por tiuj temposerio, kiuj daŭras tra ĉiuj ĉi tiuj sekcioj. Kaj se via temposeriokvanto estas malgranda, t.e. la samaj serioj estas konstante uzataj, tiam en la unua kazo ni perdus multe pli en la kvanto de diskospaco okupita kompare kun la dua kazo.

Kaj do - jes, tempa dispartigo estas bona elekto. Prometeo uzas ĝin. Sed Prometeo havas alian malavantaĝon. Dum kunfandado de ĉi tiuj datumoj, ĝi devas konservi en memoro metainformojn por ĉiuj etikedoj kaj temposerio. Sekve, se la datumoj kiujn ĝi kunfandas estas grandaj, tiam memorkonsumo multe pliiĝas dum kunfandado, male al VictoriaMetrics. Dum kunfandado, VictoriaMetrics tute ne konsumas memoron; nur kelkaj kilobajtoj estas konsumitaj, sendepende de la grandeco de la kunfanditaj datumoj.

La algoritmo, kiun vi uzas, uzas memoron. Ĝi markas temposeriotikedojn kiuj enhavas valorojn. Kaj tiamaniere vi kontrolas parigitan ĉeeston en unu datuma tabelo kaj en alia. Kaj vi komprenas ĉu intersekco okazis aŭ ne. Tipe, datumbazoj efektivigas kursorojn kaj ripetilojn kiuj stokas sian nunan enhavon kaj trakuras la ordigitajn datenojn pro la simpla komplekseco de ĉi tiuj operacioj.

Kial ni ne uzas kursorojn por trairi datumojn?

Jes.

Ni stokas ordigitajn vicojn en LevelDB aŭ mergeset. Ni povas movi la kursoron kaj trovi la intersekciĝon. Kial ni ne uzas ĝin? Ĉar ĝi estas malrapida. Ĉar kursoroj signifas, ke vi devas voki funkcion por ĉiu linio. Funkcia voko estas 5 nanosekundoj. Kaj se vi havas 100 liniojn, tiam rezultas, ke ni pasigas duonan sekundon nur voki la funkcion.

Estas tia afero, jes. Kaj mia lasta demando. La demando povas soni iom stranga. Kial ne eblas legi ĉiujn necesajn agregaĵojn en la momento, kiam la datumoj alvenas kaj konservi ilin en la bezonata formo? Kial ŝpari grandegajn volumojn en iuj sistemoj kiel VictoriaMetrics, ClickHouse, ktp., kaj poste pasigi multan tempon por ili?

Mi donos ekzemplon por pliklarigi ĝin. Ni diru kiel funkcias malgranda ludila rapidometro? Ĝi registras la distancon, kiun vi vojaĝis, la tutan tempon aldonante ĝin al unu valoro, kaj la duan fojon. Kaj dividas. Kaj ricevas mezan rapidecon. Vi povas fari pri la sama afero. Aldonu ĉiujn necesajn faktojn sur la flugo.

Bone, mi komprenas la demandon. Via ekzemplo havas sian lokon. Se vi scias, kiajn agregaĵojn vi bezonas, tiam ĉi tiu estas la plej bona efektivigo. Sed la problemo estas, ke homoj konservas ĉi tiujn metrikojn, iujn datumojn en ClickHouse kaj ili ankoraŭ ne scias kiel ili kunigos kaj filtrilos ilin estonte, do ili devas konservi ĉiujn krudajn datumojn. Sed se vi scias, ke vi bezonas kalkuli ion averaĝe, kial ne kalkuli ĝin anstataŭ stoki amason da krudaj valoroj tie? Sed ĉi tio estas nur se vi scias ĝuste kion vi bezonas.

Cetere, datumbazoj por stoki temposerio subtenas nombradon de agregaĵoj. Ekzemple, Prometeo subtenas reguloj pri registrado. Tio estas, tio povas esti farita se vi scias kiajn unuojn vi bezonos. VictoriaMetrics ankoraŭ ne havas ĉi tion, sed ĝi estas kutime antaŭita de Prometheus, en kiu tio povas esti farita en la rekodigaj reguloj.

Ekzemple, en mia antaŭa laboro mi devis kalkuli la nombron da eventoj en glita fenestro dum la lasta horo. La problemo estas, ke mi devis fari laŭmendan efektivigon en Go, t.e. servon por kalkuli ĉi tiun aferon. Ĉi tiu servo estis finfine ne bagatela, ĉar ĝi estas malfacile kalkulebla. La efektivigo povas esti simpla se vi bezonas kalkuli iujn agregaĵojn je fiksaj tempaj intervaloj. Se vi volas kalkuli eventojn en glita fenestro, tiam ĝi ne estas tiel simpla kiel ŝajnas. Mi pensas, ke ĉi tio ankoraŭ ne estis efektivigita en ClickHouse aŭ en tempaj datumbazoj, ĉar ĝi estas malfacile efektivigebla.

Kaj unu plia demando. Ni nur parolis pri averaĝado, kaj mi rememoris, ke iam ekzistis io kiel Grafito kun Karbona malantaŭo. Kaj li sciis kiel maldikigi malnovajn datumojn, tio estas, lasi unu poenton por minuto, unu poenton por horo, ktp. Principe ĉi tio estas sufiĉe oportuna, se ni bezonas krudajn datumojn, relative parolante, por monato, kaj ĉio alia povas. esti maldikigita. Sed Prometheus kaj VictoriaMetrics ne subtenas ĉi tiun funkcion. Ĉu oni planas subteni ĝin? Se ne, kial ne?

Dankon pro la demando. Niaj uzantoj faras ĉi tiun demandon periode. Ili demandas kiam ni aldonos subtenon por subspecimeno. Estas pluraj problemoj ĉi tie. Unue, ĉiu uzanto komprenas downsampling io malsama: iu volas ricevi ajnan arbitran punkton sur difinita intervalo, iu volas maksimumajn, minimumajn, averaĝajn valorojn. Se multaj sistemoj skribas datumojn al via datumbazo, tiam vi ne povas kunigi ĉion. Povas esti, ke ĉiu sistemo postulas malsaman maldikiĝon. Kaj ĉi tio estas malfacile efektivigi.

Kaj la dua afero estas, ke VictoriaMetrics, kiel ClickHouse, estas optimumigita por labori pri grandaj kvantoj da krudaj datumoj, do ĝi povas ŝoveli miliardojn da linioj en malpli ol sekundo se vi havas multajn kernojn en via sistemo. Skanado de temposeriopoentoj en VictoriaMetrics - 50 poentoj sekundo per kerno. Kaj ĉi tiu rendimento skalas al ekzistantaj kernoj. Tio estas, se vi havas 000 kernojn, ekzemple, vi skanos miliardojn da poentoj sekundo. Kaj ĉi tiu posedaĵo de VictoriaMetrics kaj ClickHouse reduktas la bezonon de subspecigo.

Alia trajto estas, ke VictoriaMetrics efike kunpremas ĉi tiujn datumojn. Kunpremo averaĝe en produktado estas de 0,4 ĝis 0,8 bajtoj po punkto. Ĉiu punkto estas tempomarko + valoro. Kaj ĝi estas kunpremita en malpli ol unu bajto averaĝe.

Sergey. Mi havas demandon. Kio estas la minimuma registra tempokvanto?

Unu milisekundo. Ni lastatempe konversaciis kun aliaj programistoj de datumbazoj de temposerio. Ilia minimuma tempotranĉo estas unu sekundo. Kaj en Grafito, ekzemple, ĝi estas ankaŭ unu sekundo. En OpenTSDB ĝi estas ankaŭ unu sekundo. InfluxDB havas nanosekundan precizecon. En VictoriaMetrics ĝi estas unu milisekundo, ĉar en Prometeo ĝi estas unu milisekundo. Kaj VictoriaMetrics estis origine evoluigita kiel fora stokado por Prometheus. Sed nun ĝi povas konservi datumojn de aliaj sistemoj.

La persono, kun kiu mi parolis, diras, ke ili havas dua-al-sekundan precizecon - tio sufiĉas por ili ĉar ĝi dependas de la tipo de datumoj, kiuj estas konservitaj en la temp-serio-datumbazo. Se ĉi tio estas DevOps-datumoj aŭ datumoj de infrastrukturo, kie vi kolektas ĝin je intervaloj de 30 sekundoj, je minuto, tiam dua precizeco sufiĉas, vi bezonas nenion malpli. Kaj se vi kolektas ĉi tiujn datumojn de altfrekvencaj komercaj sistemoj, tiam vi bezonas nanosekundan precizecon.

Milisekunda precizeco en VictoriaMetrics ankaŭ taŭgas por la kazo DevOps, kaj povas esti taŭga por la plej multaj el la kazoj, kiujn mi menciis komence de la raporto. La sola afero, por kiu ĝi eble ne taŭgas, estas altfrekvencaj komercaj sistemoj.

Dankon! Kaj alia demando. Kio estas kongruo en PromQL?

Plena malantaŭen kongruo. VictoriaMetrics plene subtenas PromQL. Krome, ĝi aldonas aldonan altnivelan funkciecon en PromQL, kiu nomiĝas MetricsQL. Estas parolado en Jutubo pri ĉi tiu etendita funkcio. Mi parolis ĉe la Monitora Renkontiĝo printempe en Sankt-Peterburgo.

Telegram-kanalo VictoriaMetrics.

Nur registritaj uzantoj povas partopreni la enketon. Ensaluti, bonvolu.

Kio malhelpas vin ŝanĝi al VictoriaMetrics kiel via longdaŭra stokado por Prometheus? (Skribu en la komentoj, mi aldonos ĝin al la balotado))

  • 71,4%Mi ne uzas Prometeon5

  • 28,6%Ne sciis pri VictoriaMetrics2

7 uzantoj voĉdonis. 12 uzantoj sindetenis.

fonto: www.habr.com

Aldoni komenton