{"id":80733,"date":"2020-05-08T13:42:31","date_gmt":"2020-05-08T11:42:31","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin"},"modified":"2020-05-08T13:42:31","modified_gmt":"2020-05-08T11:42:31","slug":"go-optimizations-in-victoriametrics-aleksandr-valyalkin","status":"publish","type":"post","link":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin","title":{"rendered":"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Nab\u00eddnout v\u00e1m, abyste se sezn\u00e1mili s p\u0159episem zpr\u00e1vy Alexandra Valjalkina z konce roku 2019 \"Optimalizace Go ve VictoriaMetrics\"<\/strong><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/victoriametrics.com\/\">VictoriaMetrics<\/a><\/noindex> \u2014 rychl\u00e1 a \u0161k\u00e1lovateln\u00e1 datab\u00e1ze pro ukl\u00e1d\u00e1n\u00ed a zpracov\u00e1n\u00ed dat v podob\u011b \u010dasov\u00fdch \u0159ad (z\u00e1znam p\u0159edstavuje \u010das a sadu hodnot odpov\u00eddaj\u00edc\u00edch tomuto \u010dasu, nap\u0159\u00edklad z\u00edskan\u00fdch prost\u0159ednictv\u00edm periodick\u00e9ho dotazov\u00e1n\u00ed stavu senzor\u016f nebo shroma\u017e\u010fov\u00e1n\u00ed metrik).<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/dd13ec10594aeb138be29ce439cc476a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Zde je odkaz na video t\u00e9to p\u0159edn\u00e1\u0161ky \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/MZ5P21j_HLE\">https:\/\/youtu.be\/MZ5P21j_HLE<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/docs.google.com\/presentation\/d\/1k7OjHvxTHA7669MFwsNTCx8hII-a8lNvpmQetLxmrEU\/edit?usp=sharing\">Prezentace<\/a><\/noindex><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/0073390d6dbcc6ab3e5305907ac6a229.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Trochu se p\u0159edstav\u00edm. Jsem Alexander Valjaljkin. Tady <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/valyala\">je m\u016fj GitHub \u00fa\u010det<\/a><\/noindex>. Zaj\u00edm\u00e1m se o Go a optimalizaci v\u00fdkonu. Napsal jsem spoustu r\u016fzn\u00fdch u\u017eite\u010dn\u00fdch a m\u00e9n\u011b u\u017eite\u010dn\u00fdch knihoven. Za\u010d\u00ednaj\u00ed bu\u010f s <code>fast<\/code>, nebo s <code>quick<\/code> prefixem. <\/p>\n<p><\/p>\n<p>V sou\u010dasn\u00e9 dob\u011b pracuji na VictoriaMetrics. Co to je a co tam d\u011bl\u00e1m? O tom budu hovo\u0159it v t\u00e9to prezentaci. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/c9194bc3fee1f615d838979bec12f7d0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pl\u00e1n p\u0159edn\u00e1\u0161ky je n\u00e1sleduj\u00edc\u00ed:<\/p>\n<p><\/p>\n<ul>\n<li>Nejprve v\u00e1m vysv\u011btl\u00edm, co je VictoriaMetrics. <\/li>\n<li>Pot\u00e9 v\u00e1m \u0159eknu, co jsou to \u010dasov\u00e9 \u0159ady. <\/li>\n<li>Pot\u00e9 pop\u00ed\u0161u, jak funguje datab\u00e1ze \u010dasov\u00fdch \u0159ad.<\/li>\n<li>Pak se budu v\u011bnovat architektu\u0159e datab\u00e1ze: z \u010deho se skl\u00e1d\u00e1.<\/li>\n<li>A nakonec p\u0159ejdeme k optimalizac\u00edm, kter\u00e9 jsou ve VictoriaMetrics. To zahrnuje optimalizaci inverzn\u00edho indexu a optimalizaci pro bitset-implementaci na Go.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/3e0244b6b6fe952f660e4a094778921a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V\u00ed n\u011bkdo v auditoriu, co je VictoriaMetrics? No vid\u00edte, mnoho lid\u00ed u\u017e to v\u00ed. To je dobr\u00e1 zpr\u00e1va. Pro ty, kte\u0159\u00ed nev\u00ed \u2013 je to datab\u00e1ze pro \u010dasov\u00e9 \u0159ady. Je zalo\u017eena na architektu\u0159e ClickHouse, na n\u011bkter\u00fdch detailech implementace ClickHouse. Nap\u0159\u00edklad na takov\u00fdch, jako je: MergeTree, paraleln\u00ed v\u00fdpo\u010dty na v\u0161ech dostupn\u00fdch j\u00e1drech procesoru a optimalizace v\u00fdkonu pomoc\u00ed pr\u00e1ce na bloc\u00edch dat, kter\u00e9 se ukl\u00e1daj\u00ed do mezipam\u011bti procesoru. <\/p>\n<p><\/p>\n<p>VictoriaMetrics poskytuje nejlep\u0161\u00ed kompresi dat ve srovn\u00e1n\u00ed s jin\u00fdmi datab\u00e1zemi pro \u010dasov\u00e9 \u0159ady. <\/p>\n<p><\/p>\n<p>\u0160k\u00e1lovateln\u011b vertik\u00e1ln\u011b \u2014 tj. m\u016f\u017eete p\u0159id\u00e1vat v\u00edce procesor\u016f, v\u00edce opera\u010dn\u00ed pam\u011bti na jednom po\u010d\u00edta\u010di. VictoriaMetrics bude \u00fasp\u011b\u0161n\u011b vyu\u017e\u00edvat tyto dostupn\u00e9 zdroje a zvy\u0161ovat line\u00e1rn\u00ed v\u00fdkon.<\/p>\n<p><\/p>\n<p>VictoriaMetrics tak\u00e9 \u0161k\u00e1lovateln\u011b horizont\u00e1ln\u011b \u2014 tj. m\u016f\u017eete p\u0159id\u00e1vat dal\u0161\u00ed uzly do clusteru VictoriaMetrics a jej\u00ed v\u00fdkon bude r\u016fst t\u00e9m\u011b\u0159 line\u00e1rn\u011b.<\/p>\n<p><\/p>\n<p>Jak jste asi uhodli, VictoriaMetrics je rychl\u00e1 datab\u00e1ze, proto\u017ee o jin\u00fdch nemohu ps\u00e1t. A je napsan\u00e1 v Go, proto o n\u00ed mluv\u00edm na tomto meetupu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/0121c9baead722eb1fe22fb6f900d4ad.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kdo v\u00ed, co je to \u010dasov\u00e1 \u0159ada? Mnoho lid\u00ed to v\u00ed. \u010casov\u00e1 \u0159ada je s\u00e9rie p\u00e1r\u016f <code>(timestamp, hodnota)<\/code>, kde jsou tyto p\u00e1ry se\u0159azeny podle \u010dasu. Hodnota je \u010d\u00edslo s plovouc\u00ed desetinnou \u010d\u00e1rkou \u2013 float64.<\/p>\n<p><\/p>\n<p>Ka\u017ed\u00e1 \u010dasov\u00e1 \u0159ada je jedine\u010dn\u011b identifikov\u00e1na kl\u00ed\u010dem. Z \u010deho se tento kl\u00ed\u010d skl\u00e1d\u00e1? Skl\u00e1d\u00e1 se z nepr\u00e1zdn\u00e9 mno\u017einy p\u00e1r\u016f kl\u00ed\u010d-hodnota. <\/p>\n<p><\/p>\n<p>Zde je p\u0159\u00edklad \u010dasov\u00e9 \u0159ady. Kl\u00ed\u010dem t\u00e9to \u0159ady je seznam p\u00e1r\u016f: <code>__name__=\"cpu_usage\"<\/code> \u2013 to je n\u00e1zev metriky, <code>instance=\"my-server\"<\/code> \u2013 to je po\u010d\u00edta\u010d, na kter\u00e9m byla tato metrika shrom\u00e1\u017ed\u011bna, <code>datacenter=\"us-east\"<\/code> \u2013 to je datov\u00e9 centrum, kde je tento po\u010d\u00edta\u010d um\u00edst\u011bn.<\/p>\n<p><\/p>\n<p>M\u00e1me jm\u00e9no \u010dasov\u00e9 \u0159ady slo\u017een\u00e9 ze t\u0159\u00ed p\u00e1r\u016f kl\u00ed\u010d-hodnota. Tomu kl\u00ed\u010di odpov\u00edd\u00e1 seznam p\u00e1r\u016f <code>(timestamp, value)<\/code>. <code>t1, t3, t3, ..., tN<\/code> \u2013 to jsou \u010dasov\u00e1 raz\u00edtka, <code>10, 20, 12, ..., 15<\/code> \u2013 odpov\u00eddaj\u00edc\u00ed hodnoty. To je cpu-usage v dan\u00e9m okam\u017eiku pro danou \u0159adu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/76cab9db0263318d355ac607ceb7e0f6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kde mohou b\u00fdt \u010dasov\u00e9 \u0159ady pou\u017eity? M\u00e1 n\u011bkdo n\u011bjak\u00e9 n\u00e1pady? <\/p>\n<p><\/p>\n<ul>\n<li>V DevOps lze m\u011b\u0159it zat\u00ed\u017een\u00ed CPU, RAM, s\u00edt\u011b, rps, po\u010det chyb atd. <\/li>\n<li>IoT \u2013 m\u016f\u017eeme m\u011b\u0159it teplotu, tlak, geokoordin\u00e1ty a dal\u0161\u00ed.<\/li>\n<li>Tak\u00e9 finance \u2013 m\u016f\u017eeme monitorovat ceny akci\u00ed a m\u011bn. <\/li>\n<li>Krom\u011b toho mohou b\u00fdt \u010dasov\u00e9 \u0159ady pou\u017eity k monitorov\u00e1n\u00ed v\u00fdrobn\u00edch proces\u016f v tov\u00e1rn\u00e1ch. M\u00e1me u\u017eivatele, kte\u0159\u00ed pou\u017e\u00edvaj\u00ed VictoriaMetrics k monitorov\u00e1n\u00ed v\u011btrn\u00fdch turb\u00edn a robot\u016f.<\/li>\n<li>Tak\u00e9 \u010dasov\u00e9 \u0159ady jsou u\u017eite\u010dn\u00e9 pro shroma\u017e\u010fov\u00e1n\u00ed informac\u00ed ze senzor\u016f r\u016fzn\u00fdch za\u0159\u00edzen\u00ed. Nap\u0159\u00edklad pro motor; pro m\u011b\u0159en\u00ed tlaku v pneumatik\u00e1ch; pro m\u011b\u0159en\u00ed rychlosti, vzd\u00e1lenosti; pro m\u011b\u0159en\u00ed spot\u0159eby benz\u00ednu atd.<\/li>\n<li>Tak\u00e9 \u010dasov\u00e9 \u0159ady mohou b\u00fdt pou\u017eity k monitorov\u00e1n\u00ed letadel. V ka\u017ed\u00e9m letadle je \u010dern\u00e1 sk\u0159\u00ed\u0148ka, kter\u00e1 shroma\u017e\u010fuje \u010dasov\u00e9 \u0159ady podle r\u016fzn\u00fdch parametr\u016f zdrav\u00ed letadla. \u010casov\u00e9 \u0159ady se tak\u00e9 pou\u017e\u00edvaj\u00ed v leteck\u00e9m pr\u016fmyslu. <\/li>\n<li>Zdravotnictv\u00ed \u2013 to jsou krevn\u00ed tlak, puls atd.<\/li>\n<\/ul>\n<p><\/p>\n<p>Mo\u017en\u00e1 je\u0161t\u011b existuj\u00ed aplikace, na kter\u00e9 jsem zapomn\u011bl, ale douf\u00e1m, \u017ee jste pochopili, \u017ee \u010dasov\u00e9 \u0159ady jsou v modern\u00edm sv\u011bt\u011b aktivn\u011b vyu\u017e\u00edv\u00e1ny. A objem jejich vyu\u017eit\u00ed roste ka\u017ed\u00fdm rokem.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/f1da29d372163751268b6a8f86836d04.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>K \u010demu slou\u017e\u00ed datab\u00e1ze pro \u010dasov\u00e9 \u0159ady? Pro\u010d nelze pou\u017e\u00edt b\u011b\u017enou rela\u010dn\u00ed datab\u00e1zi pro uchov\u00e1v\u00e1n\u00ed \u010dasov\u00fdch \u0159ad?<\/p>\n<p><\/p>\n<p>Proto\u017ee v \u010dasov\u00fdch \u0159ad\u00e1ch obvykle existuje velk\u00e9 mno\u017estv\u00ed informac\u00ed, kter\u00e9 je obt\u00ed\u017en\u00e9 uchov\u00e1vat a zpracov\u00e1vat v b\u011b\u017en\u00fdch datab\u00e1z\u00edch. Proto vznikly specializovan\u00e9 datab\u00e1ze pro \u010dasov\u00e9 \u0159ady. Tyto datab\u00e1ze efektivn\u011b ukl\u00e1daj\u00ed body <code>(timestamp, value)<\/code> s ur\u010den\u00fdm kl\u00ed\u010dem. Poskytuj\u00ed API pro \u010dten\u00ed ulo\u017een\u00fdch dat podle kl\u00ed\u010de, po jedn\u00e9 dvojici kl\u00ed\u010d-hodnota, nebo po n\u011bkolika takov\u00fdch dvojic\u00edch, anebo podle regexp. Nap\u0159\u00edklad, pokud chcete zjistit zat\u00ed\u017een\u00ed procesoru v\u0161ech va\u0161ich slu\u017eeb v datov\u00e9m centru v Americe, pot\u0159ebujete pou\u017e\u00edt takov\u00fd pseudo-dotaz.<\/p>\n<p><\/p>\n<p>Obvykle datab\u00e1ze pro \u010dasov\u00e9 \u0159ady nab\u00edzej\u00ed specializovan\u00e9 dotazovac\u00ed jazyky, proto\u017ee SQL pro \u010dasov\u00e9 \u0159ady nen\u00ed p\u0159\u00edli\u0161 vhodn\u00fd. I kdy\u017e existuj\u00ed datab\u00e1ze, kter\u00e9 podporuj\u00ed SQL, to nen\u00ed p\u0159\u00edli\u0161 dob\u0159e funguj\u00edc\u00ed mo\u017enost. L\u00e9pe vyhovuj\u00ed takov\u00e9 dotazovac\u00ed jazyky jako <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/@valyala\/promql-tutorial-for-beginners-9ab455142085\">PromQL<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.influxdata.com\/influxdb\/v1.8\/query_language\/spec\/\">InfluxQL<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.influxdata.com\/products\/flux\/\">Flux<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/code.kx.com\/q\/\">Q<\/a><\/noindex>. Douf\u00e1m, \u017ee alespo\u0148 n\u011bkdo sly\u0161el o jednom z t\u011bchto jazyk\u016f. O PromQL pravd\u011bpodobn\u011b sly\u0161elo mnoho lid\u00ed. Je to dotazovac\u00ed jazyk Promethea.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/59e5b6d82a2f7861077bc5fe34519ee4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Takto vypad\u00e1 architektura modern\u00ed datab\u00e1ze pro \u010dasov\u00e9 \u0159ady na p\u0159\u00edkladu VictoriaMetrics.<\/p>\n<p><\/p>\n<p>Skl\u00e1d\u00e1 se ze dvou \u010d\u00e1st\u00ed. To je \u00falo\u017ei\u0161t\u011b pro invertovan\u00fd index a \u00falo\u017ei\u0161t\u011b pro hodnoty \u010dasov\u00fdch \u0159ad. Tato \u00falo\u017ei\u0161t\u011b jsou odd\u011blena. <\/p>\n<p><\/p>\n<p>Kdy\u017e p\u0159ijde nov\u00fd z\u00e1znam do datab\u00e1ze, nejprve se obrac\u00edme na invertovan\u00fd index, abychom na\u0161li identifik\u00e1tor \u010dasov\u00e9 \u0159ady podle zadan\u00e9ho souboru <code>label=value<\/code> pro tuto metriku. Najdeme tento identifik\u00e1tor a ulo\u017e\u00edme hodnotu do \u00falo\u017ei\u0161t\u011b dat.<\/p>\n<p><\/p>\n<p>Kdy\u017e p\u0159ijde n\u011bjak\u00fd dotaz na selekci dat z TSDB, nejprve se d\u00edv\u00e1me do invertovan\u00e9ho indexu. Z\u00edsk\u00e1me v\u0161echny <code>timeseries_ids<\/code> z\u00e1znamy, kter\u00e9 odpov\u00eddaj\u00ed dan\u00e9 mno\u017ein\u011b <code>label=value<\/code>. A pot\u00e9 vezmeme v\u0161echny pot\u0159ebn\u00e9 \u00fadaje z \u00falo\u017ei\u0161t\u011b dat, indexovan\u00e9ho podle <code>timeseries_ids<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/eb9b36fa3c6de2188b97b56ad3839b2c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uva\u017eujme p\u0159\u00edklad, jak datab\u00e1ze \u010dasov\u00fdch \u0159ad zpracov\u00e1v\u00e1 p\u0159\u00edchoz\u00ed select dotaz.<\/p>\n<p><\/p>\n<ul>\n<li>Nejprve z\u00edsk\u00e1 v\u0161echny <code>timeseries_ids<\/code> z invertovan\u00e9ho indexu, kter\u00e9 obsahuj\u00ed dan\u00e9 dvojice <code>label=value<\/code>, nebo spl\u0148uj\u00ed dan\u00fd regul\u00e1rn\u00ed v\u00fdraz.<\/li>\n<li>Pot\u00e9 z\u00edsk\u00e1 v\u0161echny data points z \u00falo\u017ei\u0161t\u011b dat na zadan\u00e9m \u010dasov\u00e9m intervalu pro nalezen\u00e9 <code>timeseries_ids<\/code>.<\/li>\n<li>Po tomto datab\u00e1ze provede n\u011bjak\u00e9 v\u00fdpo\u010dty na t\u011bchto datech podle po\u017eadavku u\u017eivatele. A pot\u00e9 vr\u00e1t\u00ed odpov\u011b\u010f.<\/li>\n<\/ul>\n<p><\/p>\n<p>V t\u00e9to prezentaci v\u00e1m pov\u00edm o prvn\u00ed \u010d\u00e1sti. To je vyhled\u00e1v\u00e1n\u00ed <code>timeseries_ids<\/code> v inverzn\u00edm indexu. O druh\u00e9 a t\u0159et\u00ed \u010d\u00e1sti se m\u016f\u017eete pod\u00edvat pozd\u011bji na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\">zdrojov\u00e9 k\u00f3dy VictoriaMetrics<\/a><\/noindex>, nebo si po\u010dkat, a\u017e p\u0159iprav\u00edm dal\u0161\u00ed p\u0159edn\u00e1\u0161ky \ud83d\ude42<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/3a7dab707dd1defb9bc674a342052a03.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Za\u010dn\u011bme s inverzn\u00edm indexem. Mnoha lidem se m\u016f\u017ee zd\u00e1t, \u017ee je to jednoduch\u00e9. Kdo v\u00ed, co je inverzn\u00ed index a jak funguje? O, u\u017e nen\u00ed tolik lid\u00ed. Poj\u010fme se pokusit pochopit, co to je. <\/p>\n<p><\/p>\n<p>Ve skute\u010dnosti je to jednoduch\u00e9. Je to jen slovn\u00edk, kter\u00fd mapuje kl\u00ed\u010d na hodnotu. Co je kl\u00ed\u010d? Tento p\u00e1r <code>label=value<\/code>, kde <code>label<\/code> a <code>value<\/code> \u2013 to jsou \u0159et\u011bzce. A hodnoty \u2013 to je mno\u017eina <code>timeseries_ids<\/code>, kter\u00e1 obsahuje dan\u00fd p\u00e1r <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p>Inverzn\u00ed index umo\u017e\u0148uje rychle naj\u00edt v\u0161echny <code>timeseries_ids<\/code>, kter\u00e9 maj\u00ed zadan\u00e9 <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p>A tak\u00e9 umo\u017e\u0148uje rychle naj\u00edt <code>timeseries_ids<\/code> \u010dasov\u00e9 \u0159ady pro v\u00edce p\u00e1r\u016f <code>label=value<\/code>, nebo pro p\u00e1ry <code>label=regexp<\/code>. Jak to prob\u00edh\u00e1? Pomoc\u00ed nalezen\u00ed pr\u016fniku mno\u017einy <code>timeseries_ids<\/code> pro ka\u017ed\u00fd p\u00e1r <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/837a15a078e8c9422c721f3f072c0c09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zva\u017eme r\u016fzn\u00e9 implementace inverzn\u00edho indexu. Za\u010dn\u011bme s nejsnaz\u0161\u00ed naivn\u00ed implementac\u00ed. Vypad\u00e1 to takto. <\/p>\n<p><\/p>\n<p>Funkce <code>getMetricIDs<\/code> z\u00edsk\u00e1v\u00e1 seznam \u0159et\u011bzc\u016f. Ka\u017ed\u00fd \u0159et\u011bzec obsahuje <code>label=value<\/code>. Tato funkce vrac\u00ed seznam <code>metricIDs<\/code>.<\/p>\n<p><\/p>\n<p>Jak to funguje? Tady m\u00e1me glob\u00e1ln\u00ed prom\u011bnnou, kter\u00e1 se naz\u00fdv\u00e1 <code>invertedIndex<\/code>. Je to b\u011b\u017en\u00fd slovn\u00edk (<code>mapa<\/code>), kter\u00fd mapuje \u0159et\u011bzec na slice int\u016f. \u0158et\u011bzec obsahuje <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p>Implementace funkce: vyt\u00e1hneme <code>metricIDs<\/code> pro prvn\u00ed <code>label=value<\/code>, pot\u00e9 projdeme v\u0161echny ostatn\u00ed <code>label=value<\/code>, vyt\u00e1hneme <code>metricIDs<\/code> pro n\u011b. A vol\u00e1me funkci <code>intersectInts<\/code>, o kter\u00e9 bude podrobn\u011bji \u0159e\u010d pozd\u011bji. A tato funkce vrac\u00ed pr\u016fnik t\u011bchto seznam\u016f.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/709beca79884a9693098781974c26f4d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak vid\u00edte, implementace inverzn\u00edho indexu nen\u00ed p\u0159\u00edli\u0161 slo\u017eit\u00e1. Ale je to naivn\u00ed implementace. Jak\u00e9 m\u00e1 nev\u00fdhody? Hlavn\u00ed nev\u00fdhodou naivn\u00ed implementace je ta, \u017ee takov\u00fd inverzn\u00ed index m\u00e1me ulo\u017een\u00fd v opera\u010dn\u00ed pam\u011bti. Po restartu aplikace ztr\u00e1c\u00edme tento index. Nen\u00ed ulo\u017een\u00ed tohoto indexu na disk. Pro datab\u00e1zi asi takov\u00fd inverzn\u00ed index nebude vhodn\u00fd.<\/p>\n<p><\/p>\n<p>Druh\u00fd nedostatek souvis\u00ed tak\u00e9 s pam\u011bt\u00ed. Inverzn\u00ed index mus\u00ed b\u00fdt um\u00edst\u011bn v pam\u011bti. Pokud p\u0159ekro\u010d\u00ed velikost opera\u010dn\u00ed pam\u011bti, dostaneme evidentn\u011b \u2013 chybu \u201eout of memory\u201c a program nebude fungovat.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/495394168ac03aa8cbcf56ccad1cb2b8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tento probl\u00e9m lze vy\u0159e\u0161it pomoc\u00ed hotov\u00fdch \u0159e\u0161en\u00ed, jako jsou <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/google\/leveldb\">LevelDB<\/a><\/noindex>, nebo <noindex><a rel=\"nofollow\" href=\"https:\/\/rocksdb.org\/\">RocksDB<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Pokud to shrneme, pot\u0159ebujeme datab\u00e1zi, kter\u00e1 umo\u017e\u0148uje rychl\u00e9 proveden\u00ed t\u0159\u00ed operac\u00ed. <\/p>\n<p><\/p>\n<ul>\n<li>Prvn\u00ed operac\u00ed je z\u00e1pis <code>kl\u00ed\u010d-hodnota<\/code> do t\u00e9to datab\u00e1ze. To d\u011bl\u00e1 velmi rychle, kde <code>kl\u00ed\u010d-hodnota<\/code> \u2013 jsou libovoln\u00e9 \u0159et\u011bzce. <\/li>\n<li>Druhou operac\u00ed je rychl\u00e9 vyhled\u00e1n\u00ed hodnoty podle zadan\u00e9ho kl\u00ed\u010de.<\/li>\n<li>A t\u0159et\u00ed operac\u00ed je rychl\u00e9 vyhled\u00e1n\u00ed v\u0161ech hodnot podle dan\u00e9ho prefixu. <\/li>\n<\/ul>\n<p><\/p>\n<p>LevelDB a RocksDB \u2013 tyto datab\u00e1ze byly vyvinuty ve firm\u00e1ch Google a Facebook. Nejprve se objevila LevelDB. Pot\u00e9 si lid\u00e9 z Facebooku vzali LevelDB a za\u010dali ji vylep\u0161ovat, \u010d\u00edm\u017e vytvo\u0159ili RocksDB. V sou\u010dasnosti v Facebooku na RocksDB funguj\u00ed t\u00e9m\u011b\u0159 v\u0161echny intern\u00ed datab\u00e1ze, v\u010detn\u011b toho, \u017ee p\u0159enesli MySQL na RocksDB. Nazvali to <noindex><a rel=\"nofollow\" href=\"http:\/\/myrocks.io\/\">MyRocks<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Inverzn\u00ed index lze implementovat pomoc\u00ed LevelDB. Jak to ud\u011blat? Ukl\u00e1d\u00e1me jako kl\u00ed\u010d <code>label=value<\/code>. A jako hodnotu \u2013 identifik\u00e1tor \u010dasov\u00e9ho \u0159ady, kde existuje p\u00e1r <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p>Pokud m\u00e1me mnoho \u010dasov\u00fdch \u0159ad s t\u00edmto p\u00e1rem <code>label=value<\/code>, bude v t\u00e9to datab\u00e1zi mnoho \u0159\u00e1dk\u016f se stejn\u00fdm kl\u00ed\u010dem a r\u016fzn\u00fdmi <code>timeseries_ids<\/code>. Abychom z\u00edskali seznam v\u0161ech <code>timeseries_ids<\/code>, kter\u00e9 za\u010d\u00ednaj\u00ed dan\u00fdm <code>label=prefix<\/code>, prov\u00e1d\u00edme range scan, pro kter\u00fd je tato datab\u00e1ze optimalizov\u00e1na. T. j. vyb\u00edr\u00e1me v\u0161echny \u0159\u00e1dky, kter\u00e9 za\u010d\u00ednaj\u00ed s <code>label=prefix<\/code> a z\u00edsk\u00e1v\u00e1me pot\u0159ebn\u00e9 <code>timeseries_ids<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/a40877ecb758ac3bc1979bcd568d7e83.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tady je p\u0159\u00edkladn\u00e1 implementace, jak by vypadala v Go. M\u00e1me inverzn\u00ed index. Je to LevelDB.<\/p>\n<p><\/p>\n<p>Funkce je stejn\u00e1 jako pro naivn\u00ed implementaci. T\u00e9m\u011b\u0159 se \u0159\u00e1dek po \u0159\u00e1dku opakuje naivn\u00ed implementaci. Jedin\u00fd okam\u017eik je, \u017ee m\u00edsto p\u0159\u00edstupu k <code>mapa<\/code> se dost\u00e1v\u00e1me k inverzn\u00edmu indexu. Z\u00edsk\u00e1v\u00e1me v\u0161echna hodnoty pro prvn\u00ed <code>label=value<\/code>. Pot\u00e9 proch\u00e1z\u00edme v\u0161emi zb\u00fdvaj\u00edc\u00edmi p\u00e1ry <code>label=value<\/code> a z\u00edsk\u00e1v\u00e1me odpov\u00eddaj\u00edc\u00ed sady metricIDs pro n\u011b. Pot\u00e9 nal\u00e9z\u00e1me pr\u016fnik. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/de11b15286816ada04b22727ff78e43d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vypad\u00e1 to dob\u0159e, ale v tomto \u0159e\u0161en\u00ed jsou nedostatky. VictoriaMetrics zpo\u010d\u00e1tku implementovala inverzn\u00ed index na z\u00e1klad\u011b LevelDB. Ale nakonec od toho musela upustit.<\/p>\n<p><\/p>\n<p>Pro\u010d? Proto\u017ee LevelDB je pomalej\u0161\u00ed ne\u017e naivn\u00ed implementace. V naivn\u00ed implementaci podle zadan\u00e9ho kl\u00ed\u010de okam\u017eit\u011b z\u00edsk\u00e1v\u00e1me cel\u00fd slice. <code>metricIDs<\/code>Tato velmi rychl\u00e1 operace \u2013 cel\u00fd slice je p\u0159ipraven k pou\u017eit\u00ed.<\/p>\n<p><\/p>\n<p>V LevelDB se p\u0159i ka\u017ed\u00e9m zavol\u00e1n\u00ed funkce <code>GetValues<\/code> mus\u00ed proj\u00edt v\u0161emi \u0159\u00e1dky, kter\u00e9 za\u010d\u00ednaj\u00ed na <code>label=value<\/code>. A pro ka\u017ed\u00fd \u0159\u00e1dek z\u00edskat hodnotu <code>timeseries_ids<\/code>. Z takov\u00fdch <code>timeseries_ids<\/code> sestavit slice t\u011bchto <code>timeseries_ids<\/code>. Je z\u0159ejm\u00e9, \u017ee to je mnohem pomalej\u0161\u00ed ne\u017e jednoduch\u00fd p\u0159\u00edstup k b\u011b\u017en\u00e9 map\u011b podle kl\u00ed\u010de.<\/p>\n<p><\/p>\n<p>Druhou nev\u00fdhodou je, \u017ee LevelDB je naps\u00e1n v C. P\u0159\u00edstup k C-funkc\u00edm z Go nen\u00ed p\u0159\u00edli\u0161 rychl\u00fd. Z\u00edsk\u00e1v\u00e1 to stovky nanosekund. To nen\u00ed p\u0159\u00edli\u0161 rychl\u00e9, proto\u017ee ve srovn\u00e1n\u00ed s b\u011b\u017en\u00fdm vol\u00e1n\u00edm funkce napsan\u00e9 v go, kter\u00e1 zabere 1-5 nanosekund, je rozd\u00edl v v\u00fdkonu desetin\u00e1sobn\u00fd. Pro VictoriaMetrics to byla fat\u00e1ln\u00ed nev\u00fdhoda \ud83d\ude42<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/47cace825807b7b062064c2e790dc9d3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Proto jsem napsal vlastn\u00ed implementaci inverzn\u00edho indexu. A nazval jsem ji <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\/tree\/master\/lib\/mergeset\">mergeset<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>Mergeset je postaven na datov\u00e9 struktu\u0159e MergeTree. Tato datov\u00e1 struktura byla p\u0159evzata z ClickHouse. Je jasn\u00e9, \u017ee mergeset by m\u011bl b\u00fdt optimalizov\u00e1n pro rychl\u00e9 vyhled\u00e1v\u00e1n\u00ed <code>timeseries_ids<\/code> podle zadan\u00e9ho kl\u00ed\u010de. Mergeset je naps\u00e1n kompletn\u011b v Go. M\u016f\u017eete se pod\u00edvat na <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\">zdrojov\u00e9 k\u00f3dy VictoriaMetrics na GitHubu<\/a><\/noindex>. Implementace mergeset le\u017e\u00ed v adres\u00e1\u0159i <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\/tree\/master\/lib\/mergeset\">\/lib\/mergeset<\/a><\/noindex>. M\u016f\u017eete se pokusit pochopit, co se tam d\u011bje.<\/p>\n<p><\/p>\n<p>API mergeset je velmi podobn\u00e9 LevelDB a RocksDB. To znamen\u00e1, \u017ee umo\u017e\u0148uje rychle ulo\u017eit nov\u00e9 z\u00e1znamy a rychle vyb\u00edrat z\u00e1znamy podle zadan\u00e9ho prefixu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/845704ed36f70beb468907d22701af59.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>O nev\u00fdhod\u00e1ch mergeset si popov\u00edd\u00e1me pozd\u011bji. Te\u010f se posu\u0148me k probl\u00e9m\u016fm, kter\u00e9 vznikly s VictoriaMetrics v produkci p\u0159i implementaci inverzn\u00edho indexu.<\/p>\n<p><\/p>\n<p>Pro\u010d vznikly?<\/p>\n<p><\/p>\n<p>Prvn\u00ed d\u016fvod \u2013 to je vysok\u00e1 m\u00edra fluktuace. V p\u0159ekladu do \u010de\u0161tiny \u2013 to je \u010dast\u00e1 zm\u011bna \u010dasov\u00fdch \u0159ad. To je, kdy\u017e \u010dasov\u00e1 \u0159ada kon\u010d\u00ed a za\u010d\u00edn\u00e1 nov\u00e1 \u0159ada, nebo za\u010d\u00edn\u00e1 mnoho nov\u00fdch \u010dasov\u00fdch \u0159ad. A to se d\u011bje \u010dasto.<\/p>\n<p><\/p>\n<p>Druh\u00fd d\u016fvod \u2013 to je velk\u00e9 mno\u017estv\u00ed \u010dasov\u00fdch \u0159ad. Na za\u010d\u00e1tku, kdy\u017e monitoring nab\u00edral popularitu, bylo mno\u017estv\u00ed \u010dasov\u00fdch \u0159ad mal\u00e9. Nap\u0159\u00edklad na ka\u017ed\u00fd po\u010d\u00edta\u010d je t\u0159eba monitorovat z\u00e1t\u011b\u017e procesoru, pam\u011bti, s\u00edt\u011b a disku. 4 \u010dasov\u00e9 \u0159ady na ka\u017ed\u00fd po\u010d\u00edta\u010d. M\u00e1te, dejme tomu, 100 po\u010d\u00edta\u010d\u016f a 400 \u010dasov\u00fdch \u0159ad. To je velmi m\u00e1lo. <\/p>\n<p><\/p>\n<p>V pr\u016fb\u011bhu \u010dasu lid\u00e9 p\u0159i\u0161li na to, \u017ee je mo\u017en\u00e9 m\u011b\u0159it podrobn\u011bj\u0161\u00ed informace. Nap\u0159\u00edklad m\u011b\u0159it z\u00e1t\u011b\u017e nejen cel\u00e9ho procesoru, ale jednotliv\u011b ka\u017ed\u00e9ho procesorov\u00e9ho j\u00e1dra. Pokud m\u00e1te 40 procesorov\u00fdch jader, m\u00e1te tedy 40kr\u00e1t v\u00edce \u010dasov\u00fdch \u0159ad pro m\u011b\u0159en\u00ed z\u00e1t\u011b\u017ee procesoru. <\/p>\n<p><\/p>\n<p>Ale to nen\u00ed v\u0161echno. Ka\u017ed\u00e9 procesorov\u00e9 j\u00e1dro m\u016f\u017ee m\u00edt n\u011bkolik stav\u016f, jako je idle, kdy\u017e nepracuje. Tak\u00e9 m\u016f\u017ee pracovat ve space u\u017eivatele, v kernel space a dal\u0161\u00ed stavy. A ka\u017ed\u00fd takov\u00fd stav lze tak\u00e9 m\u011b\u0159it jako samostatnou \u010dasovou \u0159adu. To nav\u00edc zvy\u0161uje po\u010det \u0159ad 7-8kr\u00e1t.<\/p>\n<p><\/p>\n<p>Z jedn\u00e9 metriky m\u00e1me 40 x 8 = 320 metrik pouze pro jeden po\u010d\u00edta\u010d. N\u00e1sob\u00edme 100 a dost\u00e1v\u00e1me 32 000 m\u00edsto 400. <\/p>\n<p><\/p>\n<p>Pak p\u0159i\u0161el Kubernetes. A v\u0161echno se je\u0161t\u011b zhor\u0161ilo, proto\u017ee v Kubernetes m\u016f\u017ee b\u011b\u017eet mnoho r\u016fzn\u00fdch slu\u017eeb. Ka\u017ed\u00e1 slu\u017eba v Kubernetes se skl\u00e1d\u00e1 z mnoha pod\u016f. A to v\u0161e je pot\u0159eba monitorovat. Krom\u011b toho m\u00e1me neust\u00e1l\u00e9 nasazov\u00e1n\u00ed nov\u00fdch verz\u00ed va\u0161ich slu\u017eeb. Pro ka\u017edou novou verzi je t\u0159eba vytv\u00e1\u0159et nov\u00e9 \u010dasov\u00e9 \u0159ady. Nakonec se po\u010det \u010dasov\u00fdch \u0159ad exponenci\u00e1ln\u011b zvy\u0161uje a setk\u00e1v\u00e1me se s probl\u00e9mem velk\u00e9ho po\u010dtu \u010dasov\u00fdch \u0159ad, kter\u00fd se naz\u00fdv\u00e1 high-cardinality. VictoriaMetrics si s t\u00edmto probl\u00e9mem \u00fasp\u011b\u0161n\u011b porad\u00ed ve srovn\u00e1n\u00ed s jin\u00fdmi datab\u00e1zemi pro \u010dasov\u00e9 \u0159ady. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/c11b7ce6d3294ae420243f72636af4b9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pod\u00edvejme se podrobn\u011bji na vysokou m\u00edru obm\u016fny (high churn rate). Pro\u010d se na produkci objevuje vysok\u00e1 m\u00edra obm\u016fny? Proto\u017ee n\u011bkter\u00e9 hodnoty \u0161t\u00edtk\u016f a tag\u016f se neust\u00e1le m\u011bn\u00ed.<\/p>\n<p><\/p>\n<p>Nap\u0159\u00edklad vezmeme Kubernetes, ve kter\u00e9m existuje pojem <code>deployment<\/code>, tj. kdy\u017e se uvoln\u00ed nov\u00e1 verze va\u0161\u00ed aplikace. V\u00fdvoj\u00e1\u0159i Kubernetes se rozhodli p\u0159idat id deploymentu do labelu.<\/p>\n<p><\/p>\n<p>K \u010demu to vedlo? K tomu, \u017ee p\u0159i ka\u017ed\u00e9m nov\u00e9m deploymentu v\u0161echny star\u00e9 \u010dasov\u00e9 \u0159ady p\u0159eru\u0161\u00edme a m\u00edsto toho za\u010d\u00edn\u00e1me nov\u00e9 \u010dasov\u00e9 \u0159ady s novou hodnotou labelu. <code>deployment_id<\/code>. Takov\u00fdch \u0159ad m\u016f\u017ee b\u00fdt stovky tis\u00edc a dokonce i miliony.<\/p>\n<p><\/p>\n<p>D\u016fle\u017eit\u00fdm rysem tohoto v\u0161eho je to, \u017ee celkov\u00e9 mno\u017estv\u00ed \u010dasov\u00fdch \u0159ad roste, ale po\u010det \u010dasov\u00fdch \u0159ad, kter\u00e9 jsou moment\u00e1ln\u011b aktivn\u00ed, na kter\u00e9 p\u0159ich\u00e1zej\u00ed data, z\u016fst\u00e1v\u00e1 konstantn\u00ed. Tento stav se naz\u00fdv\u00e1 \u2013 vysok\u00e1 m\u00edra obm\u016fny.<\/p>\n<p><\/p>\n<p>Hlavn\u00edm probl\u00e9mem vysok\u00e9 m\u00edry odchodu z\u00e1kazn\u00edk\u016f je zajistit st\u00e1lou rychlost vyhled\u00e1v\u00e1n\u00ed v\u0161ech \u010dasov\u00fdch \u0159ad podle dan\u00e9 sady \u0161t\u00edtk\u016f za ur\u010dit\u00e9 \u010dasov\u00e9 obdob\u00ed. Obvykle se jedn\u00e1 o \u010dasov\u00fd interval za posledn\u00ed hodinu nebo za posledn\u00ed den. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/ac18482b87cc37624d163b30c68cf7be.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak tento probl\u00e9m vy\u0159e\u0161it? Prvn\u00ed mo\u017enost\u00ed je rozd\u011blit invertovan\u00fd index na nez\u00e1visl\u00e9 \u010d\u00e1sti podle \u010dasu. Tedy, uplyne n\u011bjak\u00fd \u010dasov\u00fd interval, dokon\u010d\u00edme pr\u00e1ci s aktu\u00e1ln\u00edm invertovan\u00fdm indexem. A vytvo\u0159\u00edme nov\u00fd invertovan\u00fd index. Pot\u00e9 uplyne dal\u0161\u00ed \u010dasov\u00fd interval, vytvo\u0159\u00edme dal\u0161\u00ed a dal\u0161\u00ed. <\/p>\n<p><\/p>\n<p>A p\u0159i dotazov\u00e1n\u00ed na tyto invertovan\u00e9 indexy najdeme sadu invertovan\u00fdch index\u016f, kter\u00e9 spadaj\u00ed do zadan\u00e9ho intervalu. A odpov\u00eddaj\u00edc\u00edm zp\u016fsobem vybereme id \u010dasov\u00fdch \u0159ad. <\/p>\n<p><\/p>\n<p>To umo\u017e\u0148uje \u0161et\u0159it zdroje, proto\u017ee nemus\u00edme proch\u00e1zet \u010d\u00e1sti, kter\u00e9 nespadaj\u00ed do zadan\u00e9ho intervalu. Tedy obvykle, pokud vyb\u00edr\u00e1me data za posledn\u00ed hodinu, dotazy na p\u0159edchoz\u00ed \u010dasov\u00e9 intervaly p\u0159esko\u010d\u00edme. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/1afa3a88caa7423941ae3494b9cec706.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Existuje tak\u00e9 dal\u0161\u00ed mo\u017enost \u0159e\u0161en\u00ed tohoto probl\u00e9mu. A to uchov\u00e1vat pro ka\u017ed\u00fd den samostatn\u00fd seznam id \u010dasov\u00fdch \u0159ad, kter\u00e9 se v dan\u00fd den vyskytly.<\/p>\n<p><\/p>\n<p>V\u00fdhodou tohoto \u0159e\u0161en\u00ed oproti p\u0159edchoz\u00edmu \u0159e\u0161en\u00ed je, \u017ee neduplikuje informace o \u010dasov\u00fdch \u0159ad\u00e1ch, kter\u00e9 s \u010dasem nezmiz\u00ed. Tyto \u010dasov\u00e9 \u0159ady st\u00e1le existuj\u00ed a nem\u011bn\u00ed se. <\/p>\n<p><\/p>\n<p>Nev\u00fdhodou je, \u017ee takov\u00e9 \u0159e\u0161en\u00ed je slo\u017eit\u011bj\u0161\u00ed na implementaci a debuggov\u00e1n\u00ed. A VictoriaMetrics si zvolila toto \u0159e\u0161en\u00ed. Ov\u011b\u0159ilo se historicky. Toto \u0159e\u0161en\u00ed se tak\u00e9 jev\u00ed jako docela dobr\u00e9 ve srovn\u00e1n\u00ed s p\u0159edchoz\u00edm. Proto\u017ee toto \u0159e\u0161en\u00ed nebylo implementov\u00e1no kv\u016fli nutnosti duplikovat data v ka\u017ed\u00e9 partition pro \u010dasov\u00e9 \u0159ady, kter\u00e9 se nem\u011bn\u00ed, t.j. kter\u00e9 s \u010dasem nezmiz\u00ed. VictoriaMetrics byla prim\u00e1rn\u011b optimalizov\u00e1na na spot\u0159ebu diskov\u00e9ho prostoru a p\u0159edchoz\u00ed implementace zhor\u0161ovala spot\u0159ebu tohoto prostoru. Toto \u0159e\u0161en\u00ed je tedy l\u00e9pe p\u0159izp\u016fsobeno minimalizaci spot\u0159eby diskov\u00e9ho prostoru, a proto bylo zvoleno. <\/p>\n<p><\/p>\n<p>Museli jsme se s t\u00edm pot\u00fdkat. Boj spo\u010d\u00edval v tom, \u017ee v t\u00e9to implementaci je t\u0159eba st\u00e1le vyb\u00edrat mnohem v\u011bt\u0161\u00ed mno\u017estv\u00ed <code>timeseries_ids<\/code> pro data, ne\u017e kdy\u017e je invertovan\u00fd index rozd\u011blen podle \u010dasu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/5b10e61aaa803428ed3bfe31815f09d3.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak jsme tento probl\u00e9m vy\u0159e\u0161ili? Vy\u0159e\u0161ili jsme ho origin\u00e1ln\u00edm zp\u016fsobem \u2013 ulo\u017een\u00edm n\u011bkolika identifik\u00e1tor\u016f \u010dasov\u00fdch \u0159ad v ka\u017ed\u00e9m z\u00e1znamu inverzn\u00edho indexu m\u00edsto jednoho identifik\u00e1toru. T. j. m\u00e1me kl\u00ed\u010d <code>label=value<\/code>, kter\u00fd se vyskytuje v ka\u017ed\u00e9 \u010dasov\u00e9 \u0159ad\u011b. A nyn\u00ed ukl\u00e1d\u00e1me n\u011bkolik <code>timeseries_ids<\/code> v jednom z\u00e1znamu.<\/p>\n<p><\/p>\n<p>Zde je p\u0159\u00edklad. D\u0159\u00edve jsme m\u011bli N z\u00e1znam\u016f, a nyn\u00ed m\u00e1me jeden z\u00e1znam, jeho\u017e prefix je stejn\u00fd jako u v\u0161ech ostatn\u00edch. P\u0159edchoz\u00ed z\u00e1znam obsahoval v\u0161echny id \u010dasov\u00fdch \u0159ad. <\/p>\n<p><\/p>\n<p>To umo\u017enilo zv\u00fd\u0161it rychlost skenov\u00e1n\u00ed takov\u00e9ho inverzn\u00edho indexu a\u017e 10kr\u00e1t. A sn\u00ed\u017eit spot\u0159ebu pam\u011bti pro cache, proto\u017ee nyn\u00ed ukl\u00e1d\u00e1me \u0159et\u011bzec <code>label=value<\/code> pouze jednou v cache m\u00edsto N kr\u00e1t. A tento \u0159et\u011bzec m\u016f\u017ee b\u00fdt velk\u00fd, pokud jsou v tag\u00edch a \u0161t\u00edtc\u00edch ulo\u017eeny dlouh\u00e9 \u0159et\u011bzce, kter\u00e9 tam r\u00e1d vkl\u00e1d\u00e1 Kubernetes.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/ae4f38a440203bad2d03cf2abd1faafe.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dal\u0161\u00ed mo\u017enost\u00ed, jak urychlit vyhled\u00e1v\u00e1n\u00ed v inverzn\u00edm indexu, je shardov\u00e1n\u00ed. Vytvo\u0159en\u00ed n\u011bkolika inverzn\u00edch index\u016f m\u00edsto jednoho a shardov\u00e1n\u00ed dat mezi nimi podle kl\u00ed\u010de. To je soubor <code>key=value<\/code> p\u00e1r\u016f. T. j. m\u00e1me n\u011bkolik nez\u00e1visl\u00fdch inverzn\u00edch index\u016f, kter\u00e9 m\u016f\u017eeme dotazovat paraleln\u011b na n\u011bkolika procesorech. P\u0159edchoz\u00ed implementace umo\u017e\u0148ovaly pracovat pouze v jednoprocesorov\u00e9m re\u017eimu, t. j. skenovat data pouze na jednom j\u00e1d\u0159e. Toto \u0159e\u0161en\u00ed umo\u017e\u0148uje skenovat data najednou na n\u011bkolika j\u00e1drech, jak to r\u00e1d d\u011bl\u00e1 ClickHouse. To pl\u00e1nujeme realizovat.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/5ced6446efbf8ded8d7fb91694a999b0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A nyn\u00ed se vra\u0165me k na\u0161im ovc\u00edm \u2013 k funkci pr\u016fniku <code>timeseries_ids<\/code>. Pod\u00edvejme se, jak\u00e9 mohou b\u00fdt implementace. Tato funkce umo\u017e\u0148uje naj\u00edt <code>timeseries_ids<\/code> pro danou sadu <code>label=value<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/073a155018a91120c6996c324772f9af.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prvn\u00ed mo\u017enost \u2013 to je naivn\u00ed implementace. Dva vno\u0159en\u00e9 cykly. Takto dost\u00e1v\u00e1me na vstupu funkce <code>intersectInts<\/code> dv\u011b slices \u2014 <code>a<\/code> a <code>b<\/code>. Na v\u00fdstupu by n\u00e1m m\u011bla vr\u00e1tit pr\u016fnik t\u011bchto slices.<\/p>\n<p><\/p>\n<p>Naivn\u00ed implementace vypad\u00e1 takto. Proch\u00e1z\u00edme v\u0161echny hodnoty z slice <code>a<\/code>, uvnit\u0159 tohoto cyklu proch\u00e1z\u00edme v\u0161echny hodnoty slice <code>b<\/code>. A porovn\u00e1v\u00e1me je. Pokud se shoduj\u00ed, na\u0161li jsme pr\u016fnik. A ukl\u00e1d\u00e1me ho do <code>result<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/b89dcbb4f6d73377f9cf4f50169d6dd7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 jsou nev\u00fdhody? Kvadratick\u00e1 slo\u017eitost \u2013 to je jej\u00ed hlavn\u00ed nev\u00fdhoda. Nap\u0159\u00edklad, pokud m\u00e1te velikosti slice <code>a<\/code> a <code>b<\/code> Pokud je to jeden milion, tato funkce v\u00e1m nikdy nevr\u00e1t\u00ed odpov\u011b\u010f. Proto\u017ee bude muset prov\u00e9st jeden bilion iterac\u00ed, co\u017e je velmi hodn\u011b i pro dne\u0161n\u00ed po\u010d\u00edta\u010de.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/bad26b0092a2fd7fc813bcb79a9138ce.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Druh\u00e1 implementace je zalo\u017eena na map\u011b. Vytv\u00e1\u0159\u00edme mapu. Do t\u00e9to mapy vkl\u00e1d\u00e1me v\u0161echny hodnoty z \u0159ez\u016f <code>a<\/code>. Pot\u00e9 proch\u00e1z\u00edme jednotliv\u00fdm cyklem po \u0159ez\u00edch <code>b<\/code>. A kontrolujeme, zda se tato hodnota z \u0159ez\u016f <code>b<\/code> nach\u00e1z\u00ed v map\u011b. Pokud ano, p\u0159id\u00e1me ji do v\u00fdsledku. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/1e610acf641a9cfe4c80aac1fe26044c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Jak\u00e9 jsou v\u00fdhody? V\u00fdhodou je, \u017ee zde je pouze line\u00e1rn\u00ed slo\u017eitost. Tedy funkce se pro velk\u00e9 velikosti \u0159ez\u016f vykon\u00e1 mnohem rychleji. Pro \u0159ez s milionovou velikost\u00ed se tato funkce provede za 2 miliony iterac\u00ed, na rozd\u00edl od bilionu iterac\u00ed, jako v p\u0159edchoz\u00ed funkci.<\/p>\n<p><\/p>\n<p>Nev\u00fdhodou je, \u017ee tato funkce vy\u017eaduje v\u00edce pam\u011bti k vytvo\u0159en\u00ed t\u00e9to mapy.<\/p>\n<p><\/p>\n<p>Druh\u00e1 nev\u00fdhoda je velk\u00fd overhead na hashov\u00e1n\u00ed. Tato nev\u00fdhoda nen\u00ed nijak z\u0159ejm\u00e1. A pro n\u00e1s to tak\u00e9 nebylo p\u0159\u00edli\u0161 z\u0159ejm\u00e9, proto zpo\u010d\u00e1tku v VictoriaMetrics implementace pr\u016fse\u010d\u00edku byla p\u0159es mapu. Ale pot\u00e9 profilov\u00e1n\u00ed uk\u00e1zalo, \u017ee v\u011bt\u0161ina procesorov\u00e9ho \u010dasu se str\u00e1v\u00ed zapisov\u00e1n\u00edm do mapy a kontrolou existence hodnoty v t\u00e9to map\u011b.<\/p>\n<p><\/p>\n<p>Pro\u010d se v t\u011bchto m\u00edstech str\u00e1c\u00ed procesorov\u00fd \u010das? Proto\u017ee v t\u011bchto \u0159\u00e1dc\u00edch Go prov\u00e1d\u00ed hashovac\u00ed operaci. Tedy po\u010d\u00edt\u00e1 hash kl\u00ed\u010de, aby se nahl\u00e9dlo do zadan\u00e9ho indexu v HashMap\u011b. Operace v\u00fdpo\u010dtu hashe se prov\u00e1d\u00ed za des\u00edtky nanosekund. To je pomal\u00e9 pro VictoriaMetrics.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/969f10d875d88998e958894ca28b1181.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Rozhodl jsem se implementovat bitset, optimalizovan\u00fd speci\u00e1ln\u011b pro tento p\u0159\u00edpad. Takto nyn\u00ed vypad\u00e1 pr\u016fse\u010d\u00edk dvou \u0159ez\u016f. Tady vytv\u00e1\u0159\u00edme bitset. P\u0159id\u00e1v\u00e1me do n\u011bj prvky z prvn\u00edho \u0159ezu. Pot\u00e9 kontrolujeme p\u0159\u00edtomnost t\u011bchto prvk\u016f ve druh\u00e9m \u0159ezu. A p\u0159id\u00e1v\u00e1me je do v\u00fdsledku. Tedy se to t\u00e9m\u011b\u0159 neli\u0161\u00ed od p\u0159edchoz\u00edho p\u0159\u00edkladu. Jedin\u00e1 v\u011bc, kterou jsme zde nahradili, je vol\u00e1n\u00ed vlastn\u00edch funkc\u00ed m\u00edsto p\u0159\u00edstupu k map\u011b. <code>add<\/code> a <code>has<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/b4ec0753d30d9684868a031f605632c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Na prvn\u00ed pohled se zd\u00e1, \u017ee by to m\u011blo fungovat pomaleji, pokud byla d\u0159\u00edve pou\u017eita standardn\u00ed mapa, a tady se volaj\u00ed n\u011bjak\u00e9 funkce, ale profilov\u00e1n\u00ed ukazuje, \u017ee tato v\u011bc funguje desetkr\u00e1t rychleji ne\u017e standardn\u00ed mapa pro p\u0159\u00edpad s VictoriaMetrics.<\/p>\n<p><\/p>\n<p>Krom\u011b toho pou\u017e\u00edv\u00e1 mnohem m\u00e9n\u011b pam\u011bti ve srovn\u00e1n\u00ed s implementac\u00ed pomoc\u00ed mapy. Proto\u017ee zde uchov\u00e1v\u00e1me bity m\u00edsto osmibitov\u00fdch hodnot.<\/p>\n<p><\/p>\n<p>Nev\u00fdhodou t\u00e9to implementace je, \u017ee nen\u00ed tak z\u0159ejm\u00e1 a nep\u016fsob\u00ed trivi\u00e1ln\u011b. <\/p>\n<p><\/p>\n<p>Dal\u0161\u00ed nev\u00fdhodou, kter\u00e9 si mnoz\u00ed nemus\u00ed v\u0161imnout, je, \u017ee tato implementace m\u016f\u017ee v n\u011bkter\u00fdch p\u0159\u00edpadech pracovat \u0161patn\u011b. Tedy je optimalizov\u00e1na pro konkr\u00e9tn\u00ed p\u0159\u00edpad, pro tento p\u0159\u00edpad pr\u016fniku ids \u010dasov\u00fdch \u0159ad ve VictoriaMetrics. Neznamen\u00e1 to, \u017ee bude fungovat ve v\u0161ech situac\u00edch. Pokud ji pou\u017eijete nespr\u00e1vn\u011b, nedos\u00e1hnete n\u00e1r\u016fstu v\u00fdkonu, ale dojde k chyb\u011b out of memory a zpomalen\u00ed v\u00fdkonu. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/94bd174afe43e67b3cf279dc7a1be17c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pod\u00edvejme se na implementaci t\u00e9to struktury. Pokud chcete, najdete ji v zdrojov\u00fdch k\u00f3dech VictoriaMetrics, ve slo\u017ece <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\/tree\/master\/lib\/uint64set\">lib\/uint64set<\/a><\/noindex>. Je optimalizov\u00e1na pr\u00e1v\u011b pro p\u0159\u00edpad VictoriaMetrics, kde <code>timeseries_id<\/code> p\u0159edstavuje 64bitovou hodnotu, kde prvn\u00edch 32 bit\u016f je v\u011bt\u0161inou konstantn\u00edch a m\u011bn\u00ed se pouze posledn\u00edch 32 bit\u016f.<\/p>\n<p><\/p>\n<p>Tato datov\u00e1 struktura nen\u00ed ukl\u00e1d\u00e1na na disku, pracuje pouze v pam\u011bti. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/e24ca65f860e2b04037e073f7acae0c1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Zde je jej\u00ed API. Nen\u00ed p\u0159\u00edli\u0161 slo\u017eit\u00e9. API je upraveno p\u0159esn\u011b pro konkr\u00e9tn\u00ed p\u0159\u00edklad pou\u017eit\u00ed VictoriaMetrics. Tedy zde nejsou \u017e\u00e1dn\u00e9 zbyte\u010dn\u00e9 funkce. Jsou zde funkce, kter\u00e9 jsou jasn\u011b pou\u017e\u00edv\u00e1ny VictoriaMetrics.<\/p>\n<p><\/p>\n<p>Existuje funkce <code>add<\/code>, kter\u00e1 p\u0159id\u00e1v\u00e1 nov\u00e9 hodnoty. Je zde funkce <code>has<\/code>, kter\u00e1 kontroluje nov\u00e9 hodnoty. A je zde funkce <code>del<\/code>, kter\u00e1 odstra\u0148uje hodnoty. Je zde pomocn\u00e1 funkce <code>len<\/code>, kter\u00e1 vrac\u00ed velikost mno\u017einy. Funkce <code>clone<\/code> klonuje mno\u017einu. A funkce <code>appendto<\/code> p\u0159ev\u00e1d\u00ed tuto mno\u017einu na slice. <code>timeseries_ids<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/874b04042d13f342d39f8f393e7fb78c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Takto vypad\u00e1 implementace t\u00e9to datov\u00e9 struktury. Ve setu jsou dva prvky:<\/p>\n<p><\/p>\n<ul>\n<li>\n<p><code>ItemsCount<\/code> \u2013 je to pomocn\u00e9 pole, kter\u00e9 rychle vrac\u00ed po\u010det prvk\u016f v setu. Bez tohoto pomocn\u00e9ho pole bychom se mohli obej\u00edt, ale museli jsme ho sem p\u0159idat, proto\u017ee VictoriaMetrics \u010dasto ve sv\u00fdch algoritmech dotazuje d\u00e9lku bitsetu.<\/p>\n<p>\n<\/li>\n<li>\n<p>Druh\u00e9 pole je <code>buckets<\/code>. Je to slice struktury <code>bucket32<\/code>. V ka\u017ed\u00e9 struktu\u0159e se ukl\u00e1d\u00e1 <code>hi<\/code> pole. To jsou horn\u00ed 32 bity. A dva slice \u2014 <code>b16his<\/code> a <code>buckets<\/code> z <code>bucket16<\/code> struktur. <\/p>\n<p>\n<\/li>\n<\/ul>\n<p><\/p>\n<p>Zde se ukl\u00e1daj\u00ed horn\u00ed 16 bity druh\u00e9 \u010d\u00e1sti 64bitov\u00e9 struktury. A zde se ukl\u00e1daj\u00ed bitsety pro doln\u00ed 16 bity ka\u017ed\u00e9ho bytu. <\/p>\n<p><\/p>\n<p><code>Bucket64<\/code> se skl\u00e1d\u00e1 z pole <code>uint64<\/code>. D\u00e9lka se po\u010d\u00edt\u00e1 pomoc\u00ed t\u011bchto konstant. V jednom <code>bucket16<\/code> m\u016f\u017ee maxim\u00e1ln\u011b b\u00fdt ulo\u017eeno <code>2^16=65536<\/code> bit\u016f. Pokud to vyd\u011bl\u00edte 8, z\u00edsk\u00e1te 8 kilobajt\u016f. Pokud to je\u0161t\u011b jednou vyd\u011bl\u00edte 8, dostanete 1000 <code>uint64<\/code> v hodnot\u00e1ch. Tedy, <code>Bucket16<\/code> \u2013 to je 8kilobajtov\u00e1 struktura. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/1cca4e6bfafa3408a3c95e0118e26d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pod\u00edv\u00e1me se na to, jak je implementov\u00e1na jedna z metod t\u00e9to struktury pro p\u0159id\u00e1n\u00ed nov\u00e9 hodnoty. <\/p>\n<p><\/p>\n<p>V\u0161echno za\u010d\u00edn\u00e1 s <code>uint64<\/code> hodnotou. Vypo\u010d\u00edt\u00e1me horn\u00edch 32 bit\u016f, vypo\u010d\u00edt\u00e1me doln\u00edch 32 bit\u016f. Proch\u00e1z\u00edme v\u0161echny <code>buckets<\/code>. Porovn\u00e1v\u00e1me horn\u00ed 32 bity v ka\u017ed\u00e9m bucketu s p\u0159id\u00e1vanou hodnotou. A pokud se shoduj\u00ed, zavol\u00e1me funkci <code>add<\/code> ve struktu\u0159e b32 <code>buckets<\/code>. A p\u0159id\u00e1v\u00e1me tam doln\u00edch 32 bit\u016f. A pokud to vr\u00e1tilo <code>true<\/code>, znamen\u00e1 to, \u017ee jsme tuto hodnotu p\u0159idali a nem\u011bli jsme ji. Pokud vr\u00e1t\u00ed <code>false<\/code>, takov\u00e1 hodnota ji\u017e existovala. Pot\u00e9 zv\u00fd\u0161\u00edme po\u010det prvk\u016f ve struktu\u0159e. <\/p>\n<p><\/p>\n<p>Pokud jsme nenalezli pot\u0159ebn\u00fd <code>bucket<\/code> s po\u017eadovanou hi-hodnotou, zavol\u00e1me funkci <code>addAlloc<\/code>, kter\u00e1 p\u0159id\u011bluje nov\u00fd <code>bucket<\/code>, p\u0159id\u00e1vaj\u00edc\u00ed ho do bucket-struktury.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/c5d1e5de767f47c7c40e01e12b6d0617.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Toto je implementace funkce <code>b32.add<\/code>. Je podobn\u00e1 p\u0159edchoz\u00ed implementaci. Vypo\u010d\u00edt\u00e1me horn\u00edch 16 bit\u016f, doln\u00edch 16 bit\u016f.<\/p>\n<p><\/p>\n<p>Pak proch\u00e1z\u00edme v\u0161echny horn\u00ed 16 bity. Hled\u00e1me shody. A p\u0159i shod\u011b vol\u00e1me metodu add, kterou probereme na dal\u0161\u00ed str\u00e1nce pro <code>bucket16<\/code>.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/e98c4ef316f3a894fd7019c3c85696f7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>A toto je nejni\u017e\u0161\u00ed \u00farove\u0148, kter\u00e1 by m\u011bla b\u00fdt maxim\u00e1ln\u011b optimalizov\u00e1na. Vypo\u010d\u00edt\u00e1me pro <code>uint64<\/code> id hodnotu v slice bit, a tak\u00e9 <code>bitmask<\/code>. Toto je maska pro danou 64-bitovou hodnotu, podle kter\u00e9 lze zkontrolovat p\u0159\u00edtomnost tohoto bitu nebo jej nastavit. Kontrolujeme p\u0159\u00edtomnost tohoto nastaven\u00e9ho bitu a nastavujeme ho a vrac\u00edme p\u0159\u00edtomnost. Tato implementace n\u00e1m umo\u017enila zrychlit operaci pr\u016fniku ids \u010dasov\u00fdch \u0159ad 10kr\u00e1t ve srovn\u00e1n\u00ed s b\u011b\u017en\u00fdmi maps.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/4dfa5a6142829a3551be22d6c9c3ab92.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ve VictoriaMetrics vedle t\u00e9to optimalizace existuje mnoho dal\u0161\u00edch optimalizac\u00ed. V\u011bt\u0161ina z t\u011bchto optimalizac\u00ed byla p\u0159id\u00e1na nejen tak, ale po profilov\u00e1n\u00ed k\u00f3du v produkci.<\/p>\n<p><\/p>\n<p>To je hlavn\u00ed pravidlo optimalizace \u2013 nep\u0159id\u00e1vat optimalizaci, pokud se domn\u00edv\u00e1te, \u017ee zde bude \u00fazk\u00e9 m\u00edsto, proto\u017ee se m\u016f\u017ee uk\u00e1zat, \u017ee tam \u00fazk\u00e9 m\u00edsto nebude. Optimalizace obvykle zhor\u0161uje kvalitu k\u00f3du. Proto je dobr\u00e9 optimalizovat pouze po profilov\u00e1n\u00ed a ide\u00e1ln\u011b v produkci, aby to byly re\u00e1ln\u00e1 data. Kdo m\u00e1 z\u00e1jem, m\u016f\u017ee se pod\u00edvat na zdrojov\u00e9 k\u00f3dy VictoriaMetrics a prozkoumat dal\u0161\u00ed optimalizace, kter\u00e9 tam jsou.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Optimalizace Go ve VictoriaMetrics. Alexandr Valjalkin\" src=\"\/wp-content\/uploads\/2020\/05\/7585c4dc782627bac5b649e6a55e2ffb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><em>M\u00e1m dotaz na bitset. Velmi to p\u0159ipom\u00edn\u00e1 implementaci C++ vector bool, optimalizovan\u00fd bitset. Odtud jste vzali implementaci?<\/em><\/p>\n<p><\/p>\n<p>Ne, to nen\u00ed ono. P\u0159i realizaci tohoto bitsetu jsem se \u0159\u00eddil znalost\u00ed struktury t\u011bchto ids time series, kter\u00e9 se pou\u017e\u00edvaj\u00ed ve VictoriaMetrics. Jejich struktura je takov\u00e1, \u017ee horn\u00edch 32 bit\u016f je v\u011bt\u0161inou konstantn\u00edch. Spodn\u00edch 32 bit\u016f se m\u016f\u017ee m\u011bnit. \u010c\u00edm ni\u017e\u0161\u00ed je bit, t\u00edm \u010dast\u011bji se m\u016f\u017ee m\u011bnit. Proto je tato realizace optimalizov\u00e1na p\u0159esn\u011b pro tuto datovou strukturu. C++ realizace, co v\u00edm, je optimalizov\u00e1na pro obecn\u00fd p\u0159\u00edpad. Pokud d\u011bl\u00e1te optimalizaci pro obecn\u00fd p\u0159\u00edpad, znamen\u00e1 to, \u017ee nebude nejoptim\u00e1ln\u011bj\u0161\u00ed pro konkr\u00e9tn\u00ed situaci.<\/p>\n<p><\/p>\n<p>Doporu\u010duji v\u00e1m tak\u00e9 se pod\u00edvat na p\u0159edn\u00e1\u0161ku Alexeje Milovida. P\u0159ed m\u011bs\u00edcem n\u011bkde hovo\u0159il o optimalizac\u00edch v ClickHouse pro konkr\u00e9tn\u00ed specializace. \u0158\u00edk\u00e1 pr\u00e1v\u011b, \u017ee C++ realizace nebo jin\u00e1 realizace jsou zac\u00edlen\u00e9 na dobr\u00e9 fungov\u00e1n\u00ed v pr\u016fm\u011bru. M\u016f\u017ee pracovat h\u016f\u0159e ne\u017e specializovan\u00e1 realizace pro konkr\u00e9tn\u00ed znalosti, jako u n\u00e1s, kdy v\u00edme, \u017ee horn\u00edch 32 bit\u016f je v\u011bt\u0161inou konstantn\u00edch.<\/p>\n<p><\/p>\n<p><em>M\u00e1m druhou ot\u00e1zku. Jak\u00fd je z\u00e1sadn\u00ed rozd\u00edl od InfluxDB?<\/em><\/p>\n<p><\/p>\n<p>Rozd\u00edl\u016f je mnoho. Pokud jde o v\u00fdkon a spot\u0159ebu pam\u011bti, InfluxDB v testech vykazuje 10kr\u00e1t vy\u0161\u0161\u00ed spot\u0159ebu pam\u011bti pro high cardinality \u010dasov\u00e9 \u0159ady, kdy\u017e jich m\u00e1te hodn\u011b, nap\u0159\u00edklad miliony. Nap\u0159\u00edklad VictoriaMetrics spot\u0159ebov\u00e1v\u00e1 1 GB na milion aktivn\u00edch \u0159ad\u016f, zat\u00edmco InfluxDB spot\u0159ebov\u00e1v\u00e1 10 GB. A to je velk\u00fd rozd\u00edl. <\/p>\n<p><\/p>\n<p>Druh\u00fd z\u00e1sadn\u00ed rozd\u00edl spo\u010d\u00edv\u00e1 v tom, \u017ee v InfluxDB jsou podivn\u00e9 dotazovac\u00ed jazyky \u2013 Flux a InfluxQL. Nen\u00ed to moc pohodln\u00e9 pro pr\u00e1ci s \u010dasov\u00fdmi \u0159adami v porovn\u00e1n\u00ed s <noindex><a rel=\"nofollow\" href=\"https:\/\/medium.com\/@valyala\/promql-tutorial-for-beginners-9ab455142085\">PromQL<\/a><\/noindex>, kter\u00fd je podporov\u00e1n ve VictoriaMetrics. PromQL je dotazovac\u00ed jazyk z Prometheus.<\/p>\n<p><\/p>\n<p>A je\u0161t\u011b jedno rozd\u00edl \u2013 InfluxDB m\u00e1 trochu zvl\u00e1\u0161tn\u00ed model dat, kde ka\u017ed\u00e9 \u0159\u00e1dce m\u016f\u017ee b\u00fdt ulo\u017eeno n\u011bkolik fields s r\u016fznou sadou tag\u016f. Tyto \u0159\u00e1dky jsou rozd\u011bleny do r\u016fzn\u00fdch tabulek. Tato dodate\u010dn\u00e1 slo\u017eitost zt\u011b\u017euje n\u00e1slednou pr\u00e1ci s touto datab\u00e1z\u00ed. Je obt\u00ed\u017en\u00e9 ji udr\u017eovat a rozum\u011bt j\u00ed.<\/p>\n<p><\/p>\n<p>Ve VictoriaMetrics je to mnohem jednodu\u0161\u0161\u00ed. Ka\u017ed\u00e1 \u010dasov\u00e1 \u0159ada p\u0159edstavuje kl\u00ed\u010d-hodnota. Hodnota je soubor bod\u016f \u2013 <code>(timestamp, value)<\/code>, a kl\u00ed\u010d je soubor <code>label=value<\/code>. Nen\u00ed \u017e\u00e1dn\u00e9 rozd\u011blen\u00ed na fields a measurements. To v\u00e1m umo\u017e\u0148uje vyb\u00edrat jak\u00e1koliv data a n\u00e1sledn\u011b je kombinovat, s\u010d\u00edtat, ode\u010d\u00edtat, n\u00e1sobit, d\u011blit, na rozd\u00edl od InfluxDB, kde jsou v\u00fdpo\u010dty mezi r\u016fzn\u00fdmi \u0159\u00e1dky st\u00e1le nerealizov\u00e1ny, pokud v\u00edm. I pokud by realizov\u00e1ny byly, je to slo\u017eit\u00e9, mus\u00edte napsat spoustu k\u00f3du. <\/p>\n<p><\/p>\n<p><em>M\u00e1m up\u0159es\u0148uj\u00edc\u00ed ot\u00e1zku. Spr\u00e1vn\u011b jsem pochopil, \u017ee do\u0161lo k n\u011bjak\u00e9mu probl\u00e9mu, o kter\u00e9m jste mluvili, \u017ee tento invertovan\u00fd index se nevejde do pam\u011bti, proto se tam prov\u00e1d\u00ed partitionaling?<\/em><\/p>\n<p><\/p>\n<p>Zpo\u010d\u00e1tku jsem uk\u00e1zal naivn\u00ed implementaci inverzn\u00edho indexu na standardn\u00ed map\u011b v Go. Takov\u00e1 implementace nen\u00ed vhodn\u00e1 pro datab\u00e1ze, proto\u017ee tento inverzn\u00ed index nen\u00ed ulo\u017een na disku, a datab\u00e1ze mus\u00ed ukl\u00e1dat na disk, aby byla data dostupn\u00e1 po restartu. V t\u00e9to implementaci p\u0159i restartu aplikace v\u00e1\u0161 inverzn\u00ed index zmiz\u00ed. A vy ztrat\u00edte p\u0159\u00edstup ke v\u0161em dat\u016fm, proto\u017ee je nebudete schopni naj\u00edt. <\/p>\n<p><\/p>\n<p><em>Dobr\u00fd den! D\u011bkuji za p\u0159edn\u00e1\u0161ku! Jmenuji se Pavel. Jsem z firmy Wildberries. M\u00e1m na v\u00e1s n\u011bkolik ot\u00e1zek. Prvn\u00ed ot\u00e1zka. Mysl\u00edte si, \u017ee kdybyste zvolili jin\u00fd princip p\u0159i stavb\u011b architektury sv\u00e9 aplikace a partitionovali data podle \u010dasu, mo\u017en\u00e1 byste mohli prov\u00e1d\u011bt pr\u016fnik dat p\u0159i hled\u00e1n\u00ed, zakl\u00e1daj\u00edc\u00ed se pouze na tom, \u017ee v jedn\u00e9 partition\u011b jsou \u00fadajena za jedno \u010dasov\u00e9 obdob\u00ed, tj. za jeden \u010dasov\u00fd interval, a nemuseli byste se starat o to, \u017ee m\u00e1te \u010d\u00e1sti r\u016fzn\u011b rozm\u00edst\u011bn\u00e9? Druh\u00e1 ot\u00e1zka \u2014 jeliko\u017e implementujete takov\u00fd algoritmus s bitsetem a v\u0161\u00edm ostatn\u00edm, mo\u017en\u00e1 jste zkusili pou\u017e\u00edvat instrukce procesoru? Mo\u017en\u00e1 jste zkusili takov\u00e9 optimalizace?<\/em><\/p>\n<p><\/p>\n<p>Na druhou ot\u00e1zku hned odpov\u00edm. K tomu jsme se zat\u00edm je\u0161t\u011b nedostali. Ale pokud bude pot\u0159eba, dostaneme se k tomu. A co byla prvn\u00ed ot\u00e1zka?<\/p>\n<p><\/p>\n<p><em>Diskutovali jste dva sc\u00e9n\u00e1\u0159e. A \u0159ekli jste, \u017ee jste zvolili druh\u00fd se slo\u017eit\u011bj\u0161\u00ed implementac\u00ed. A nep\u0159ednostili jste prvn\u00ed, kde jsou data partitionov\u00e1na podle \u010dasu.<\/em> <\/p>\n<p><\/p>\n<p>Ano. V prvn\u00edm p\u0159\u00edpad\u011b by byl celkov\u00fd objem indexu v\u011bt\u0161\u00ed, proto\u017ee v ka\u017ed\u00e9 partici bychom museli uchov\u00e1vat duplicitn\u00ed data pro tyto \u010dasov\u00e9 \u0159ady, kter\u00e9 pokra\u010duj\u00ed nap\u0159\u00ed\u010d v\u0161emi t\u011bmito partcemi. A pokud m\u00e1te malou m\u00edru odchodu \u010dasov\u00fdch \u0159ad, tj. st\u00e1le se pou\u017e\u00edvaj\u00ed stejn\u00e9 \u0159ady, v prvn\u00edm p\u0159\u00edpad\u011b bychom v\u00fdrazn\u011bji ztratili na objemu zabran\u00e9ho diskov\u00e9ho prostoru ve srovn\u00e1n\u00ed s druh\u00fdm p\u0159\u00edpadem.<\/p>\n<p><\/p>\n<p>Ano, partitioning podle \u010dasu je dobr\u00e1 volba. To pou\u017e\u00edv\u00e1 i Prometheus. Ale v Prometheu je dal\u0161\u00ed nev\u00fdhoda. P\u0159i slou\u010den\u00ed t\u011bchto kousk\u016f dat mus\u00ed dr\u017eet v pam\u011bt\u00ed meta-informace ke v\u0161em label\u016fm a \u010dasov\u00fdm \u0159ad\u00e1m. Proto, pokud jsou kousky dat velk\u00e9, kter\u00e9 slou\u010d\u00ed, pak spot\u0159eba pam\u011bti velmi roste p\u0159i slou\u010den\u00ed, na rozd\u00edl od VictoriaMetrics. P\u0159i slou\u010den\u00ed VictoriaMetrics v\u016fbec nepou\u017e\u00edv\u00e1 pam\u011b\u0165, tam se spot\u0159ebuj\u00ed jen n\u011bjak\u00e9 kilobajty, bez ohledu na velikosti slou\u010den\u00fdch kousk\u016f dat.<\/p>\n<p><\/p>\n<p><em>Algoritmus, kter\u00fd m\u00e1te pou\u017eit\u00fd, vyu\u017e\u00edv\u00e1 pam\u011b\u0165. V n\u00ed jsou ozna\u010deny timeseries \u0161t\u00edtky, na kter\u00fdch jsou hodnoty. A t\u00edmto zp\u016fsobem kontrolujete p\u0159\u00edtomnost v jednom datov\u00e9m poli a v druh\u00e9m. A ch\u00e1pete - do\u0161lo k pr\u016fse\u010d\u00edku nebo ne. Obvykle v datab\u00e1z\u00edch implementuj\u00ed kurzory, iter\u00e1tory, kter\u00e9 uchov\u00e1vaj\u00ed sv\u016fj aktu\u00e1ln\u00ed stav a proch\u00e1zej\u00ed se podle se\u0159azen\u00fdch dat d\u00edky \u010demu\u017e m\u00e1te jednoduchou slo\u017eitost u t\u011bchto operac\u00ed.<\/em> <\/p>\n<p><\/p>\n<p>Pro\u010d nepou\u017e\u00edv\u00e1me kurzory pro pr\u016fnik dat?<\/p>\n<p><\/p>\n<p><em>Ano.<\/em> <\/p>\n<p><\/p>\n<p>M\u00e1me v LevelDB nebo v mergesetu pr\u00e1v\u011b se\u0159azen\u00e9 \u0159\u00e1dky. M\u016f\u017eeme proj\u00edt kurzorem a naj\u00edt pr\u016fnik. A pro\u010d to nepou\u017e\u00edv\u00e1me? Proto\u017ee - to je pomal\u00e9. Proto\u017ee kurzory p\u0159edpokl\u00e1daj\u00ed, \u017ee na ka\u017ed\u00fd \u0159\u00e1dek mus\u00edte zavolat funkci. Zavol\u00e1n\u00ed funkce - to je 5 nanosekund. A pokud m\u00e1te 100 000 000 \u0159\u00e1dk\u016f, pak str\u00e1v\u00edme p\u016fl sekundy jen na vol\u00e1n\u00ed funkce.<\/p>\n<p><\/p>\n<p><em>Takov\u00e9 n\u011bco je, ano. A posledn\u00ed ot\u00e1zka. Ot\u00e1zka, kter\u00e1 m\u016f\u017ee zn\u00edt trochu zvl\u00e1\u0161tn\u011b. Pro\u010d p\u0159i p\u0159\u00edjmu dat nelze spo\u010d\u00edtat v\u0161echny pot\u0159ebn\u00e9 agreg\u00e1ty a ukl\u00e1dat je v pot\u0159ebn\u00e9 podob\u011b? Pro\u010d ukl\u00e1dat obrovsk\u00e9 objemy do n\u011bjak\u00fdch syst\u00e9m\u016f jako VictoriaMetrics, ClickHouse atd., a pak tr\u00e1vit spoustu \u010dasu na nich?<\/em><\/p>\n<p><\/p>\n<p><em>D\u00e1m p\u0159\u00edklad, aby to bylo jasn\u011bj\u0161\u00ed. P\u0159edstavte si, jak funguje mal\u00fd hra\u010dkov\u00fd rychlom\u011br? Zaznamen\u00e1v\u00e1 vzd\u00e1lenost, kterou jste urazili, a neust\u00e1le ji p\u0159id\u00e1v\u00e1 do jedn\u00e9 hodnoty, do druh\u00e9 \u2013 \u010das. A d\u011bl\u00ed. A dost\u00e1v\u00e1 pr\u016fm\u011brnou rychlost. M\u016f\u017eete d\u011blat n\u011bco podobn\u00e9ho. S\u010d\u00edtat \u201ena letu\u201c v\u0161echny pot\u0159ebn\u00e9 faktory.<\/em><\/p>\n<p><\/p>\n<p>Dob\u0159e, ch\u00e1pu ot\u00e1zku. V\u00e1\u0161 p\u0159\u00edklad m\u00e1 sv\u00e9 m\u00edsto. Pokud v\u00edte, jak\u00e9 agreg\u00e1ty pot\u0159ebujete, pak je to nejlep\u0161\u00ed realizace. Ale probl\u00e9m je v tom, \u017ee lid\u00e9 ukl\u00e1daj\u00ed tyto metriky, n\u011bjak\u00e1 data do ClickHouse a nev\u00ed je\u0161t\u011b, jak je v budoucnu budou agregovat, filtrovat, proto mus\u00ed ukl\u00e1dat v\u0161echny surov\u00e9 \u00fadaje. Ale pokud v\u00edte, \u017ee pot\u0159ebujete spo\u010d\u00edtat n\u011bco pr\u016fm\u011brn\u00e9ho, pro\u010d to nespo\u010d\u00edtat, m\u00edsto abyste tam ukl\u00e1dali hromadu surov\u00fdch hodnot? Ale to jen v p\u0159\u00edpad\u011b, \u017ee p\u0159esn\u011b v\u00edte, co pot\u0159ebujete.<\/p>\n<p><\/p>\n<p>Mimochodem, datab\u00e1ze pro ukl\u00e1d\u00e1n\u00ed \u010dasov\u00fdch \u0159ad podporuj\u00ed po\u010d\u00edt\u00e1n\u00ed agreg\u00e1t\u016f. Nap\u0159\u00edklad Prometheus podporuje <noindex><a rel=\"nofollow\" href=\"https:\/\/prometheus.io\/docs\/prometheus\/latest\/configuration\/recording_rules\/\">pravidla pro z\u00e1znam<\/a><\/noindex>. T. j. m\u016f\u017ee to b\u00fdt provedeno, pokud v\u00edte, jak\u00e9 agreg\u00e1ty budete pot\u0159ebovat. V VictoriaMetrics to zat\u00edm nen\u00ed, ale p\u0159ed n\u00ed se obvykle instaluje Prometheus, ve kter\u00e9m to lze ud\u011blat v pravidlech z\u00e1znamu.<\/p>\n<p><\/p>\n<p>Nap\u0159\u00edklad na p\u0159edchoz\u00ed pr\u00e1ci bylo pot\u0159eba po\u010d\u00edtat po\u010det ud\u00e1lost\u00ed v klouzav\u00e9m okn\u011b za posledn\u00ed hodinu. Probl\u00e9m byl v tom, \u017ee bylo nutn\u00e9 ud\u011blat vlastn\u00ed realizaci na Go, t. j. slu\u017ebu pro po\u010d\u00edt\u00e1n\u00ed t\u00e9to v\u011bci. Tato slu\u017eba byla nakonec dost slo\u017eit\u00e1, proto\u017ee to nen\u00ed snadn\u00e9 spo\u010d\u00edtat. Realizace m\u016f\u017ee b\u00fdt jednoduch\u00e1, pokud pot\u0159ebujete po\u010d\u00edtat n\u011bjak\u00e9 agreg\u00e1ty na pevn\u00fdch \u010dasov\u00fdch intervalech. Pokud v\u0161ak chcete po\u010d\u00edtat ud\u00e1losti v klouzav\u00e9m okn\u011b, nen\u00ed to tak snadn\u00e9, jak se zd\u00e1. Mysl\u00edm, \u017ee to zat\u00edm nen\u00ed realizov\u00e1no v ClickHouse nebo v datab\u00e1z\u00edch pro \u010dasov\u00e9 \u0159ady, proto\u017ee je to slo\u017eit\u00e9 na realizaci.<\/p>\n<p><\/p>\n<p><em>A je\u0161t\u011b jedna ot\u00e1zka. Te\u010f jsme hovo\u0159ili o pr\u016fm\u011brov\u00e1n\u00ed a vzpomn\u011bl jsem si, \u017ee kdysi existoval takov\u00fd n\u00e1stroj jako Graphite s backendem Carbon. A um\u011bl pro\u0159ez\u00e1vat star\u00e9 \u00fadaje, t. j. nech\u00e1val jednu hodnotu za minutu, jednu hodnotu za hodinu atd. V z\u00e1sad\u011b je to docela pohodln\u00e9, pokud pot\u0159ebujeme surov\u00e1 data, \u0159ekn\u011bme, za m\u011bs\u00edc, a v\u0161echno ostatn\u00ed se m\u016f\u017ee pro\u0159ezat. Ale Prometheus a VictoriaMetrics tuto funk\u010dnost nepodporuj\u00ed. Pl\u00e1nuje se jej\u00ed podpora? Pokud ne, pro\u010d?<\/em><\/p>\n<p><\/p>\n<p>D\u011bkujeme za dotaz. Na\u0161i u\u017eivatel\u00e9 se na to pravideln\u011b ptaj\u00ed. Ptaj\u00ed se, kdy p\u0159id\u00e1me podporu pro zhu\u0161\u0165ov\u00e1n\u00ed (downsampling). V tomto ohledu existuje n\u011bkolik probl\u00e9m\u016f. Za prv\u00e9, ka\u017ed\u00fd u\u017eivatel ch\u00e1pe pod t\u00edmto pojmem <code>downsampling<\/code> n\u011bco jin\u00e9ho: n\u011bkdo chce z\u00edskat libovoln\u00fd bod v dan\u00e9m intervalu, n\u011bkdo chce maxim\u00e1ln\u00ed, minim\u00e1ln\u00ed, pr\u016fm\u011brn\u00e9 hodnoty. Pokud do va\u0161\u00ed datab\u00e1ze zapisuj\u00ed data r\u016fzn\u00e9 syst\u00e9my, nelze je rozhodn\u011b zhu\u0161\u0165ovat jednotn\u011b. M\u016f\u017ee se st\u00e1t, \u017ee pro ka\u017ed\u00fd syst\u00e9m je pot\u0159eba pou\u017e\u00edt jin\u00e9 zhu\u0161t\u011bn\u00ed. A to je obt\u00ed\u017en\u00e9 na realizaci.<\/p>\n<p><\/p>\n<p>A druh\u00e9 - VictoriaMetrics, stejn\u011b jako ClickHouse, je optimalizov\u00e1n pro pr\u00e1ci s velk\u00fdm objemem surov\u00fdch dat, tak\u017ee dok\u00e1\u017ee zpracovat miliardu \u0159\u00e1dk\u016f za m\u00e9n\u011b ne\u017e jednu sekundu, pokud m\u00e1te v syst\u00e9mu mnoho jader. Skanning \u010dasov\u00fdch bod\u016f v VictoriaMetrics - 50 000 000 bod\u016f za sekundu na jedno j\u00e1dro. A tato v\u00fdkonnost se \u0161k\u00e1luje na st\u00e1vaj\u00edc\u00ed j\u00e1dra. Tedy, pokud m\u00e1te nap\u0159\u00edklad 20 jader, z\u00edsk\u00e1te skanning miliardy bod\u016f za sekundu. A tato vlastnost VictoriaMetrics a ClickHouse sni\u017euje pot\u0159ebu downsamplingu.<\/p>\n<p><\/p>\n<p>Dal\u0161\u00ed vlastnost\u00ed je, \u017ee VictoriaMetrics efektivn\u011b komprimuje tato data. Pr\u016fm\u011brn\u00e1 komprese v produk\u010dn\u00edm prost\u0159ed\u00ed se pohybuje od 0,4 do 0,8 bajt\u016f na bod. Ka\u017ed\u00fd bod \u2013 to je timestamp + hodnota. A v pr\u016fm\u011bru se komprimuje na m\u00e9n\u011b ne\u017e jeden bajt. <\/p>\n<p><\/p>\n<p><em>Serg\u011bj. M\u00e1m ot\u00e1zku. Jak\u00fd je minim\u00e1ln\u00ed \u010dasov\u00fd kvant zapisov\u00e1n\u00ed?<\/em><\/p>\n<p><\/p>\n<p>Jedna milisekunda. Ned\u00e1vno jsme m\u011bli rozhovor s jin\u00fdmi v\u00fdvoj\u00e1\u0159i datab\u00e1z\u00ed pro \u010dasov\u00e9 \u0159ady. U nich je minim\u00e1ln\u00ed \u010dasov\u00fd kvant jedna sekunda. A v Graphite je to nap\u0159\u00edklad tak\u00e9 jedna sekunda. V OpenTSDB tak\u00e9 jedna sekunda. V InfluxDB \u2013 nanosekundov\u00e1 p\u0159esnost. Ve VictoriaMetrics \u2013 jedna milisekunda, proto\u017ee v Prometheus je to jedna milisekunda. A VictoriaMetrics byla p\u016fvodn\u011b vyvinuta jako remote storage pro Prometheus. Ale nyn\u00ed m\u016f\u017ee uchov\u00e1vat data i z dal\u0161\u00edch syst\u00e9m\u016f. <\/p>\n<p><\/p>\n<p>\u010clov\u011bk, se kter\u00fdm jsem mluvil, \u0159\u00edk\u00e1, \u017ee maj\u00ed sekundovou p\u0159esnost \u2014 to jim sta\u010d\u00ed, proto\u017ee to z\u00e1vis\u00ed na typu dat, kter\u00e1 jsou uchov\u00e1v\u00e1na v datab\u00e1zi \u010dasov\u00fdch \u0159ad. Pokud se jedn\u00e1 o DevOps data nebo data z infrastruktury, kde je shroma\u017e\u010fujete s intervalem 30 sekund a\u017e minutu, sta\u010d\u00ed sekundov\u00e1 p\u0159esnost, m\u00e9n\u011b ji\u017e nen\u00ed pot\u0159eba. Pokud v\u0161ak shroma\u017e\u010fujete tato data z high frequency trading systems, je t\u0159eba nanosekundov\u00e1 p\u0159esnost.<\/p>\n<p><\/p>\n<p>Milisekundov\u00e1 p\u0159esnost ve VictoriaMetrics je vhodn\u00e1 jak pro DevOps p\u0159\u00edpad, tak i pro v\u011bt\u0161inu p\u0159\u00edpad\u016f, kter\u00e9 jsem zm\u00ednil na za\u010d\u00e1tku prezentace. Jedin\u011b pro high frequency trading syst\u00e9my nemus\u00ed b\u00fdt vhodn\u00e1.<\/p>\n<p><\/p>\n<p><em>D\u011bkuji! A je\u0161t\u011b ot\u00e1zka. Jak\u00e1 je kompatibilita s PromQL?<\/em><\/p>\n<p><\/p>\n<p>Pln\u00e1 zp\u011btn\u00e1 kompatibilita. VictoriaMetrics pln\u011b podporuje PromQL. Krom\u011b toho p\u0159id\u00e1v\u00e1 je\u0161t\u011b dodate\u010dn\u00e9 roz\u0161\u00ed\u0159en\u00e9 funkce k PromQL, kter\u00e9 se naz\u00fdv\u00e1 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/VictoriaMetrics\/VictoriaMetrics\/wiki\/MetricsQL\">MetricsQL<\/a><\/noindex>. O t\u00e9to roz\u0161\u00ed\u0159en\u00e9 funk\u010dnosti je k dispozici prezentace na YouTube. Mluvil jsem o tom na Monitoring Meetup na ja\u0159e v Petrohrad\u011b.<\/p>\n<p><\/p>\n<p>Telegram kan\u00e1l <noindex><a rel=\"nofollow\" href=\"https:\/\/t.me\/VictoriaMetrics_ru1\">VictoriaMetrics<\/a><\/noindex>.<\/p>\n<p class=\"for_users_only_msg\">Pouze registrovan\u00ed u\u017eivatel\u00e9 se mohou \u00fa\u010dastnit ankety. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">P\u0159ihlaste se<\/a><\/noindex>, pros\u00edm.<\/p>\n<h2 class=\"default-block__polling-title\">Co v\u00e1m br\u00e1n\u00ed p\u0159ej\u00edt na VictoriaMetrics jako dlouhodob\u00e9 \u00falo\u017ei\u0161t\u011b pro Prometheus? (Napi\u0161te to do koment\u00e1\u0159\u016f, p\u0159id\u00e1m to do ankety))<\/h2>\n<ul class=\"poll-result\">\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent  poll-result__data-percent_winner\">71,4%<\/strong>Nepou\u017e\u00edv\u00e1m Prometheus5<\/p>\n<\/li>\n<li class=\"poll-result__item\">\n<p>                <strong class=\"poll-result__data-percent\">28,6%<\/strong>Nev\u011bd\u011bl jsem o VictoriaMetrics2<\/p>\n<\/li>\n<\/ul>\n<p>    Hlasovalo 7 u\u017eivatel\u016f. Zdr\u017eelo se 12 u\u017eivatel\u016f.<br \/>\n<br \/>Zdroj: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/500844\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043a\u043e\u043d\u0446\u0430 2019 \u0433\u043e\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d\u0430 &quot;Go optimizations in VictoriaMetrics&quot; VictoriaMetrics \u2014 \u0431\u044b\u0441\u0442\u0440\u0430\u044f \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0421\u0423\u0411\u0414 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0444\u043e\u0440\u043c\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u044f\u0434\u0430 (\u0437\u0430\u043f\u0438\u0441\u044c \u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0438 \u043d\u0430\u0431\u043e\u0440 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u044d\u0442\u043e\u043c\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043f\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0438\u043b\u0438 \u0441\u0431\u043e\u0440 \u043c\u0435\u0442\u0440\u0438\u043a). \u0412\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0432\u0438\u0434\u0435\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u2014 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80734,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80733","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043a\u043e\u043d\u0446\u0430 2019 \u0433\u043e\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d\u0430 &quot;Go optimizations in VictoriaMetrics&quot;\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Go optimizations in VictoriaMetrics. \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043a\u043e\u043d\u0446\u0430 2019 \u0433\u043e\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d\u0430 &quot;Go optimizations in VictoriaMetrics&quot;\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-05-08T11:42:31+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-08T11:42:31+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Optimalizace Go ve VictoriaMetrics. Alexander Valjalkin | ProHoster","description":"Doporu\u010duji se sezn\u00e1mit se s p\u0159episem zpr\u00e1vy konce roku 2019 od Alexandra Valjaljkina \"Optimalizace Go ve VictoriaMetrics\"","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Go optimizations in VictoriaMetrics. \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d | ProHoster","og:description":"\u041f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 \u0434\u043e\u043a\u043b\u0430\u0434\u0430 \u043a\u043e\u043d\u0446\u0430 2019 \u0433\u043e\u0434\u0430 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u0430 \u0412\u0430\u043b\u044f\u043b\u043a\u0438\u043d\u0430 &quot;Go optimizations in VictoriaMetrics&quot;","og:url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/go-optimizations-in-victoriametrics-aleksandr-valyalkin","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-05-08T11:42:31+00:00","article:modified_time":"2020-05-08T11:42:31+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80733","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:12:22","updated":"2022-09-29 05:16:51","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/80733","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=80733"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/80733\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/80734"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=80733"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=80733"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=80733"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}