VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Men sizga Aleksandr Valyalkinning 2019 yil oxiridagi "VictoriaMetrics-da optimizatsiyalarga o'tish" hisobotining stenogrammasini o'qishni taklif qilaman.

VictoriaMetrics - vaqt seriyasi ko'rinishidagi ma'lumotlarni saqlash va qayta ishlash uchun tez va kengaytiriladigan DBMS (yozuv vaqtni va shu vaqtga to'g'ri keladigan qiymatlar to'plamini tashkil qiladi, masalan, sensorlar holatini davriy so'rov qilish yoki yig'ish orqali olingan. ko'rsatkichlar).

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bu hisobotning videosiga havola - https://youtu.be/MZ5P21j_HLE

Slaydlar

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

O'zingiz haqingizda gapirib bering. Men Aleksandr Valyalkinman. Bu yerga mening GitHub hisobim. Men Go va ishlashni optimallashtirishga ishtiyoqliman. Men juda ko'p foydali va unchalik foydali bo'lmagan kutubxonalarni yozdim. Ular ikkalasidan boshlanadi fast, yoki bilan quick prefiks.

Men hozirda VictoriaMetrics ustida ishlayapman. Bu nima va men u erda nima qilyapman? Men bu taqdimotda bu haqda gapiraman.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Hisobotning qisqacha mazmuni quyidagicha:

  • Birinchidan, men sizga VictoriaMetrics nima ekanligini aytib beraman.
  • Keyin men sizga vaqt seriyasi nima ekanligini aytib beraman.
  • Keyin men sizga vaqt seriyali ma'lumotlar bazasi qanday ishlashini aytib beraman.
  • Keyinchalik, men sizga ma'lumotlar bazasi arxitekturasi haqida gapirib beraman: u nimadan iborat.
  • Va keyin VictoriaMetrics-da mavjud bo'lgan optimallashtirishlarga o'tamiz. Bu teskari indeks uchun optimallashtirish va Go'da bitsetni amalga oshirish uchun optimallashtirish.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Tomoshabinlardan kimdir VictoriaMetrics nima ekanligini biladimi? Voy, ko'p odamlar allaqachon bilishadi. Bu yaxshi xabar. Bilmaganlar uchun bu vaqt seriyalari ma'lumotlar bazasi. U ClickHouse arxitekturasiga, ClickHouse ilovasining ba'zi tafsilotlariga asoslangan. Masalan, MergeTree, barcha mavjud protsessor yadrolarida parallel hisoblash va protsessor keshiga joylashtirilgan ma'lumotlar bloklari ustida ishlash orqali ishlashni optimallashtirish.

VictoriaMetrics boshqa vaqt seriyali ma'lumotlar bazalariga qaraganda yaxshiroq ma'lumotlarni siqishni ta'minlaydi.

U vertikal ravishda o'lchaydi - ya'ni bitta kompyuterga ko'proq protsessorlar, ko'proq RAM qo'shishingiz mumkin. VictoriaMetrics ushbu mavjud resurslardan muvaffaqiyatli foydalanadi va chiziqli mahsuldorlikni oshiradi.

VictoriaMetrics ham gorizontal ravishda o'lchaydi - ya'ni siz VictoriaMetrics klasteriga qo'shimcha tugunlarni qo'shishingiz mumkin va uning ishlashi deyarli chiziqli ravishda oshadi.

Siz taxmin qilganingizdek, VictoriaMetrics tezkor ma'lumotlar bazasi, chunki men boshqalarni yoza olmayman. Va bu Go-da yozilgan, shuning uchun men bu uchrashuvda bu haqda gapiryapman.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Vaqt seriyasi nima ekanligini kim biladi? Bundan tashqari, u ko'p odamlarni biladi. Vaqt seriyasi - bu juftliklar qatori (timestamp, значение), bu erda bu juftliklar vaqt bo'yicha tartiblangan. Qiymat suzuvchi nuqtali raqam - float64.

Har bir vaqt seriyasi kalit bilan noyob tarzda aniqlanadi. Bu kalit nimadan iborat? U kalit-qiymat juftlarining bo'sh bo'lmagan to'plamidan iborat.

Mana vaqt seriyasiga misol. Ushbu seriyaning kaliti juftliklar ro'yxati: __name__="cpu_usage" metrikaning nomi, instance="my-server" - bu ko'rsatkich to'plangan kompyuter, datacenter="us-east" - bu kompyuter joylashgan ma'lumotlar markazi.

Biz uchta kalit-qiymat juftligidan iborat vaqt seriyasining nomi bilan yakunlandik. Bu kalit juftliklar ro'yxatiga mos keladi (timestamp, value). t1, t3, t3, ..., tN - bu vaqt belgilari, 10, 20, 12, ..., 15 - mos keladigan qiymatlar. Bu ma'lum bir satr uchun ma'lum bir vaqtda protsessordan foydalanish.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Vaqt seriyalaridan qayerda foydalanish mumkin? Hech kimning fikri bormi?

  • DevOps-da siz CPU, operativ xotira, tarmoq, rps, xatolar sonini va hokazolarni o'lchashingiz mumkin.
  • IoT - biz haroratni, bosimni, geokoordinatalarni va boshqa narsalarni o'lchashimiz mumkin.
  • Shuningdek, moliya - biz barcha turdagi aktsiyalar va valyutalar narxlarini kuzatishimiz mumkin.
  • Bundan tashqari, fabrikalarda ishlab chiqarish jarayonlarini kuzatishda vaqt seriyalaridan foydalanish mumkin. Robotlar uchun shamol turbinalarini kuzatish uchun VictoriaMetrics-dan foydalanadigan foydalanuvchilarimiz bor.
  • Vaqt seriyalari turli qurilmalarning sensorlaridan ma'lumot to'plash uchun ham foydalidir. Masalan, dvigatel uchun; shinalar bosimini o'lchash uchun; tezlikni, masofani o'lchash uchun; benzin sarfini o'lchash uchun va boshqalar.
  • Vaqt seriyalaridan samolyotlarni kuzatish uchun ham foydalanish mumkin. Har bir samolyotda samolyot sog'lig'ining turli parametrlari uchun vaqt seriyalarini to'playdigan qora quti mavjud. Vaqt seriyalari aerokosmik sanoatida ham qo'llaniladi.
  • Sog'liqni saqlash - bu qon bosimi, puls va boshqalar.

Men unutgan ilovalar ko'proq bo'lishi mumkin, ammo umid qilamanki, vaqt seriyalari zamonaviy dunyoda faol qo'llanilishini tushunasiz. Ulardan foydalanish hajmi esa yil sayin ortib bormoqda.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Vaqt seriyalari ma'lumotlar bazasi nima uchun kerak? Nima uchun vaqt seriyasini saqlash uchun muntazam relyatsion ma'lumotlar bazasidan foydalana olmaysiz?

Chunki vaqt seriyalari odatda katta hajmdagi ma'lumotlarni o'z ichiga oladi, ularni an'anaviy ma'lumotlar bazalarida saqlash va qayta ishlash qiyin. Shuning uchun vaqt seriyalari uchun maxsus ma'lumotlar bazalari paydo bo'ldi. Ushbu bazalar ballarni samarali saqlaydi (timestamp, value) berilgan kalit bilan. Ular saqlangan ma'lumotlarni kalit bo'yicha, bitta kalit-qiymat juftligi yoki bir nechta kalit-qiymat juftligi yoki regexp orqali o'qish uchun API taqdim etadi. Misol uchun, siz Amerikadagi ma'lumotlar markazida barcha xizmatlaringizning protsessor yukini topmoqchi bo'lsangiz, keyin ushbu soxta so'rovdan foydalanishingiz kerak.

Odatda vaqt seriyali ma'lumotlar bazalari maxsus so'rovlar tillarini taqdim etadi, chunki vaqt seriyasi SQL unchalik mos emas. SQL-ni qo'llab-quvvatlaydigan ma'lumotlar bazalari mavjud bo'lsa-da, u juda mos emas. kabi so'rov tillari PromQL, InfluxQL, oqib, Q. Umid qilamanki, kimdir bu tillardan kamida bittasini eshitgan. Ko'pchilik PromQL haqida eshitgan bo'lishi mumkin. Bu Prometey so'rovlar tili.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

VictoriaMetrics misolida zamonaviy vaqt seriyali ma'lumotlar bazasi arxitekturasi shunday ko'rinadi.

U ikki qismdan iborat. Bu teskari indeks uchun saqlash va vaqt seriyalari qiymatlari uchun saqlash. Bu omborlar ajratilgan.

Ma'lumotlar bazasiga yangi yozuv kelganda, biz avval berilgan to'plam uchun vaqt seriyasi identifikatorini topish uchun teskari indeksga kiramiz. label=value ma'lum bir ko'rsatkich uchun. Biz ushbu identifikatorni topamiz va qiymatni ma'lumotlar do'konida saqlaymiz.

TSDB dan ma'lumotlarni olish uchun so'rov kelganda, biz birinchi navbatda teskari indeksga o'tamiz. Keling, hamma narsani olamiz timeseries_ids ushbu to'plamga mos keladigan yozuvlar label=value. Va keyin biz barcha kerakli ma'lumotlarni ma'lumotlar omboridan indekslangan holda olamiz timeseries_ids.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Vaqt seriyali ma'lumotlar bazasi kiruvchi tanlash so'rovini qanday qayta ishlashiga misolni ko'rib chiqaylik.

  • Birinchidan, u hamma narsani oladi timeseries_ids berilgan juftlarni o'z ichiga olgan teskari indeksdan label=value, yoki berilgan muntazam ifodani qanoatlantiring.
  • Keyin topilganlar uchun ma'lum vaqt oralig'ida barcha ma'lumotlar nuqtalarini ma'lumotlarni saqlash joyidan oladi timeseries_ids.
  • Shundan so'ng, ma'lumotlar bazasi foydalanuvchining so'roviga binoan ushbu ma'lumotlar nuqtalari bo'yicha ba'zi hisob-kitoblarni amalga oshiradi. Va shundan keyin u javobni qaytaradi.

Ushbu taqdimotda men sizga birinchi qism haqida gapirib beraman. Bu qidiruv timeseries_ids teskari indeks bo'yicha. Ikkinchi va uchinchi qismini keyinroq tomosha qilishingiz mumkin VictoriaMetrics manbalari, yoki boshqa hisobotlarni tayyorlamaguncha kuting :)

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Keling, teskari indeksga o'tamiz. Ko'pchilik buni oddiy deb o'ylashi mumkin. Invert indeks nima ekanligini va u qanday ishlashini kim biladi? Oh, endi ko'p odamlar emas. Keling, bu nima ekanligini tushunishga harakat qilaylik.

Bu aslida oddiy. Bu oddiygina lug'at bo'lib, kalitni qiymatga moslashtiradi. Kalit nima? Bu juftlik label=valueqayerda label и value - bu chiziqlar. Va qiymatlar to'plamdir timeseries_ids, unga berilgan juftlik kiradi label=value.

Inverted indeks sizga hamma narsani tezda topish imkonini beradi timeseries_ids, berganlar label=value.

Shuningdek, u tezda topishga imkon beradi timeseries_ids bir necha juftlik uchun vaqt seriyasi label=value, yoki juftliklar uchun label=regexp. Bu qanday sodir bo'ladi? To'plamning kesishuvini topish orqali timeseries_ids har bir juftlik uchun label=value.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Keling, teskari indeksning turli xil ilovalarini ko'rib chiqaylik. Eng oddiy sodda amalga oshirishdan boshlaylik. U shunday ko'rinadi.

vazifa getMetricIDs satrlar ro'yxatini oladi. Har bir qator o'z ichiga oladi label=value. Ushbu funktsiya ro'yxatni qaytaradi metricIDs.

U qanday ishlaydi? Bu erda biz global o'zgaruvchiga egamiz invertedIndex. Bu oddiy lug'at (map), bu satrni intslarni kesish uchun xaritaga keltiradi. Qator o'z ichiga oladi label=value.

Funktsiyani amalga oshirish: get metricIDs birinchi uchun label=value, keyin biz qolgan hamma narsadan o'tamiz label=value, tushunamiz metricIDs ular uchun. Va funktsiyani chaqiring intersectInts, bu quyida muhokama qilinadi. Va bu funktsiya ushbu ro'yxatlarning kesishishini qaytaradi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Ko'rib turganingizdek, teskari indeksni amalga oshirish juda murakkab emas. Ammo bu sodda amalga oshirish. Uning qanday kamchiliklari bor? Naif amalga oshirishning asosiy kamchiligi shundaki, bunday teskari indeks RAMda saqlanadi. Ilovani qayta ishga tushirgandan so'ng biz ushbu indeksni yo'qotamiz. Ushbu indeks diskda saqlanmaydi. Bunday teskari indeks ma'lumotlar bazasi uchun mos bo'lishi dargumon.

Ikkinchi kamchilik ham xotira bilan bog'liq. Invertlangan indeks RAMga mos kelishi kerak. Agar u RAM hajmidan oshib ketgan bo'lsa, unda biz aniqki - xotiradan chiqib ketish xatosi. Va dastur ishlamaydi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Kabi tayyor echimlar yordamida bu muammoni hal qilish mumkin LevelDB, yoki RocksDB.

Qisqasi, bizga uchta operatsiyani tez bajarish imkonini beruvchi ma'lumotlar bazasi kerak.

  • Birinchi operatsiya - yozib olish ключ-значение ushbu ma'lumotlar bazasiga. U buni juda tez qiladi, qaerda ключ-значение ixtiyoriy qatorlardir.
  • Ikkinchi operatsiya - berilgan kalit yordamida qiymatni tezkor qidirish.
  • Uchinchi operatsiya esa berilgan prefiks bo'yicha barcha qiymatlarni tezkor qidirishdir.

LevelDB va RocksDB - bu ma'lumotlar bazalari Google va Facebook tomonidan ishlab chiqilgan. Birinchi bo'lib LevelDB keldi. Keyin Facebook yigitlari LevelDB-ni olib, uni yaxshilashni boshladilar, ular RocksDB-ni yaratdilar. Endi deyarli barcha ichki ma'lumotlar bazalari Facebook ichidagi RocksDB-da ishlaydi, shu jumladan RocksDB va MySQL-ga o'tkazilganlar. Unga ism qo'yishdi MyRocks.

Invertlangan indeks LevelDB yordamida amalga oshirilishi mumkin. Buni qanday qilish kerak? Biz kalit sifatida saqlaymiz label=value. Va qiymat bu juftlik mavjud bo'lgan vaqt seriyasining identifikatoridir label=value.

Agar berilgan juftlik bilan ko'p vaqtli qatorlar mavjud bo'lsa label=value, keyin ushbu ma'lumotlar bazasida bir xil kalit va har xil bo'lgan ko'plab qatorlar bo'ladi timeseries_ids. Hammasi ro'yxatini olish uchun timeseries_ids, bu bilan boshlanadi label=prefix, biz ushbu ma'lumotlar bazasi optimallashtirilgan diapazonni skanerlaymiz. Ya'ni, biz boshlanadigan barcha qatorlarni tanlaymiz label=prefix va kerakli narsalarni oling timeseries_ids.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Mana, Go'da qanday ko'rinishini amalga oshirishning namunasi. Bizda teskari indeks mavjud. Bu LevelDB.

Funktsiya sodda amalga oshirish bilan bir xil. U sodda amalga oshirishni deyarli satr bilan takrorlaydi. Yagona nuqta shundaki, unga murojaat qilish o'rniga map biz teskari indeksga kiramiz. Birinchisi uchun barcha qiymatlarni olamiz label=value. Keyin qolgan barcha juftlarni bosib o'tamiz label=value va ular uchun mos metrik identifikatorlar to'plamini oling. Keyin biz kesishgan joyni topamiz.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Hamma narsa yaxshi ko'rinadi, ammo bu yechimning kamchiliklari bor. VictoriaMetrics dastlab LevelDB asosida teskari indeksni amalga oshirdi. Lekin oxirida men undan voz kechishga majbur bo'ldim.

Nega? Chunki LevelDB sodda dasturga qaraganda sekinroq. Oddiy dasturda, berilgan kalit berilgan bo'lsa, biz darhol butun tilimni olamiz metricIDs. Bu juda tez operatsiya - butun tilim foydalanishga tayyor.

LevelDB da funksiya har safar chaqirilganda GetValues bilan boshlangan barcha satrlarni bosib o'tishingiz kerak label=value. Va har bir satr uchun qiymatni oling timeseries_ids. Bundaylardan timeseries_ids bularning bir bo'lagini yig'ing timeseries_ids. Shubhasiz, bu oddiy xaritaga kalit yordamida kirishdan ko'ra ancha sekinroq.

Ikkinchi kamchilik shundaki, LevelDB C tilida yozilgan. Go'dan C funksiyalarini chaqirish unchalik tez emas. Bu yuzlab nanosoniyalarni oladi. Bu juda tez emas, chunki go'da yozilgan oddiy funktsiya chaqiruvi bilan solishtirganda, 1-5 nanosekund davom etadi, ishlashdagi farq o'nlab marta. VictoriaMetrics uchun bu halokatli kamchilik edi :)

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Shunday qilib, men teskari indeksni o'zimning amalga oshirishimni yozdim. Va u uni chaqirdi birlashtirish.

Mergeset MergeTree ma'lumotlar strukturasiga asoslangan. Ushbu ma'lumotlar strukturasi ClickHouse'dan olingan. Shubhasiz, birlashma to'plamini tez qidirish uchun optimallashtirish kerak timeseries_ids berilgan kalitga muvofiq. Mergeset butunlay Go-da yozilgan. Ko'rishingiz mumkin GitHub-dagi VictoriaMetrics manbalari. Mergesetni amalga oshirish papkada /lib/mergeset. Siz u erda nima bo'layotganini tushunishga harakat qilishingiz mumkin.

Mergeset API LevelDB va RocksDB ga juda o'xshaydi. Ya'ni, u erda yangi yozuvlarni tezda saqlash va berilgan prefiks bo'yicha yozuvlarni tezda tanlash imkonini beradi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Birlashtirishning kamchiliklari haqida keyinroq gaplashamiz. Endi teskari indeksni amalga oshirishda ishlab chiqarishda VictoriaMetrics bilan qanday muammolar paydo bo'lganligi haqida gapiraylik.

Nima uchun ular paydo bo'ldi?

Birinchi sabab - yuqori ishdan chiqish darajasi. Rus tiliga tarjima qilinganda, bu vaqt seriyasining tez-tez o'zgarishi. Bu vaqt seriyasi tugaydi va yangi seriya boshlanadi yoki ko'plab yangi vaqt seriyalari boshlanadi. Va bu tez-tez sodir bo'ladi.

Ikkinchi sabab - vaqt seriyalarining ko'pligi. Dastlab, monitoring ommalashib borayotgan paytda, vaqt seriyalari soni kam edi. Misol uchun, har bir kompyuter uchun protsessor, xotira, tarmoq va disk yukini kuzatishingiz kerak. Har bir kompyuter uchun 4 ta vaqt seriyasi. Aytaylik, sizda 100 ta kompyuter va 400 ta vaqt seriyasi mavjud. Bu juda oz.

Vaqt o'tishi bilan odamlar ko'proq ma'lumotni o'lchashlari mumkinligini tushunishdi. Masalan, butun protsessorning emas, balki har bir protsessor yadrosining yukini alohida o'lchang. Agar sizda 40 ta protsessor yadrosi bo'lsa, protsessor yukini o'lchash uchun 40 marta ko'proq vaqt seriyasiga ega bo'lasiz.

Lekin bu hammasi emas. Har bir protsessor yadrosi bir nechta holatga ega bo'lishi mumkin, masalan, u ishlamay qolganda. Shuningdek, foydalanuvchi maydonida ishlash, yadro maydonida va boshqa holatlarda ishlash. Va har bir bunday holat alohida vaqt qatori sifatida ham o'lchanishi mumkin. Bu qo'shimcha ravishda qatorlar sonini 7-8 marta oshiradi.

Bitta ko'rsatkichdan biz faqat bitta kompyuter uchun 40 x 8 = 320 ko'rsatkichni oldik. 100 ga ko'paytirsak, biz 32 o'rniga 000 400 ni olamiz.

Keyin Kubernetes keldi. Va bu yomonlashdi, chunki Kubernetes turli xil xizmatlarni qabul qilishi mumkin. Kubernetesdagi har bir xizmat ko'p podkastlardan iborat. Va bularning barchasini kuzatib borish kerak. Bundan tashqari, biz sizning xizmatlaringizning yangi versiyalarini doimiy ravishda tarqatamiz. Har bir yangi versiya uchun yangi vaqt seriyasi yaratilishi kerak. Natijada, vaqt qatorlari soni eksponent tarzda o'sib boradi va biz yuqori kardinallik deb ataladigan ko'p sonli vaqt seriyalari muammosiga duch kelamiz. VictoriaMetrics boshqa vaqt seriyalari ma'lumotlar bazalariga qaraganda u bilan muvaffaqiyatli kurashadi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Keling, yuqori ishdan chiqish tezligini batafsil ko'rib chiqaylik. Ishlab chiqarishda yuqori ishlamay qolishga nima sabab bo'ladi? Chunki teglar va teglarning ba'zi ma'nolari doimo o'zgarib turadi.

Misol uchun, kontseptsiyaga ega bo'lgan Kubernetesni olaylik deployment, ya'ni ilovangizning yangi versiyasi chiqarilganda. Ba'zi sabablarga ko'ra, Kubernetes ishlab chiquvchilari yorliqga joylashtirish identifikatorini qo'shishga qaror qilishdi.

Bu nimaga olib keldi? Bundan tashqari, har bir yangi o'rnatish bilan barcha eski vaqt seriyalari uzilib qoladi va ularning o'rniga yangi vaqt seriyalari yangi yorliq qiymati bilan boshlanadi. deployment_id. Bunday qatorlar yuz minglab va hatto millionlab bo'lishi mumkin.

Bularning barchasida muhim jihat shundaki, vaqt seriyalarining umumiy soni o'sib boradi, lekin hozirda faol bo'lgan va ma'lumotlarni qabul qiluvchi vaqt seriyalari soni doimiy bo'lib qoladi. Bu holat yuqori ishdan chiqish darajasi deb ataladi.

Yuqori uzilish tezligining asosiy muammosi ma'lum vaqt oralig'ida berilgan belgilar to'plami uchun barcha vaqt seriyalari uchun doimiy qidiruv tezligini ta'minlashdir. Odatda bu oxirgi soat yoki oxirgi kun uchun vaqt oralig'i.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bu muammoni qanday hal qilish mumkin? Mana birinchi variant. Bu vaqt o'tishi bilan teskari indeksni mustaqil qismlarga bo'lishdir. Ya'ni, bir oz vaqt oralig'i o'tadi, biz joriy teskari indeks bilan ishlashni tugatamiz. Va yangi teskari indeks yarating. Yana bir vaqt oralig'i o'tadi, biz boshqasini va boshqasini yaratamiz.

Va bu teskari indekslardan tanlab olishda biz berilgan intervalga to'g'ri keladigan teskari indekslar to'plamini topamiz. Va shunga ko'ra, biz u erdan vaqt seriyasining identifikatorini tanlaymiz.

Bu resurslarni tejaydi, chunki biz berilgan intervalga to'g'ri kelmaydigan qismlarga qarashimiz shart emas. Ya'ni, odatda, agar biz oxirgi soat uchun ma'lumotlarni tanlasak, oldingi vaqt oralig'ida biz so'rovlarni o'tkazib yuboramiz.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Ushbu muammoni hal qilishning yana bir varianti bor. Bu har bir kun uchun o'sha kuni sodir bo'lgan vaqt seriyalari identifikatorlarining alohida ro'yxatini saqlash uchun mo'ljallangan.

Bu yechimning oldingi yechimdan afzalligi shundaki, biz vaqt o'tishi bilan yo'qolmaydigan vaqt seriyalari ma'lumotlarini takrorlamaymiz. Ular doimo mavjud va o'zgarmasdir.

Kamchilik shundaki, bunday yechimni amalga oshirish qiyinroq va disk raskadrovka qilish qiyinroq. Va VictoriaMetrics bu yechimni tanladi. Tarixiy jihatdan shunday bo'lgan. Ushbu yechim avvalgisiga nisbatan ham yaxshi ishlaydi. Ushbu yechim o'zgarmas, ya'ni vaqt o'tishi bilan yo'qolmaydigan vaqt seriyalari uchun har bir bo'limda ma'lumotlarni takrorlash zarurligi sababli amalga oshirilmadi. VictoriaMetrics birinchi navbatda disk maydonini iste'mol qilish uchun optimallashtirilgan va oldingi dastur disk maydoni sarfini yomonlashtirdi. Ammo bu dastur diskdagi bo'sh joy sarfini minimallashtirish uchun ko'proq mos keladi, shuning uchun u tanlangan.

Men u bilan jang qilishim kerak edi. Kurash shundan iboratki, ushbu amalga oshirishda siz hali ham ko'proq raqamni tanlashingiz kerak timeseries_ids ma'lumotlar uchun teskari indeks vaqtga bo'lingandan ko'ra.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bu muammoni qanday hal qildik? Biz uni original tarzda hal qildik - har bir teskari indeks yozuvida bitta identifikator o'rniga bir nechta vaqt seriyasi identifikatorlarini saqlash orqali. Ya'ni, bizda kalit bor label=value, bu har bir vaqt qatorida uchraydi. Va endi biz bir nechtasini saqlaymiz timeseries_ids bitta kirishda.

Mana bir misol. Ilgari bizda N ta yozuv bor edi, ammo hozir bizda bitta yozuv bor, uning prefiksi boshqalar bilan bir xil. Avvalgi yozuv uchun qiymat barcha vaqt seriyalarining identifikatorlarini o'z ichiga oladi.

Bu shunday teskari indeksni skanerlash tezligini 10 barobarga oshirish imkonini berdi. Va bu bizga kesh uchun xotira sarfini kamaytirishga imkon berdi, chunki endi biz satrni saqlaymiz label=value faqat bir marta keshda birga N marta. Va agar siz Kubernetes o'z teglar va teglaringizda uzun satrlarni saqlasangiz, bu qator katta bo'lishi mumkin.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Invertlangan indeksda qidirishni tezlashtirishning yana bir varianti shardingdir. Bitta o'rniga bir nechta teskari indekslarni yaratish va ular o'rtasida kalit bo'yicha ma'lumotlarni taqsimlash. Bu to'plam key=value bug '. Ya'ni, biz bir nechta mustaqil teskari indekslarni olamiz, biz bir nechta protsessorlarda parallel ravishda so'rashimiz mumkin. Oldingi ilovalar faqat bitta protsessorli rejimda ishlashga ruxsat berdi, ya'ni faqat bitta yadroda ma'lumotlarni skanerlash. Ushbu yechim ClickHouse yoqtirganidek, bir vaqtning o'zida bir nechta yadrolardagi ma'lumotlarni skanerlash imkonini beradi. Bu biz amalga oshirishni rejalashtirgan narsamiz.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Endi qo'ylarimizga - kesishish funktsiyasiga qaytaylik timeseries_ids. Keling, qanday ilovalar bo'lishi mumkinligini ko'rib chiqaylik. Bu funksiya topish imkonini beradi timeseries_ids berilgan to'plam uchun label=value.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Birinchi variant - sodda amalga oshirish. Ikki ichki halqa. Bu erda biz funktsiyani kiritamiz intersectInts ikki bo'lak - a и b. Chiqishda u bizga ushbu bo'laklarning kesishgan joyini qaytarishi kerak.

Sodda amalga oshirish shunday ko'rinadi. Biz tilimdagi barcha qiymatlarni takrorlaymiz a, bu halqa ichida biz tilimning barcha qiymatlaridan o'tamiz b. Va biz ularni taqqoslaymiz. Agar ular mos kelsa, biz chorrahani topdik. Va uni saqlang result.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Kamchiliklari qanday? Kvadrat murakkablik uning asosiy kamchiligidir. Misol uchun, agar sizning o'lchamlaringiz tilim bo'lsa a и b bir vaqtning o'zida bir million, keyin bu funksiya sizga hech qachon javob qaytarmaydi. Chunki u bir trillion iteratsiyani amalga oshirishi kerak bo'ladi, bu hatto zamonaviy kompyuterlar uchun ham ko'p.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Ikkinchi amalga oshirish xaritaga asoslangan. Biz xaritani yaratamiz. Biz ushbu xaritaga tilimdagi barcha qiymatlarni joylashtiramiz a. Keyin biz alohida halqa ichida tilim orqali o'tamiz b. Va biz bu qiymat tilimdan yoki yo'qligini tekshiramiz b xaritada. Agar u mavjud bo'lsa, uni natijaga qo'shing.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Qanday foyda bor? Afzallik shundaki, faqat chiziqli murakkablik mavjud. Ya'ni, funksiya kattaroq bo'laklar uchun tezroq ishlaydi. Million o'lchamli bo'lak uchun bu funktsiya oldingi funktsiyaning trillion iteratsiyasidan farqli o'laroq 2 million iteratsiyada bajariladi.

Salbiy tomoni shundaki, ushbu funktsiya ushbu xaritani yaratish uchun ko'proq xotira talab qiladi.

Ikkinchi kamchilik - bu xeshlash uchun katta xarajatlar. Bu kamchilik juda aniq emas. Va biz uchun bu juda aniq emas edi, shuning uchun dastlab VictoriaMetrics-da kesishuvni amalga oshirish xarita orqali amalga oshirildi. Ammo keyin profillash shuni ko'rsatdiki, asosiy protsessor vaqti xaritaga yozish va ushbu xaritada qiymat mavjudligini tekshirishga sarflanadi.

Nima uchun bu joylarda CPU vaqti behuda ketmoqda? Chunki Go bu satrlarda xeshlash operatsiyasini bajaradi. Ya'ni, u HashMap-dagi berilgan indeksga kirish uchun kalitning xeshini hisoblab chiqadi. Xeshni hisoblash operatsiyasi o'nlab nanosekundlarda yakunlanadi. Bu VictoriaMetrics uchun sekin.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Men bu ish uchun maxsus optimallashtirilgan bitsetni amalga oshirishga qaror qildim. Ikki bo'lakning kesishishi endi shunday ko'rinadi. Bu erda biz bit to'plamini yaratamiz. Biz unga birinchi bo'limdan elementlarni qo'shamiz. Keyin ikkinchi bo'lakda ushbu elementlarning mavjudligini tekshiramiz. Va ularni natijaga qo'shing. Ya'ni, oldingi misoldan deyarli farq qilmaydi. Bu erda yagona narsa shundaki, biz xaritaga kirishni maxsus funktsiyalar bilan almashtirdik add и has.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bir qarashda, agar ilgari u erda standart xarita ishlatilgan bo'lsa va keyin boshqa funktsiyalar chaqirilgan bo'lsa, bu sekinroq ishlashi kerakdek tuyuladi, ammo profillash shuni ko'rsatadiki, VictoriaMetrics misolida bu narsa standart xaritadan 10 baravar tezroq ishlaydi.

Bundan tashqari, u xaritani amalga oshirish bilan solishtirganda ancha kam xotirani ishlatadi. Chunki biz bu yerda sakkiz baytlik qiymatlar o‘rniga bitlarni saqlayapmiz.

Ushbu amalga oshirishning kamchiligi shundaki, u unchalik aniq emas, ahamiyatsiz emas.

Ko'pchilik sezmasligi mumkin bo'lgan yana bir kamchilik shundaki, bu dastur ba'zi hollarda yaxshi ishlamasligi mumkin. Ya'ni, u VictoriaMetrics vaqt seriyasining identifikatorlari kesishishi uchun ma'lum bir holat uchun optimallashtirilgan. Bu barcha holatlar uchun mos keladi degani emas. Agar u noto'g'ri ishlatilsa, biz ishlashning o'sishini emas, balki xotirada xatolik va ishlashning sekinlashishini olamiz.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Keling, ushbu tuzilmani amalga oshirishni ko'rib chiqaylik. Agar siz qidirmoqchi bo'lsangiz, u VictoriaMetrics manbalarida, papkada joylashgan lib/uint64set. Bu VictoriaMetrics ishi uchun maxsus optimallashtirilgan, qaerda timeseries_id 64 bitli qiymat bo'lib, bu erda birinchi 32 bit asosan doimiy va faqat oxirgi 32 bit o'zgaradi.

Ushbu ma'lumotlar strukturasi diskda saqlanmaydi, u faqat xotirada ishlaydi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Mana uning API. Bu juda murakkab emas. API maxsus VictoriaMetrics-dan foydalanishning o'ziga xos misoliga moslashtirilgan. Ya'ni, bu erda keraksiz funktsiyalar yo'q. Mana VictoriaMetrics tomonidan aniq ishlatiladigan funktsiyalar.

Funktsiyalar mavjud add, bu yangi qiymatlarni qo'shadi. Funktsiya mavjud has, bu yangi qiymatlarni tekshiradi. Va funksiya mavjud del, bu qiymatlarni olib tashlaydi. Yordamchi funksiya mavjud len, bu to'plam hajmini qaytaradi. Funktsiya clone juda ko'p klonlar. Va funktsiya appendto bu to'plamni tilimga aylantiradi timeseries_ids.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Ushbu ma'lumotlar strukturasini amalga oshirish shunday ko'rinadi. to'plam ikkita elementga ega:

  • ItemsCount to'plamdagi elementlar sonini tezda qaytarish uchun yordamchi maydon. Ushbu yordamchi maydonsiz buni qilish mumkin edi, lekin uni bu erga qo'shish kerak edi, chunki VictoriaMetrics ko'pincha o'z algoritmlarida bitlar uzunligini so'raydi.

  • Ikkinchi maydon buckets. Bu strukturadan parcha bucket32. Har bir tuzilma saqlanadi hi maydon. Bular yuqori 32 bit. Va ikkita tilim - b16his и buckets dan bucket16 tuzilmalar.

16 bitli strukturaning ikkinchi qismining yuqori 64 biti bu erda saqlanadi. Va bu erda bitsets har bir baytning pastki 16 biti uchun saqlanadi.

Bucket64 massivdan iborat uint64. Uzunlik ushbu konstantalar yordamida hisoblanadi. Birida bucket16 maksimal darajada saqlanishi mumkin 2^16=65536 bit. Agar siz buni 8 ga bo'lsangiz, u 8 kilobayt bo'ladi. Agar siz yana 8 ga bo'lsangiz, u 1000 bo'ladi uint64 ma'nosi. Anavi Bucket16 - bu bizning 8 kilobaytlik tuzilmamiz.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Keling, ushbu tuzilmaning yangi qiymat qo'shish usullaridan biri qanday amalga oshirilishini ko'rib chiqaylik.

Hammasi bilan boshlanadi uint64 ma'nolari. Biz yuqori 32 bitni hisoblaymiz, pastki 32 bitni hisoblaymiz. Keling, hamma narsani boshdan kechiraylik buckets. Biz har bir chelakdagi eng yaxshi 32 bitni qo'shilgan qiymat bilan solishtiramiz. Va agar ular mos kelsa, biz funktsiyani chaqiramiz add b32 tuzilishida buckets. Va u erda pastki 32 bitni qo'shing. Va agar qaytib kelsa true, demak, biz u erda bunday qiymatni qo'shdik va bizda bunday qiymat yo'q edi. Agar qaytib kelsa false, keyin bunday ma'no allaqachon mavjud edi. Keyin strukturadagi elementlar sonini ko'paytiramiz.

Agar biz sizga kerakli narsani topmagan bo'lsak bucket kerakli yuqori qiymat bilan, keyin biz funktsiyani chaqiramiz addAlloc, bu yangisini ishlab chiqaradi bucket, uni chelak tuzilishiga qo'shish.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bu funktsiyani amalga oshirish b32.add. Bu avvalgi amaliyotga o'xshaydi. Biz eng muhim 16 bitni, eng kam ahamiyatli 16 bitni hisoblaymiz.

Keyin biz barcha yuqori 16 bitdan o'tamiz. Biz mosliklarni topamiz. Va agar mos keladigan bo'lsa, biz qo'shish usulini chaqiramiz, uni keyingi sahifada ko'rib chiqamiz bucket16.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Va bu erda imkon qadar optimallashtirish kerak bo'lgan eng past daraja. uchun hisoblaymiz uint64 tilim bitidagi id qiymati va shuningdek bitmask. Bu ma'lum 64-bitli qiymat uchun niqob bo'lib, bu bitning mavjudligini tekshirish yoki uni o'rnatish uchun ishlatilishi mumkin. Biz bu bit o'rnatilgan yoki yo'qligini tekshiramiz va uni o'rnatamiz va mavjudligini qaytaramiz. Bu bizning amalga oshirishimiz bo'lib, u bizga an'anaviy xaritalarga nisbatan 10 marta kesishgan vaqt seriyalarining identifikatorlari ishini tezlashtirishga imkon berdi.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Ushbu optimallashtirishdan tashqari, VictoriaMetrics boshqa ko'plab optimallashtirishlarga ega. Ushbu optimallashtirishlarning aksariyati biron bir sababga ko'ra qo'shilgan, ammo ishlab chiqarishda kodni profillashdan keyin.

Bu optimallashtirishning asosiy qoidasi – bu yerda to‘siq bo‘ladi deb optimallashtirishni qo‘shmang, chunki u yerda to‘siq bo‘lmasligi mumkin. Optimallashtirish odatda kod sifatini pasaytiradi. Shuning uchun, bu haqiqiy ma'lumotlar bo'lishi uchun faqat profillashdan keyin va afzalroq ishlab chiqarishda optimallashtirishga arziydi. Agar kimdir qiziqsa, siz VictoriaMetrics manba kodini ko'rishingiz va u erda mavjud bo'lgan boshqa optimallashtirishlarni o'rganishingiz mumkin.

VictoriaMetrics-da optimallashtirishga o'ting. Aleksandr Valyalkin

Bitset haqida savolim bor. C++ vektor bool ilovasiga juda o'xshash, optimallashtirilgan bit to'plami. Amalga oshirishni u erdan oldingizmi?

Yo'q, u erdan emas. Ushbu bit-setni amalga oshirishda men VictoriaMetrics-da qo'llaniladigan ushbu identifikatorlar vaqt seriyalarining tuzilishi haqidagi bilimlarga asoslandim. Va ularning tuzilishi shundayki, yuqori 32 bit asosan doimiydir. Pastki 32 bit o'zgarishi mumkin. Bit qanchalik past bo'lsa, u qanchalik tez-tez o'zgarishi mumkin. Shuning uchun, ushbu dastur ushbu ma'lumotlar strukturasi uchun maxsus optimallashtirilgan. Men bilishimcha, C++ ilovasi umumiy holat uchun optimallashtirilgan. Agar siz umumiy holat uchun optimallashtirsangiz, bu ma'lum bir ish uchun eng maqbul bo'lmasligini anglatadi.

Shuningdek, Aleksey Milovidning reportajini tomosha qilishni maslahat beraman. Taxminan bir oy oldin, u muayyan mutaxassisliklar uchun ClickHouse-da optimallashtirish haqida gapirdi. Uning so'zlariga ko'ra, umumiy holatda C++ ilovasi yoki boshqa dastur shifoxonada o'rtacha yaxshi ishlashi uchun moslashtirilgan. Bu biznikiga o'xshash bilimga oid dasturdan ko'ra yomonroq ishlashi mumkin, bu erda biz eng yaxshi 32 bit asosan doimiy ekanligini bilamiz.

Menda ikkinchi savol bor. InfluxDB dan asosiy farqi nimada?

Ko'p fundamental farqlar mavjud. Ishlash va xotira iste'moli nuqtai nazaridan, InfluxDB testlarda yuqori kardinallik vaqt seriyalari uchun 10 baravar ko'p xotira sarfini ko'rsatadi, agar sizda ularning ko'pi bo'lsa, masalan, millionlab. Misol uchun, VictoriaMetrics har bir million faol satr uchun 1 GB, InfluxDB esa 10 GB sarflaydi. Va bu katta farq.

Ikkinchi asosiy farq shundaki, InfluxDB g'alati so'rov tillariga ega - Flux va InfluxQL. Ular bilan solishtirganda vaqt seriyalari bilan ishlash uchun juda qulay emas PromQL, bu VictoriaMetrics tomonidan qo'llab-quvvatlanadi. PromQL - bu Prometey so'rovlar tili.

Va yana bir farq shundaki, InfluxDB biroz g'alati ma'lumotlar modeliga ega, unda har bir satr turli teglar to'plami bilan bir nechta maydonlarni saqlashi mumkin. Bu chiziqlar yana turli jadvallarga bo'lingan. Ushbu qo'shimcha asoratlar ushbu ma'lumotlar bazasi bilan keyingi ishlarni murakkablashtiradi. Qo'llab-quvvatlash va tushunish qiyin.

VictoriaMetrics-da hamma narsa ancha sodda. U erda har bir vaqt seriyasi kalit-qiymatdir. Qiymat nuqtalar to'plamidir - (timestamp, value), va kalit to'plamdir label=value. Maydonlar va o'lchovlar o'rtasida hech qanday ajratish yo'q. Bu sizga har qanday ma'lumotlarni tanlash va keyin birlashtirish, qo'shish, ayirish, ko'paytirish, bo'lish imkonini beradi, InfluxDB dan farqli o'laroq, men bilganimdek, turli qatorlar orasidagi hisoblar hali ham amalga oshirilmaydi. Agar ular amalga oshirilsa ham, bu qiyin, siz juda ko'p kod yozishingiz kerak.

Menda aniq bir savol bor. Men siz aytgan qandaydir muammo borligini, bu teskari indeks xotiraga mos kelmasligini, shuning uchun u erda bo'linish borligini to'g'ri tushundimmi?

Birinchidan, men standart Go xaritasida teskari indeksning sodda bajarilishini ko'rsatdim. Ushbu dastur ma'lumotlar bazalari uchun mos emas, chunki bu teskari indeks diskda saqlanmaydi va ma'lumotlar bazasi diskda saqlanishi kerak, shunda bu ma'lumotlar qayta ishga tushirilganda mavjud bo'lib qoladi. Ushbu dasturda, dasturni qayta ishga tushirganingizda, teskari indeksingiz yo'qoladi. Va siz barcha ma'lumotlarga kirish huquqini yo'qotasiz, chunki uni topa olmaysiz.

Salom! Hisobot uchun rahmat! Mening ismim Pavel. Men Wildberriesdanman. Sizga bir nechta savollarim bor. Birinchi savol. Sizningcha, agar siz ilovangiz arxitekturasini yaratishda boshqa printsipni tanlagan bo'lsangiz va vaqt o'tishi bilan ma'lumotlarni qismlarga ajratgan bo'lsangiz, ehtimol siz qidiruv paytida ma'lumotlarni kesishingiz mumkin edi, faqat bitta bo'lim bitta bo'lim uchun ma'lumotlarni o'z ichiga oladi. vaqt oralig'ida, ya'ni bir vaqt oralig'ida va sizning bo'laklaringiz boshqacha tarqalganligi haqida tashvishlanishingiz shart emasmi? 2-savol - Bitset va boshqa barcha narsalar bilan shunga o'xshash algoritmni amalga oshirayotganingiz uchun, ehtimol siz protsessor ko'rsatmalaridan foydalanishga harakat qildingizmi? Ehtimol, siz bunday optimallashtirishni sinab ko'rganmisiz?

Men darhol ikkinchisiga javob beraman. Biz hali u darajaga yetganimiz yo‘q. Ammo kerak bo'lsa, biz u erga boramiz. Va birinchisi, savol nima edi?

Siz ikkita stsenariyni muhokama qildingiz. Va ular ikkinchisini yanada murakkabroq amalga oshirishni tanlaganliklarini aytishdi. Va ular ma'lumotlar vaqt bo'yicha bo'lingan birinchisini afzal ko'rishmadi.

Ha. Birinchi holda, indeksning umumiy hajmi kattaroq bo'ladi, chunki har bir bo'limda biz ushbu bo'limlarning barchasida davom etadigan vaqt seriyalari uchun takroriy ma'lumotlarni saqlashimiz kerak edi. Va agar sizning vaqt seriyangizning ishdan chiqish tezligi kichik bo'lsa, ya'ni bir xil seriyalar doimiy ravishda ishlatilsa, birinchi holatda biz ikkinchi holatga nisbatan egallagan disk maydoni miqdorini ko'proq yo'qotamiz.

Va shuning uchun - ha, vaqtni ajratish yaxshi variant. Prometey undan foydalanadi. Ammo Prometeyning yana bir kamchiligi bor. Ushbu ma'lumotlar qismlarini birlashtirganda, u barcha teglar va vaqt seriyalari uchun meta-ma'lumotni xotirada saqlashi kerak. Shuning uchun, agar u birlashtirgan ma'lumotlar bo'laklari katta bo'lsa, VictoriaMetrics-dan farqli o'laroq, xotira iste'moli birlashish paytida juda ko'p ortadi. Birlashtirilganda VictoriaMetrics umuman xotirani iste'mol qilmaydi; birlashtirilgan ma'lumotlarning hajmidan qat'i nazar, faqat bir necha kilobayt iste'mol qilinadi.

Siz foydalanayotgan algoritm xotiradan foydalanadi. U qiymatlarni o'z ichiga olgan vaqt seriyasi teglarini belgilaydi. Shunday qilib, siz bir ma'lumot massivida va boshqasida juftlangan mavjudligini tekshirasiz. Va siz kesishgan yoki yo'qligini tushunasiz. Odatda, ma'lumotlar bazalari ushbu operatsiyalarning oddiy murakkabligi tufayli ularning joriy tarkibini saqlaydigan va tartiblangan ma'lumotlar orqali ishlaydigan kursorlar va iteratorlarni amalga oshiradi.

Nega biz ma'lumotlarni o'tkazish uchun kursorlardan foydalanmaymiz?

Ha.

Biz tartiblangan qatorlarni LevelDB yoki birlashmada saqlaymiz. Kursorni siljitishimiz va kesishmani topishimiz mumkin. Nega biz undan foydalanmaymiz? Chunki u sekin. Chunki kursorlar har bir satr uchun funktsiyani chaqirish kerakligini bildiradi. Funktsiya chaqiruvi 5 nanosekundni tashkil qiladi. Va agar sizda 100 000 000 qator bo'lsa, biz funktsiyani chaqirish uchun yarim soniya vaqtimizni sarflaymiz.

Bunday narsa bor, ha. Va mening oxirgi savolim. Savol biroz g'alati tuyulishi mumkin. Nima uchun ma'lumotlar kelgan paytda barcha kerakli agregatlarni o'qish va ularni kerakli shaklda saqlash mumkin emas? Nima uchun VictoriaMetrics, ClickHouse va boshqalar kabi ba'zi tizimlarda katta hajmlarni saqlash va keyin ularga ko'p vaqt sarflash kerak?

Men buni aniqroq qilish uchun misol keltiraman. Aytaylik, kichkina o'yinchoq spidometri qanday ishlaydi? U siz bosib o'tgan masofani yozib oladi, har doim uni bitta qiymatga qo'shadi, ikkinchisi esa. Va ajratadi. Va o'rtacha tezlikni oladi. Siz xuddi shu narsani qilishingiz mumkin. Tezda barcha kerakli faktlarni qo'shing.

OK, men savolni tushunaman. Sizning misolingiz o'z o'rniga ega. Agar sizga qanday agregatlar kerakligini bilsangiz, bu eng yaxshi dasturdir. Ammo muammo shundaki, odamlar ushbu ko'rsatkichlarni, ba'zi ma'lumotlarni ClickHouse-da saqlaydi va ular kelajakda ularni qanday yig'ish va filtrlashini hali bilishmaydi, shuning uchun ular barcha xom ma'lumotlarni saqlashlari kerak. Ammo agar siz biror narsani o'rtacha hisoblashingiz kerakligini bilsangiz, unda bir nechta xom qiymatlarni saqlash o'rniga uni hisoblab chiqmaysizmi? Ammo bu sizga nima kerakligini aniq bilsangizgina bo'ladi.

Aytgancha, vaqt seriyasini saqlash uchun ma'lumotlar bazalari agregatlarni hisoblashni qo'llab-quvvatlaydi. Masalan, Prometey qo'llab-quvvatlaydi ro'yxatga olish qoidalari. Ya'ni, bu sizga qanday birliklar kerakligini bilsangiz amalga oshirilishi mumkin. VictoriaMetrics hali bunga ega emas, lekin odatda Prometeydan oldin bo'ladi, unda buni qayta kodlash qoidalarida amalga oshirish mumkin.

Misol uchun, oldingi ishimda men so'nggi bir soat ichida toymasin oynadagi voqealar sonini hisoblashim kerak edi. Muammo shundaki, men Go-da maxsus dasturni, ya'ni bu narsani hisoblash xizmatini yaratishim kerak edi. Bu xizmat oxir-oqibatda ahamiyatsiz edi, chunki uni hisoblash qiyin. Agar siz belgilangan vaqt oralig'ida ba'zi agregatlarni hisoblashingiz kerak bo'lsa, amalga oshirish oddiy bo'lishi mumkin. Agar siz voqealarni toymasin oynada hisoblashni istasangiz, unda bu ko'rinadigan darajada oddiy emas. Menimcha, bu hali ClickHouse-da yoki vaqt seriyali ma'lumotlar bazalarida amalga oshirilmagan, chunki uni amalga oshirish qiyin.

Va yana bir savol. Biz shunchaki o'rtacha hisoblash haqida gapirgan edik va men bir vaqtlar karbonli grafit kabi narsa borligini esladim. Va u eski ma'lumotlarni qanday yupqalashni bilardi, ya'ni daqiqada bir nuqta, soatiga bir nuqta va hokazolarni qoldirishni bilardi. Aslida, agar bizga nisbatan bir oy davomida xom ma'lumot kerak bo'lsa, bu juda qulay va qolgan hamma narsa mumkin. yupqalashtirmoq. Ammo Prometey va VictoriaMetrics bu funksiyani qo'llab-quvvatlamaydi. Uni qo'llab-quvvatlash rejalashtirilganmi? Agar yo'q bo'lsa, nima uchun?

Savol uchun rahmat. Bizning foydalanuvchilarimiz bu savolni vaqti-vaqti bilan berishadi. Ular bizdan pastga namuna olish uchun qo'llab-quvvatlashni qachon qo'shishimizni so'rashadi. Bu erda bir nechta muammolar mavjud. Birinchidan, har bir foydalanuvchi tushunadi downsampling boshqa narsa: kimdir ma'lum oraliqda istalgan o'zboshimchalik nuqtasini olishni xohlaydi, kimdir maksimal, minimal, o'rtacha qiymatlarni xohlaydi. Agar ko'plab tizimlar ma'lumotlar bazasiga ma'lumotlarni yozsa, siz ularni birlashtira olmaysiz. Har bir tizim har xil noziklashtirishni talab qilishi mumkin. Va buni amalga oshirish qiyin.

Va ikkinchi narsa shundaki, VictoriaMetrics, xuddi ClickHouse kabi, katta hajmdagi xom ma'lumotlar ustida ishlash uchun optimallashtirilgan, shuning uchun tizimingizda ko'plab yadrolarga ega bo'lsangiz, u bir soniyadan kamroq vaqt ichida milliard qatorni siljitadi. VictoriaMetrics-da vaqt seriyasi nuqtalarini skanerlash - har bir yadro uchun sekundiga 50 000 000 ball. Va bu ishlash mavjud yadrolarga mos keladi. Ya'ni, agar sizda 20 ta yadro bo'lsa, masalan, soniyada milliard nuqtani skanerlaysiz. VictoriaMetrics va ClickHouse-ning bu xususiyati pastga tushirishga bo'lgan ehtiyojni kamaytiradi.

Yana bir xususiyat shundaki, VictoriaMetrics ushbu ma'lumotlarni samarali tarzda siqib chiqaradi. Ishlab chiqarishda o'rtacha siqilish har bir nuqta uchun 0,4 dan 0,8 baytgacha. Har bir nuqta vaqt belgisi + qiymatdir. Va u o'rtacha bir baytdan kamroq siqiladi.

Sergey. Menda sovol bor. Minimal yozish vaqti kvanti nima?

Bir millisekund. Biz yaqinda boshqa vaqt seriyalari ma'lumotlar bazasini ishlab chiquvchilari bilan suhbatlashdik. Ularning minimal vaqt oralig'i bir soniya. Masalan, Grafitda bu ham bir soniya. OpenTSDB da bu ham bir soniya. InfluxDB nanosekundlik aniqlikka ega. VictoriaMetrics-da bu bir millisekund, chunki Prometeyda bu bir millisekund. VictoriaMetrics dastlab Prometey uchun masofaviy saqlash sifatida ishlab chiqilgan. Ammo endi u boshqa tizimlardan ma'lumotlarni saqlashi mumkin.

Men gaplashgan odamning aytishicha, ular ikkinchi soniya aniqligiga ega - bu ular uchun etarli, chunki bu vaqt seriyalari ma'lumotlar bazasida saqlanadigan ma'lumotlar turiga bog'liq. Agar bu DevOps ma'lumotlari yoki infratuzilma ma'lumotlari bo'lsa, siz uni daqiqada 30 soniya oralig'ida to'playsiz, ikkinchi aniqlik kifoya qiladi, sizga kamroq narsa kerak emas. Va agar siz ushbu ma'lumotlarni yuqori chastotali savdo tizimlaridan to'plasangiz, unda nanosekundlik aniqlik kerak.

VictoriaMetrics-dagi millisekundlik aniqlik DevOps ishi uchun ham mos keladi va men hisobot boshida aytib o'tgan holatlarning aksariyati uchun mos bo'lishi mumkin. Bu mos kelmasligi mumkin bo'lgan yagona narsa - bu yuqori chastotali savdo tizimlari.

Rahmat! Va yana bir savol. PromQL da muvofiqlik nima?

To'liq orqaga qarab muvofiqlik. VictoriaMetrics PromQL-ni to'liq qo'llab-quvvatlaydi. Bundan tashqari, u PromQL-da qo'shimcha rivojlangan funksiyalarni qo'shadi, bu esa chaqiriladi MetricsQL. Ushbu kengaytirilgan funksiya haqida YouTube'da gap bor. Men bahorda Sankt-Peterburgda bo'lib o'tgan Monitoring Meetupda nutq so'zladim.

Telegram kanali VictoriaMetrics.

So'rovda faqat ro'yxatdan o'tgan foydalanuvchilar ishtirok etishlari mumkin. tizimga kirishiltimos.

Prometey uchun uzoq muddatli saqlash sifatida VictoriaMetrics-ga o'tishingizga nima to'sqinlik qilmoqda? (Izohlarda yozing, men uni so'rovnomaga qo'shaman))

  • 71,4%Men Prometey5 dan foydalanmayman

  • 28,6%VictoriaMetrics2 haqida bilmasdim

7 foydalanuvchi ovoz berdi. 12 nafar foydalanuvchi betaraf qolgan.

Manba: www.habr.com

a Izoh qo'shish