VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Би танд Александр Валялкиний 2019 оны сүүлчээр хийсэн "VictoriaMetrics-д оновчлол хийх" тайлангийн хуулбарыг уншихыг санал болгож байна.

VictoriaMetrics - өгөгдлийг цаг хугацааны цуваа хэлбэрээр хадгалах, боловсруулахад зориулагдсан хурдан бөгөөд өргөтгөх боломжтой DBMS (бичлэг нь цаг хугацаа, энэ цагтай харгалзах утгын багцыг бүрдүүлдэг, жишээлбэл, мэдрэгчийн төлөвийг үе үе санал асуулга эсвэл цуглуулах замаар олж авсан) хэмжүүр).

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ тайлангийн видеоны холбоос энд байна - https://youtu.be/MZ5P21j_HLE

Слайд

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Бидэнд өөрийнхөө тухай яриач. Би бол Александр Валялкин. Энд миний GitHub данс. Би Go болон гүйцэтгэлийн оновчлолд дуртай. Би маш их хэрэгтэй, тийм ч хэрэггүй номын санг бичсэн. Тэд аль нэгээр нь эхэлдэг fast, эсвэл хамт quick угтвар.

Би одоо VictoriaMetrics дээр ажиллаж байна. Энэ юу вэ, би тэнд юу хийж байна вэ? Би энэ танилцуулгад энэ талаар ярих болно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Тайлангийн тойм нь дараах байдалтай байна.

  • Эхлээд би VictoriaMetrics гэж юу болохыг хэлэх болно.
  • Дараа нь би танд цагийн цуврал гэж юу болохыг хэлье.
  • Дараа нь би цаг хугацааны цуврал мэдээллийн сан хэрхэн ажилладагийг танд хэлэх болно.
  • Дараа нь би мэдээллийн сангийн архитектурын талаар танд хэлэх болно: энэ нь юунаас бүрддэг.
  • Дараа нь VictoriaMetrics-ийн оновчлол руу шилжье. Энэ нь урвуу индексийн оновчлол ба Go дахь битсетийн хэрэгжилтийн оновчлол юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Үзэгчдийн дунд VictoriaMetrics гэж юу болохыг мэддэг хүн байна уу? Хөөх, олон хүмүүс аль хэдийн мэддэг болсон. Сайхан мэдээ байна. Мэдэхгүй хүмүүсийн хувьд энэ бол цаг хугацааны цуврал мэдээллийн сан юм. Энэ нь ClickHouse-ийн архитектур, ClickHouse-ийн хэрэгжилтийн зарим нарийн ширийн зүйл дээр суурилдаг. Жишээлбэл, MergeTree, бүх боломжтой процессорын цөм дээр зэрэгцээ тооцоолол хийх, процессорын кэшэд байрлуулсан өгөгдлийн блокууд дээр ажиллах замаар гүйцэтгэлийг оновчтой болгох.

VictoriaMetrics нь бусад цагийн цуврал мэдээллийн сангаас илүү сайн өгөгдөл шахах боломжийг олгодог.

Энэ нь босоо байдлаар хэмжигддэг - өөрөөр хэлбэл та нэг компьютер дээр илүү олон процессор, илүү их RAM нэмж болно. VictoriaMetrics нь эдгээр нөөцийг амжилттай ашиглаж, шугаман бүтээмжийг сайжруулах болно.

VictoriaMetrics нь мөн хэвтээ байдлаар хэмжигддэг - өөрөөр хэлбэл та VictoriaMetrics кластерт нэмэлт зангилаа нэмэх боломжтой бөгөөд түүний гүйцэтгэл нь бараг шугаман байдлаар нэмэгдэх болно.

Таны таамаглаж байсанчлан VictoriaMetrics бол хурдан мэдээллийн сан, учир нь би бусдад бичиж чадахгүй. Энэ нь Go дээр бичигдсэн тул би энэ уулзалт дээр энэ тухай ярьж байна.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Цагийн цуваа гэж юу байдгийг хэн мэдэх вэ? Тэр бас олон хүнийг мэддэг. Хугацааны цуваа нь хосуудын цуваа юм (timestamp, значение), эдгээр хосуудыг цаг хугацаагаар нь эрэмбэлдэг. Утга нь хөвөгч цэгийн тоо - float64.

Цагийн цуваа бүрийг түлхүүрээр өвөрмөц байдлаар тодорхойлдог. Энэ түлхүүр юунаас бүрдэх вэ? Энэ нь түлхүүр-утга хосын хоосон бус багцаас бүрдэнэ.

Цаг хугацааны цувралын жишээ энд байна. Энэ цувралын гол зүйл бол хосуудын жагсаалт юм. __name__="cpu_usage" хэмжүүрийн нэр, instance="my-server" - энэ бол энэ хэмжигдэхүүнийг цуглуулсан компьютер юм. datacenter="us-east" - энэ бол энэ компьютер байрладаг мэдээллийн төв юм.

Бид гурван түлхүүр-утга хосоос бүрдсэн цагийн цувралын нэрээр төгсөв. Энэ түлхүүр нь хосуудын жагсаалттай тохирч байна (timestamp, value). t1, t3, t3, ..., tN - эдгээр нь цагийн тэмдэг, 10, 20, 12, ..., 15 - харгалзах утгууд. Энэ нь тухайн цувралын тухайн үеийн CPU-ийн хэрэглээ юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Цагийн цувааг хаана ашиглаж болох вэ? Ямар нэгэн санаа байгаа хүн байна уу?

  • DevOps дээр та CPU, RAM, сүлжээ, rps, алдааны тоо гэх мэтийг хэмжих боломжтой.
  • IoT - бид температур, даралт, гео координат болон бусад зүйлийг хэмжих боломжтой.
  • Мөн санхүү - бид бүх төрлийн хувьцаа, валютын үнийг хянах боломжтой.
  • Үүнээс гадна цаг хугацааны цувааг үйлдвэрүүдийн үйлдвэрлэлийн үйл явцыг хянахад ашиглаж болно. Бидэнд VictoriaMetrics ашиглан роботуудад зориулсан салхин турбиныг хянадаг хэрэглэгчид бий.
  • Цагийн цуваа нь янз бүрийн төхөөрөмжийн мэдрэгчээс мэдээлэл цуглуулахад хэрэгтэй. Жишээлбэл, хөдөлгүүрийн хувьд; дугуйны даралтыг хэмжих; хурд, зайг хэмжих; бензин зарцуулалтыг хэмжих гэх мэт.
  • Цагийн цувааг мөн агаарын хөлгийг хянахад ашиглаж болно. Онгоц бүр нь агаарын хөлгийн эрүүл мэндийн янз бүрийн үзүүлэлтүүдийн цаг хугацааны цувааг цуглуулдаг хар хайрцагтай. Цагийн цувааг сансар огторгуйн салбарт ч ашигладаг.
  • Эрүүл мэндийн тусламж үйлчилгээ нь цусны даралт, судасны цохилт гэх мэт.

Миний мартсан програмууд олон байж болох ч орчин үеийн ертөнцөд цагийн цуваа идэвхтэй ашиглагдаж байгааг та бүхэн ойлгож байгаа гэж найдаж байна. Мөн тэдний хэрэглээний хэмжээ жил бүр нэмэгдэж байна.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Яагаад танд цаг хугацааны цуврал мэдээллийн сан хэрэгтэй байна вэ? Та яагаад цагийн цувааг хадгалахын тулд ердийн харилцааны мэдээллийн санг ашиглаж болохгүй гэж?

Хугацааны цуваа нь ихэвчлэн их хэмжээний мэдээллийг агуулдаг учир ердийн мэдээллийн санд хадгалах, боловсруулахад хүндрэлтэй байдаг. Тиймээс цаг хугацааны цувралын тусгай мэдээллийн сан гарч ирэв. Эдгээр суурь нь цэгүүдийг үр дүнтэй хадгалдаг (timestamp, value) өгөгдсөн түлхүүрээр. Тэд хадгалагдсан өгөгдлийг түлхүүрээр, нэг түлхүүр-утга хосоор эсвэл олон түлхүүр-утга хосоор эсвэл regexp-ээр унших API-г өгдөг. Жишээлбэл, та Америк дахь дата төвөөс өөрийн бүх үйлчилгээний CPU-ийн ачааллыг олохыг хүсвэл энэ псевдо асуулга ашиглах хэрэгтэй.

Хугацааны цуврал мэдээллийн сан нь ихэвчлэн тусгайлсан асуулгын хэлээр хангадаг, учир нь цагийн цуврал SQL нь тийм ч тохиромжтой биш юм. Хэдийгээр SQL-г дэмждэг мэдээллийн сан байдаг ч энэ нь тийм ч тохиромжтой биш юм. гэх мэт хэлүүдийг асууна PromQL, InfluxQL, урсгал, Q. Хэн нэгэн эдгээр хэлнүүдийн ядаж нэгийг нь сонссон байх гэж найдаж байна. PromQL-ийн талаар олон хүн сонссон байх. Энэ бол Prometheus query хэл юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

VictoriaMetrics-ийг жишээ болгон ашигласан орчин үеийн цагийн цуврал мэдээллийн сангийн архитектур ийм харагдаж байна.

Энэ нь хоёр хэсгээс бүрдэнэ. Энэ нь урвуу индексийн хадгалалт ба хугацааны цувааны утгуудын хадгалалт юм. Эдгээр агуулахууд нь тусдаа байдаг.

Өгөгдлийн санд шинэ бичлэг ирэхэд бид эхлээд урвуу индекс рүү нэвтэрч өгөгдсөн багцын цагийн цувааны тодорхойлогчийг олдог. label=value өгөгдсөн хэмжүүрийн хувьд. Бид энэ танигчийг олж, өгөгдлийг мэдээллийн санд хадгалдаг.

TSDB-ээс мэдээлэл авах хүсэлт ирэхэд бид эхлээд урвуу индекс рүү очдог. Бүгдийг нь авцгаая timeseries_ids энэ багцад тохирсон бичлэгүүд label=value. Дараа нь бид шаардлагатай бүх өгөгдлийг өгөгдлийн агуулахаас индексжүүлсэн байдлаар авдаг timeseries_ids.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Хугацааны цувааны өгөгдлийн сан нь ирж буй сонгон шалгаруулах хүсэлтийг хэрхэн боловсруулдаг жишээг харцгаая.

  • Юуны өмнө тэр бүх зүйлийг олж авдаг timeseries_ids Өгөгдсөн хосуудыг агуулсан урвуу индексээс label=value, эсвэл өгөгдсөн тогтмол илэрхийллийг хангана.
  • Дараа нь өгөгдлийн сангаас олдсон бүх өгөгдлийн цэгүүдийг өгөгдсөн хугацааны интервалаар татаж авдаг timeseries_ids.
  • Үүний дараа мэдээллийн сан нь хэрэглэгчийн хүсэлтийн дагуу эдгээр өгөгдлийн цэгүүд дээр зарим тооцооллыг гүйцэтгэдэг. Үүний дараа хариултыг буцаана.

Энэ танилцуулгад би эхний хэсгийн талаар танд хэлэх болно. Энэ бол хайлт юм timeseries_ids урвуу индексээр. Та хоёр дахь хэсэг, гурав дахь хэсгийг дараа үзэх боломжтой VictoriaMetrics эх сурвалжууд, эсвэл өөр тайлан бэлтгэх хүртэл хүлээнэ үү :)

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Урвуутай индекс рүү шилжье. Олон хүмүүс үүнийг энгийн гэж бодож магадгүй юм. Урвуу индекс гэж юу болох, хэрхэн ажилладагийг хэн мэдэх вэ? Өө, тийм ч олон хүн байхгүй болсон. Энэ нь юу болохыг ойлгохыг хичээцгээе.

Энэ нь үнэндээ энгийн. Энэ бол зүгээр л утгын түлхүүрийг харуулсан толь бичиг юм. Түлхүүр гэж юу вэ? Энэ хос label=valueхаана label и value - эдгээр нь шугамууд юм. Мөн утгууд нь багц юм timeseries_ids, үүнд өгөгдсөн хос багтана label=value.

Урвуу индекс нь бүх зүйлийг хурдан олох боломжийг олгодог timeseries_ids, өгсөн label=value.

Мөн хурдан олох боломжийг танд олгоно timeseries_ids хэд хэдэн хосын цагийн цуваа label=value, эсвэл хосуудад зориулсан label=regexp. Энэ нь яаж болдог вэ? Олонлогийн огтлолцлыг олох замаар timeseries_ids хос бүрийн хувьд label=value.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Урвуу индексийн янз бүрийн хэрэгжилтийг харцгаая. Хамгийн энгийн гэнэн хэрэгжүүлэлтээс эхэлье. Тэр ийм харагдаж байна.

үйл ажиллагаа getMetricIDs мөрүүдийн жагсаалтыг авна. Мөр бүрийг агуулна label=value. Энэ функц нь жагсаалтыг буцаана metricIDs.

Хэрхэн ажилладаг? Энд бид глобал хувьсагчтай байна invertedIndex. Энэ бол ердийн толь бичиг (map), энэ нь мөрийг ints зүсэхийн тулд дүрслэх болно. Мөр нь агуулж байна label=value.

Функцийн хэрэгжилт: авах metricIDs эхнийх нь хувьд label=value, дараа нь бид бусад бүх зүйлийг даван туулдаг label=value, бид үүнийг ойлгож байна metricIDs тэдэнд. Мөн функцийг дууд intersectInts, үүнийг доор хэлэлцэх болно. Мөн энэ функц нь эдгээр жагсаалтын огтлолцлыг буцаана.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Таны харж байгаагаар урвуу индексийг хэрэгжүүлэх нь тийм ч төвөгтэй биш юм. Гэхдээ энэ бол гэнэн хэрэг явдал. Энэ нь ямар сул талуудтай вэ? Гэнэн хэрэгжүүлэлтийн гол сул тал нь ийм урвуу индексийг RAM-д хадгалдаг явдал юм. Програмыг дахин эхлүүлсний дараа бид энэ индексийг алддаг. Энэ индексийг дискэнд хадгалах боломжгүй. Ийм урвуу индекс нь мэдээллийн санд тохирохгүй байх магадлалтай.

Хоёр дахь дутагдал нь санах ойтой холбоотой юм. Урвуулагдсан индекс нь RAM-д багтах ёстой. Хэрэв энэ нь RAM-ийн хэмжээнээс хэтэрсэн бол бид санах ойн алдаа гарах болно. Тэгээд програм ажиллахгүй.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

гэх мэт бэлэн шийдлүүдийг ашиглан энэ асуудлыг шийдэж болно LevelDB, эсвэл RocksDB.

Товчхондоо гурван үйлдлийг хурдан хийх боломжтой мэдээллийн сан хэрэгтэй байна.

  • Эхний үйлдэл нь бичлэг хийх явдал юм ключ-значение энэ мэдээллийн санд. Тэр үүнийг маш хурдан хийдэг, хаана ключ-значение дурын мөрүүд юм.
  • Хоёрдахь үйлдэл нь өгөгдсөн түлхүүрийг ашиглан утгыг хурдан хайх явдал юм.
  • Гурав дахь үйлдэл нь өгөгдсөн угтвараар бүх утгыг хурдан хайх явдал юм.

LevelDB болон RocksDB - эдгээр мэдээллийн санг Google болон Facebook-ээс боловсруулсан. Эхлээд LevelDB гарч ирэв. Тэгээд фэйсбүүкийн залуус LevelDB аваад сайжруулж эхэлсэн, RocksDB хийсэн. Одоо бараг бүх дотоод мэдээллийн сан нь RocksDB болон MySQL-д шилжсэн зэрэг Facebook доторх RocksDB дээр ажилладаг. Тэд түүнийг нэрлэсэн MyRocks.

LevelDB ашиглан урвуу индексийг хэрэгжүүлж болно. Үүнийг хэрхэн хийх вэ? Бид түлхүүр болгон хадгалдаг label=value. Мөн утга нь тухайн хос байгаа хугацааны цувааны тодорхойлогч юм label=value.

Хэрэв бид өгөгдсөн хостой олон цагийн цуваатай бол label=value, дараа нь энэ мэдээллийн санд ижил түлхүүртэй, өөр өөр олон мөр байх болно timeseries_ids. Бүх жагсаалтыг авахын тулд timeseries_ids, үүнээс эхэлдэг label=prefix, бид энэ мэдээллийн санг оновчтой болгох мужийг скан хийдэг. Өөрөөр хэлбэл, бид эхэлсэн бүх мөрийг сонгоно label=prefix мөн шаардлагатай зүйлээ аваарай timeseries_ids.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Go-д ямар харагдахыг харуулсан жишээ жишээ энд байна. Бид урвуу индекстэй байна. Энэ бол LevelDB юм.

Функц нь гэнэн хэрэгжүүлэхтэй адил юм. Энэ нь гэнэн хэрэгжүүлэлтийг бараг мөр мөрөөр давтдаг. Цорын ганц зүйл бол эргэхийн оронд map бид урвуу индекс рүү ханддаг. Бид эхнийх нь бүх утгыг авдаг label=value. Дараа нь бид үлдсэн бүх хосуудыг дамжуулдаг label=value мөн тэдгээрт тохирох хэмжүүрийн ID-н багцыг аваарай. Дараа нь бид уулзварыг олно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Бүх зүйл сайхан байгаа мэт боловч энэ шийдэлд сул талууд бий. VictoriaMetrics анх LevelDB дээр суурилсан урвуу индексийг хэрэгжүүлсэн. Гэвч эцэст нь би түүнээс татгалзах хэрэгтэй болсон.

Яагаад? Учир нь LevelDB нь гэнэн хэрэгжүүлэлтээс удаан байдаг. Гэнэн хэрэгжүүлэлтийн хувьд өгөгдсөн түлхүүрийг бид нэн даруй бүхэл бүтэн зүсмэлийг гаргаж авдаг metricIDs. Энэ бол маш хурдан ажиллагаа юм - зүсмэлийг бүхэлд нь ашиглахад бэлэн байна.

LevelDB дээр функц дуудагдах болгонд GetValues гэж эхэлсэн бүх мөрийг давах хэрэгтэй label=value. Мөн мөр бүрийн утгыг аваарай timeseries_ids. Иймээс timeseries_ids эдгээрээс нэг хэсгийг цуглуул timeseries_ids. Энэ нь энгийн газрын зурагт товчлуураар хандахаас хамаагүй удаан байх нь ойлгомжтой.

Хоёрдахь дутагдал нь LevelDB нь C хэл дээр бичигдсэн байдаг. Go-оос C функцийг дуудах нь тийм ч хурдан биш юм. Үүнд хэдэн зуун наносекунд шаардлагатай. Энэ нь тийм ч хурдан биш, учир нь 1-5 наносекунд зарцуулдаг go-д бичигдсэн ердийн функцын дуудлагатай харьцуулахад гүйцэтгэлийн ялгаа нь хэдэн арван дахин их байдаг. VictoriaMetrics-ийн хувьд энэ нь аймшигтай алдаа байсан :)

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Тиймээс би урвуу индексийн өөрийн хэрэгжилтийг бичсэн. Тэгээд тэр түүнийг дуудсан нэгтгэх.

Mergeset нь MergeTree өгөгдлийн бүтэц дээр суурилдаг. Энэхүү өгөгдлийн бүтцийг ClickHouse-аас зээлсэн. Хурдан хайлт хийхэд mergeset-ийг оновчтой болгох нь ойлгомжтой timeseries_ids өгөгдсөн түлхүүрийн дагуу. Mergeset нь бүхэлдээ Go дээр бичигдсэн байдаг. Та харж болно GitHub дээрх VictoriaMetrics эх сурвалжууд. Mergeset-ийн хэрэгжилт хавтсанд байна /lib/mergeset. Та тэнд юу болж байгааг олж мэдэхийг оролдож болно.

Mergeset API нь LevelDB болон RocksDB-тэй маш төстэй юм. Өөрөөр хэлбэл, энэ нь танд шинэ бичлэгүүдийг хурдан хадгалах, өгөгдсөн угтвараар бичлэгийг хурдан сонгох боломжийг олгоно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Mergeset-ийн сул талуудын талаар бид дараа нь ярих болно. Одоо урвуу индексийг хэрэгжүүлэхэд VictoriaMetrics-ийн үйлдвэрлэлд ямар асуудал үүссэн талаар ярилцъя.

Тэд яагаад үүссэн бэ?

Эхний шалтгаан нь гацах өндөр түвшин юм. Орос хэл рүү орчуулбал энэ нь цаг хугацааны цувааг байнга өөрчлөх явдал юм. Энэ нь цаг хугацааны цуврал дуусч, шинэ цуврал эхлэх эсвэл олон шинэ цагийн цуваа эхэлдэг. Мөн энэ нь ихэвчлэн тохиолддог.

Хоёр дахь шалтгаан нь олон тооны цаг хугацааны цуваа юм. Мониторингийн ажил эхэндээ дэлгэрч байх үед цаг хугацааны цувралын тоо бага байсан. Жишээлбэл, компьютер бүрийн хувьд та CPU, санах ой, сүлжээ, дискний ачааллыг хянах хэрэгтэй. Нэг компьютерт 4 цагийн цуврал. Танд 100 компьютер, 400 цагийн цуврал байна гэж бодъё. Энэ бол маш бага.

Цаг хугацаа өнгөрөхөд хүмүүс илүү нарийн мэдээллийг хэмжиж чадна гэдгээ ойлгосон. Жишээлбэл, бүх процессорын ачааллыг хэмжинэ, харин процессорын цөм тус бүрийг тусад нь хэмжинэ. Хэрэв танд 40 процессор цөм байгаа бол процессорын ачааллыг хэмжих хугацаа 40 дахин их байна.

Гэхдээ энэ нь бүгд биш юм. Процессорын цөм бүр идэвхгүй байх үед сул зогсолт гэх мэт хэд хэдэн төлөвтэй байж болно. Мөн хэрэглэгчийн орон зайд ажиллах, цөмийн орон зай болон бусад мужид ажиллах. Мөн ийм төлөв бүрийг тусдаа хугацааны цуваа болгон хэмжиж болно. Энэ нь эгнээний тоог 7-8 дахин нэмэгдүүлнэ.

Нэг хэмжүүрээс бид зөвхөн нэг компьютерт 40 x 8 = 320 хэмжүүр авсан. 100-аар үржүүлбэл 32 биш 000 мянга болно.

Дараа нь Кубернетес гарч ирэв. Kubernetes олон төрлийн үйлчилгээг байршуулж чаддаг тул энэ нь улам дордов. Кубернетес дэх үйлчилгээ бүр нь олон тооны pods-ээс бүрдэнэ. Мөн энэ бүхэнд хяналт тавих шаардлагатай байна. Нэмж дурдахад бид таны үйлчилгээний шинэ хувилбаруудыг байнга байршуулж байна. Шинэ хувилбар бүрийн хувьд шинэ цагийн цуваа үүсгэх ёстой. Үүний үр дүнд цаг хугацааны цувааны тоо экспоненциалаар нэмэгдэж, бид олон тооны хугацааны цувралын асуудалтай тулгардаг бөгөөд үүнийг өндөр кардинал гэж нэрлэдэг. VictoriaMetrics нь бусад цагийн цуврал мэдээллийн сантай харьцуулахад үүнийг амжилттай даван туулж байна.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Өндөр уналтын хувь хэмжээг нарийвчлан авч үзье. Үйлдвэрлэлийн гацалт өндөр байгаа шалтгаан юу вэ? Яагаад гэвэл шошго, шошгоны зарим утга нь байнга өөрчлөгдөж байдаг.

Жишээлбэл, үзэл баримтлалтай Кубернетесийг ав deployment, өөрөөр хэлбэл таны програмын шинэ хувилбар гарах үед. Зарим шалтгааны улмаас Kubernetes-ийн хөгжүүлэгчид байршуулалтын ID-г шошгон дээр нэмэхээр шийджээ.

Энэ юунд хүргэсэн бэ? Түүнчлэн, шинэ байршуулалт бүрээр бүх хуучин цагийн цуваа тасалдаж, оронд нь шинэ цагийн цувралууд шинэ шошгоны утгаар эхэлдэг. deployment_id. Ийм эгнээ хэдэн зуун мянга, бүр сая сая байж болно.

Энэ бүхний хамгийн чухал зүйл бол нийт хугацааны цувааны тоо өсөх боловч одоогоор идэвхтэй байгаа болон өгөгдөл хүлээн авч байгаа хугацааны цувааны тоо тогтмол хэвээр байгаа явдал юм. Энэ төлөвийг өндөр уналт гэж нэрлэдэг.

Өндөр гацах түвшний гол асуудал нь тодорхой хугацааны интервалд өгөгдсөн шошгоны багцын бүх цагийн цувралын хайлтын хурдыг тогтмол байлгах явдал юм. Ихэвчлэн энэ нь сүүлийн нэг цаг эсвэл сүүлийн өдрийн хугацааны интервал юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ асуудлыг хэрхэн шийдвэрлэх вэ? Энд эхний сонголт байна. Энэ нь урвуу индексийг цаг хугацааны явцад бие даасан хэсгүүдэд хуваах явдал юм. Өөрөөр хэлбэл, тодорхой хугацааны интервал өнгөрч, бид одоогийн урвуу индекстэй ажиллаж дуусна. Мөн шинэ урвуу индекс үүсгэ. Өөр нэг хугацааны интервал өнгөрч, бид өөр нэгийг бий болгодог.

Эдгээр урвуу индексүүдээс түүвэрлэхдээ бид өгөгдсөн интервалд багтах урвуу индексүүдийн багцыг олдог. Үүний дагуу бид цаг хугацааны цувралын id-г тэндээс сонгоно.

Энэ нь өгөгдсөн интервалд багтахгүй хэсгүүдийг харах шаардлагагүй тул нөөцийг хэмнэдэг. Өөрөөр хэлбэл, хэрэв бид сүүлийн нэг цагийн өгөгдлийг сонговол өмнөх цагийн интервалын хувьд бид асуулга алгасах болно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ асуудлыг шийдэх өөр нэг хувилбар бий. Энэ нь тухайн өдөр тохиолдсон цаг хугацааны цувралын id-н жагсаалтыг өдөр бүрд тусад нь хадгалах явдал юм.

Энэ шийдлийн өмнөх шийдлээс давуу тал нь бид цаг хугацааны дараа алга болдоггүй цагийн цувааны мэдээллийг давхардуулдаггүй явдал юм. Тэд байнга байдаг бөгөөд өөрчлөгддөггүй.

Сул тал нь ийм шийдлийг хэрэгжүүлэхэд илүү төвөгтэй, дибаг хийхэд илүү хэцүү байдаг. Мөн VictoriaMetrics энэ шийдлийг сонгосон. Түүхэнд ийм л болсон. Энэ шийдэл нь өмнөхтэй харьцуулахад сайн ажилладаг. Учир нь энэ шийдэл нь өөрчлөгддөггүй, өөрөөр хэлбэл цаг хугацааны явцад алга болдоггүй цаг хугацааны цувралын хуваалт бүрт өгөгдлийг хуулбарлах шаардлагатай байдаг тул хэрэгжээгүй. VictoriaMetrics нь үндсэндээ дискний зай зарцуулалтыг оновчтой болгосон бөгөөд өмнөх хэрэгжүүлэлт нь дискний зайны хэрэглээг улам дордуулсан. Гэхдээ энэ хэрэгжилт нь дискний зайны хэрэглээг багасгахад илүү тохиромжтой тул үүнийг сонгосон.

Би түүнтэй тулалдах хэрэгтэй болсон. Тэмцэл нь энэ хэрэгжилтэд та илүү их тоог сонгох хэрэгтэй хэвээр байсан юм timeseries_ids өгөгдлийн хувьд урвуу индексийг цаг хугацаагаар хуваахаас илүү.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Бид энэ асуудлыг хэрхэн шийдсэн бэ? Бид үүнийг анхны аргаар шийдсэн - нэг танигчийн оронд урвуу индексийн оруулга бүрт хэд хэдэн цагийн цуврал танигчийг хадгалах замаар. Энэ нь бидэнд түлхүүр байгаа гэсэн үг label=value, энэ нь цаг хугацааны цуваа бүрт тохиолддог. Одоо бид хэд хэдэн зүйлийг хэмнэдэг timeseries_ids нэг оруулгад.

Энд нэг жишээ байна. Өмнө нь бид N оролттой байсан бол одоо бусадтай ижил угтвартай нэг оруулгатай боллоо. Өмнөх оруулгын хувьд утга нь бүх цагийн цувралын id-г агуулна.

Энэ нь ийм урвуу индексийн сканнердах хурдыг 10 дахин нэмэгдүүлэх боломжтой болгосон. Энэ нь кэшийн санах ойн хэрэглээг багасгах боломжийг бидэнд олгосон, учир нь одоо бид мөрийг хадгалдаг label=value зөвхөн нэг удаа кэш хамтдаа N удаа. Хэрэв та Кубернетес шошго, шошгондоо урт мөрүүдийг хадгалах юм бол энэ мөр том байж болно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Урвуутай индекс дээр хайлтыг хурдасгах өөр нэг сонголт бол sharding юм. Нэгийн оронд хэд хэдэн урвуу индекс үүсгэж, тэдгээрийн хооронд өгөгдлийг түлхүүрээр хуваах. Энэ бол багц юм key=value уур. Өөрөөр хэлбэл, бид хэд хэдэн процессор дээр зэрэгцэн асууж болох хэд хэдэн бие даасан урвуу индексийг авдаг. Өмнөх хэрэгжүүлэлтүүд нь зөвхөн нэг процессорын горимд ажиллахыг, өөрөөр хэлбэл зөвхөн нэг цөм дээрх өгөгдлийг сканнердахыг зөвшөөрдөг. Энэхүү шийдэл нь ClickHouse-ийн хийх дуртай нэгэн адил хэд хэдэн цөм дээрх өгөгдлийг нэг дор скан хийх боломжийг олгодог. Үүнийг бид хэрэгжүүлэхээр төлөвлөж байна.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Одоо хонь руугаа буцаж орцгооё - уулзварын функц timeseries_ids. Ямар хэрэгжилт байж болохыг авч үзье. Энэ функц нь олох боломжийг танд олгоно timeseries_ids өгөгдсөн багцын хувьд label=value.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Эхний сонголт бол гэнэн хэрэгжүүлэлт юм. Хоёр үүрлэсэн гогцоо. Энд бид функцийн оролтыг авна intersectInts хоёр зүсмэл - a и b. Гаралтын үед энэ нь эдгээр зүсмэлүүдийн огтлолцлыг бидэнд буцааж өгөх ёстой.

Гэнэн хэрэгжүүлэлт нь иймэрхүү харагдаж байна. Бид зүсмэлийн бүх утгыг давтдаг a, энэ гогцоонд бид зүсмэлийн бүх утгыг дамжуулдаг b. Мөн бид тэдгээрийг харьцуулдаг. Хэрэв тэд таарч байвал бид уулзвар олсон байна. Тэгээд хадгалаарай result.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Сул тал нь юу вэ? Квадрат нарийн төвөгтэй байдал нь түүний гол дутагдал юм. Жишээлбэл, хэрэв таны хэмжээсүүд зүсмэл байвал a и b нэг удаад нэг сая бол энэ функц танд хэзээ ч хариу өгөхгүй. Учир нь энэ нь нэг их наяд давталт хийх шаардлагатай болно, энэ нь орчин үеийн компьютеруудад ч их юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Хоёр дахь хэрэгжилт нь газрын зураг дээр суурилдаг. Бид газрын зураг үүсгэдэг. Бид зүсмэлийн бүх утгыг энэ газрын зурагт оруулав a. Дараа нь бид тусдаа гогцоонд зүсмэлүүдийг дамжуулдаг b. Мөн бид энэ утга нь зүсмэлээс байгаа эсэхийг шалгана b газрын зураг дээр. Хэрэв байгаа бол үр дүнд нь нэмнэ үү.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Ямар ашиг тустай вэ? Давуу тал нь зөвхөн шугаман нарийн төвөгтэй байдал юм. Өөрөөр хэлбэл, том зүсмэлүүдийн хувьд функц илүү хурдан ажиллах болно. Сая хэмжээтэй зүсмэлийн хувьд энэ функц нь өмнөх функцийн триллион давталтаас ялгаатай нь 2 сая давталтаар ажиллана.

Сул тал нь энэ функц нь энэ газрын зургийг бүтээхэд илүү их санах ой шаарддаг.

Хоёрдахь дутагдалтай тал бол хэш хийх их зардал юм. Энэ сул тал нь тийм ч тод биш юм. Бидний хувьд энэ нь тийм ч тодорхой биш байсан тул анх VictoriaMetrics-т уулзварын хэрэгжилтийг газрын зургаар дамжуулж байсан. Гэхдээ дараа нь профайл хийх нь процессорын үндсэн цагийг газрын зураг дээр бичиж, энэ газрын зураг дээр утга байгаа эсэхийг шалгахад зарцуулдаг болохыг харуулсан.

CPU-ийн цаг яагаад эдгээр газруудад дэмий үрэгдэж байна вэ? Учир нь Go эдгээр мөрөнд хэш хийх үйлдлийг гүйцэтгэдэг. Өөрөөр хэлбэл, HashMap дээрх өгөгдсөн индекст хандахын тулд түлхүүрийн хэшийг тооцдог. Хэш тооцоолох ажиллагаа хэдэн арван наносекундэд дуусна. VictoriaMetrics-ийн хувьд энэ нь удаан байна.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Би энэ тохиолдолд тусгайлан оновчтой болгосон битсетийг хэрэгжүүлэхээр шийдсэн. Хоёр зүсмэлийн огтлолцол одоо иймэрхүү харагдаж байна. Энд бид битсет үүсгэдэг. Бид эхний зүсмэлээс элементүүдийг нэмнэ. Дараа нь бид хоёр дахь зүсмэл дэх эдгээр элементүүд байгаа эсэхийг шалгана. Мөн тэдгээрийг үр дүнд нэмнэ. Энэ нь өмнөх жишээнээс бараг ялгаагүй гэсэн үг юм. Энд байгаа цорын ганц зүйл бол бид газрын зургийн хандалтыг тусгай функцээр сольсон явдал юм add и has.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Эхлээд харахад энэ нь илүү удаан ажиллах ёстой юм шиг санагддаг, хэрэв өмнө нь стандарт газрын зураг тэнд ашиглагдаж байсан бол дараа нь бусад функцууд дуудагддаг боловч профайл нь VictoriaMetrics-ийн хувьд стандарт газрын зургаас 10 дахин хурдан ажилладаг болохыг харуулж байна.

Нэмж дурдахад энэ нь газрын зургийн хэрэгжилттэй харьцуулахад хамаагүй бага санах ой ашигладаг. Учир нь бид энд найман байт утгын оронд битүүдийг хадгалдаг.

Энэ хэрэгжилтийн сул тал нь тийм ч тодорхой биш, өчүүхэн биш юм.

Олон хүмүүсийн анзаардаггүй өөр нэг дутагдал нь энэ хэрэгжилт нь зарим тохиолдолд сайн ажиллахгүй байх явдал юм. Өөрөөр хэлбэл, энэ нь VictoriaMetrics-ийн цаг хугацааны цуврал id-уудын огтлолцох тохиолдолд тодорхой тохиолдлоор оновчтой болсон. Энэ нь бүх тохиолдолд тохиромжтой гэсэн үг биш юм. Хэрэв үүнийг буруу ашиглавал бид гүйцэтгэлийн өсөлтийг авахгүй, харин санах ойн алдаа, гүйцэтгэл удаашрах болно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ бүтцийн хэрэгжилтийг авч үзье. Хэрэв та харахыг хүсвэл энэ нь VictoriaMetrics-ийн эх сурвалж, хавтсанд байрладаг lib/uint64set. Энэ нь VictoriaMetrics тохиолдолд тусгайлан оновчтой байдаг, хаана timeseries_id нь 64 битийн утга бөгөөд эхний 32 бит нь үндсэндээ тогтмол бөгөөд зөвхөн сүүлийн 32 бит өөрчлөгддөг.

Энэ өгөгдлийн бүтэц нь дискэнд хадгалагдаагүй, зөвхөн санах ойд ажилладаг.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энд түүний API байна. Энэ нь тийм ч төвөгтэй биш юм. API нь VictoriaMetrics-ийг ашиглах тодорхой жишээнд тусгайлан тохируулсан. Өөрөөр хэлбэл, энд шаардлагагүй функц байхгүй. VictoriaMetrics-ийн тодорхой ашигладаг функцууд энд байна.

Функцүүд байдаг add, энэ нь шинэ утгыг нэмдэг. Функц бий has, энэ нь шинэ утгыг шалгадаг. Мөн функц байдаг del, энэ нь утгыг устгадаг. Туслах функц байдаг len, энэ нь багцын хэмжээг буцаана. Чиг үүрэг clone маш их клон хийдэг. Мөн функц appendto энэ багцыг зүсмэл болгон хувиргадаг timeseries_ids.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ өгөгдлийн бүтцийг хэрэгжүүлэх нь иймэрхүү харагдаж байна. багц нь хоёр элементтэй:

  • ItemsCount нь олонлогийн элементийн тоог хурдан буцаах туслах талбар юм. Энэ туслах талбаргүйгээр үүнийг хийх боломжтой байсан ч VictoriaMetrics нь алгоритмдаа битсетийн уртыг байнга асуудаг тул энд нэмэх шаардлагатай болсон.

  • Хоёр дахь талбар нь buckets. Энэ бол бүтцийн зүсмэл юм bucket32. Бүтэц бүр хадгалдаг hi талбар. Эдгээр нь дээд 32 бит юм. Мөн хоёр зүсмэл - b16his и buckets нь bucket16 бүтэц.

16 битийн бүтцийн хоёр дахь хэсгийн дээд 64 бит энд хадгалагдана. Мөн энд бит бүрийн доод 16 битийн хувьд битсетүүд хадгалагддаг.

Bucket64 массиваас бүрдэнэ uint64. Эдгээр тогтмолуудыг ашиглан уртыг тооцоолно. Нэг дотор bucket16 дээд зэргээр хадгалах боломжтой 2^16=65536 жаахан. Хэрэв та үүнийг 8-д хуваавал 8 килобайт болно. Дахиад 8-д хуваавал 1000 болно uint64 утга учир. Тэр бол Bucket16 - энэ бол бидний 8 килобайт бүтэц юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Шинэ үнэ цэнийг нэмэх энэхүү бүтцийн аргуудын нэг нь хэрхэн хэрэгжиж байгааг харцгаая.

Энэ бүхэн үүнээс эхэлдэг uint64 утга. Бид дээд 32 битийг тооцоолж, доод 32 битийг тооцоолно. Бүгдийг нь авч үзье buckets. Бид хувин тус бүрийн шилдэг 32 битийг нэмсэн утгатай харьцуулдаг. Хэрэв тэдгээр нь таарч байвал бид функцийг дууддаг add b32 бүтцэд buckets. Тэнд доод 32 битийг нэмнэ үү. Тэгээд буцаж ирсэн бол true, тэгвэл энэ нь бид тэнд ийм үнэ цэнийг нэмсэн бөгөөд бидэнд тийм үнэ цэнэ байгаагүй гэсэн үг юм. Хэрэв буцаж ирвэл false, тэгвэл ийм утга аль хэдийн байсан. Дараа нь бид бүтцийн элементүүдийн тоог нэмэгдүүлнэ.

Хэрэв бид танд хэрэгтэй зүйлээ олоогүй бол bucket шаардлагатай өндөр утгатай бол функцийг дуудна addAlloc, энэ нь шинээр үйлдвэрлэх болно bucket, хувингийн бүтцэд нэмэх.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэ бол чиг үүргийн хэрэгжилт юм b32.add. Энэ нь өмнөх хэрэгжилттэй төстэй юм. Бид хамгийн чухал 16 бит, хамгийн бага ач холбогдолтой 16 битийг тооцдог.

Дараа нь бид бүх дээд 16 битийг дамждаг. Бид таарч олдог. Хэрэв тохирох зүйл байвал бид нэмэх аргыг дууддаг бөгөөд үүнийг дараагийн хуудсанд авч үзэх болно bucket16.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энд хамгийн доод түвшин байгаа бөгөөд үүнийг аль болох оновчтой болгох хэрэгтэй. Бид тооцоолно uint64 зүсмэлийн бит дэх id утгыг мөн түүнчлэн bitmask. Энэ нь өгөгдсөн 64 битийн утгын маск бөгөөд энэ бит байгаа эсэхийг шалгах эсвэл тохируулахад ашиглаж болно. Бид энэ бит тохируулагдсан эсэхийг шалгаж, тохируулаад байгаа эсэхийг шалгана. Энэ бол цаг хугацааны цувааны огтлолцох id-ийн ажиллагааг ердийн газрын зурагтай харьцуулахад 10 дахин хурдасгах боломжийг олгосон бидний хэрэгжүүлэлт юм.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Энэхүү оновчлолоос гадна VictoriaMetrics өөр олон оновчлолтой. Эдгээр оновчлолын ихэнх нь тодорхой шалтгааны улмаас нэмэгдсэн боловч кодыг үйлдвэрлэлд оруулсны дараа.

Энэ бол оновчлолын гол дүрэм юм - энд гацаа үүснэ гэж бодоод оновчлол нэмж болохгүй, учир нь тэнд саад бэрхшээл гарахгүй байж магадгүй юм. Оновчлол нь ихэвчлэн кодын чанарыг бууруулдаг. Тиймээс, энэ нь бодит өгөгдөл байхын тулд зөвхөн профайл хийсний дараа, үйлдвэрлэлд илүү оновчтой болгох нь зүйтэй юм. Хэрэв хэн нэгэн сонирхож байвал VictoriaMetrics-ийн эх кодыг үзэж, тэнд байгаа бусад оновчлолуудыг судалж болно.

VictoriaMetrics дээр оновчлол хийх. Александр Валялкин

Би битсетийн талаар асуулт байна. C++ вектор bool хэрэгжилттэй маш төстэй, оновчтой битсет. Тэндээс хэрэгжилтийг нь авсан уу?

Үгүй ээ, тэндээс биш. Энэ битсетийг хэрэгжүүлэхдээ би VictoriaMetrics-д хэрэглэгддэг эдгээр id-н цагийн цувааны бүтцийн талаарх мэдлэгийг удирдан чиглүүлсэн. Мөн тэдгээрийн бүтэц нь дээд 32 бит нь үндсэндээ тогтмол байдаг. Доод 32 битийг өөрчлөх боломжтой. Бит бага байх тусам энэ нь илүү олон удаа өөрчлөгдөж болно. Тиймээс энэхүү хэрэгжилтийг энэ өгөгдлийн бүтцэд тусгайлан оновчтой болгосон. Миний мэдэж байгаагаар C++ хэрэгжилт нь ерөнхий тохиолдолд оновчтой болсон. Хэрэв та ерөнхий тохиолдолд оновчтой болгох юм бол энэ нь тодорхой тохиолдолд хамгийн оновчтой биш байх болно гэсэн үг юм.

Би бас Алексей Миловидын илтгэлийг үзэхийг зөвлөж байна. Сар орчмын өмнө тэрээр ClickHouse-д тусгай мэргэжлээр оновчтой болгох талаар ярьж байсан. Тэр зүгээр л ерөнхий тохиолдолд C++ хэрэглүүр эсвэл өөр хэрэглүүр нь эмнэлэгт дунджаар сайн ажиллахад тохирсон байдаг гэж тэр хэллээ. Энэ нь манайх шиг мэдлэгт суурилсан хэрэгжилтээс илүү муу гүйцэтгэлтэй байж магадгүй бөгөөд бид шилдэг 32 бит нь ихэвчлэн тогтмол байдаг гэдгийг мэддэг.

Надад хоёр дахь асуулт байна. InfluxDB-ээс үндсэн ялгаа нь юу вэ?

Олон үндсэн ялгаа бий. Гүйцэтгэл болон санах ойн хэрэглээний хувьд InfluxDB тестүүд нь маш олон, жишээлбэл, сая сая байх үед өндөр кардиналтай цаг хугацааны цувралуудын санах ойн хэрэглээг 10 дахин их харуулдаг. Жишээлбэл, VictoriaMetrics нэг сая идэвхтэй мөр тутамд 1 ГБ зарцуулдаг бол InfluxDB 10 ГБ зарцуулдаг. Мөн энэ нь маш том ялгаа юм.

Хоёрдахь үндсэн ялгаа нь InfluxDB нь Flux болон InfluxQL гэсэн хачирхалтай хайлтын хэлтэй байдаг. Эдгээр нь цаг хугацааны цуваатай харьцуулахад тийм ч тохиромжтой биш юм PromQL, үүнийг VictoriaMetrics дэмждэг. PromQL бол Prometheus-ийн асуулгын хэл юм.

Бас нэг ялгаа нь InfluxDB нь бага зэрэг хачирхалтай өгөгдлийн загвартай бөгөөд мөр бүр өөр өөр шошго бүхий хэд хэдэн талбарыг хадгалах боломжтой юм. Эдгээр мөрүүдийг цааш нь янз бүрийн хүснэгтэд хуваана. Эдгээр нэмэлт хүндрэлүүд нь энэ мэдээллийн сантай дараагийн ажлыг улам хүндрүүлдэг. Үүнийг дэмжих, ойлгоход хэцүү байдаг.

VictoriaMetrics-д бүх зүйл илүү хялбар байдаг. Тэнд хугацааны цуваа бүр түлхүүр-утга юм. Утга нь цэгүүдийн багц юм - (timestamp, value), гол нь багц юм label=value. Талбай болон хэмжилтийн хооронд ямар ч ялгаа байхгүй. Энэ нь ямар ч өгөгдлийг сонгох, дараа нь InfluxDB-ээс ялгаатай нь нэгтгэх, нэмэх, хасах, үржүүлэх, хуваах боломжийг олгодог бөгөөд энэ нь миний мэдэж байгаагаар өөр өөр мөр хоорондын тооцоо хийгдээгүй хэвээр байна. Тэдгээрийг хэрэгжүүлсэн ч хэцүү, маш их код бичих хэрэгтэй.

Надад тодруулах асуулт байна. Таны яриад байгаа ямар нэг асуудал байна, энэ урвуу индекс санах ойд багтахгүй, тэнд хуваалт байна гэдгийг би зөв ойлгосон уу?

Эхлээд би стандарт Go газрын зураг дээр урвуу индексийн гэнэн хэрэгжүүлэлтийг харуулсан. Урвуулагдсан индекс нь дискэнд хадгалагдаагүй тул мэдээллийн санд энэ хэрэгжүүлэлт нь тохиромжгүй бөгөөд өгөгдлийн сан нь дискэнд хадгалагдах ёстой бөгөөд ингэснээр дахин эхлүүлэх үед энэ өгөгдөл бэлэн хэвээр байх ёстой. Энэ хэрэгжилтийн үед та програмыг дахин эхлүүлэх үед таны урвуу индекс алга болно. Мөн та олох боломжгүй тул бүх өгөгдөлд хандах эрхээ алдах болно.

Сайн уу? Мэдээлэл өгсөнд баярлалаа! Намайг Павел гэдэг. Би Wildberries-ээс ирсэн. Би чамаас хэдэн асуулт асууя. Асуулт нэг. Хэрэв та програмынхаа архитектурыг бүтээхдээ өөр зарчмыг сонгож, өгөгдлийг цаг хугацааны явцад хуваах байсан бол зөвхөн нэг хуваалт нь нэг хуваалтад өгөгдөл агуулж байгаа тул хайлт хийхдээ өгөгдлийг огтолж чадах байсан гэж бодож байна уу? цаг хугацаа, өөрөөр хэлбэл нэг хугацааны интервалд байх бөгөөд таны хэсгүүд өөр өөр тархсан байна гэж санаа зовох хэрэггүй гэж үү? Асуултын дугаар 2 - Та битсет болон бусад бүх зүйлтэй ижил төстэй алгоритмыг хэрэгжүүлж байгаа тул процессорын зааврыг ашиглахыг оролдсон болов уу? Магадгүй та ийм оновчлолыг туршиж үзсэн үү?

Би хоёр дахь асуултанд шууд хариулах болно. Бид одоохондоо тийм хэмжээнд хүрээгүй байна. Гэхдээ шаардлагатай бол бид тэнд очих болно. Тэгээд эхнийх нь ямар асуулт байсан бэ?

Та хоёр хувилбарыг хэлэлцсэн. Тэгээд тэд хоёр дахь нь илүү төвөгтэй хэрэгжилтийг сонгосон гэж хэлсэн. Тэд өгөгдөл нь цаг хугацаагаар хуваагддаг эхнийхийг нь илүүд үзээгүй.

Тиймээ. Эхний тохиолдолд индексийн нийт хэмжээ илүү их байх болно, учир нь бид хуваалт бүрт эдгээр бүх хуваалтуудаар үргэлжилдэг цаг хугацааны цувралын давхардсан өгөгдлийг хадгалах шаардлагатай болно. Хэрэв таны цаг хугацааны цуваа гацах хурд бага бол, өөрөөр хэлбэл ижил цувралуудыг байнга ашигладаг бол эхний тохиолдолд бид хоёр дахь тохиолдолтой харьцуулахад эзэлдэг дискний зайг их хэмжээгээр алдах болно.

Тиймээс - тийм ээ, цагийг хуваах нь сайн сонголт юм. Прометей үүнийг ашигладаг. Гэхдээ Прометейд бас нэг сул тал бий. Эдгээр өгөгдлийн хэсгүүдийг нэгтгэхдээ бүх шошго, цагийн цувааны мета мэдээллийг санах ойд хадгалах шаардлагатай. Тиймээс хэрэв нэгтгэсэн өгөгдлийн хэсгүүд нь том бол VictoriaMetrics-ээс ялгаатай нь нэгтгэх явцад санах ойн хэрэглээ маш их нэмэгддэг. Нэгтгэх үед VictoriaMetrics санах ой огт хэрэглэдэггүй; нэгтгэсэн өгөгдлийн хэсгүүдийн хэмжээнээс үл хамааран хэдхэн килобайт зарцуулдаг.

Таны ашиглаж буй алгоритм санах ойг ашигладаг. Энэ нь утгыг агуулсан цаг хугацааны шошгыг тэмдэглэдэг. Ингэснээр та нэг өгөгдлийн массив болон нөгөө өгөгдлийн массив дахь хосолсон байгаа эсэхийг шалгана. Мөн та огтлолцсон эсэхийг ойлгож байна. Ерөнхийдөө мэдээллийн сан нь одоогийн агуулгыг хадгалах курсор, давталтуудыг хэрэгжүүлдэг бөгөөд эдгээр үйлдлүүдийн энгийн нарийн төвөгтэй байдлаас шалтгаалан эрэмбэлэгдсэн өгөгдлийг дамжуулдаг.

Бид яагаад өгөгдөл дамжуулахын тулд курсор ашигладаггүй юм бэ?

Тиймээ.

Бид эрэмбэлсэн мөрүүдийг LevelDB эсвэл mergeset-д хадгалдаг. Бид курсорыг хөдөлгөж, уулзварыг олох боломжтой. Бид яагаад үүнийг ашиглахгүй байгаа юм бэ? Учир нь энэ нь удаан. Учир нь курсор нь мөр бүрт функц дуудах шаардлагатай гэсэн үг юм. Функцийн дуудлага нь 5 наносекунд юм. Хэрэв танд 100 мөр байгаа бол бид функцийг дуудахад хагас секунд зарцуулдаг.

Ийм зүйл байдаг, тийм ээ. Тэгээд миний сүүлчийн асуулт. Асуулт жаахан хачирхалтай сонсогдож магадгүй юм. Өгөгдөл ирэх тэр мөчид шаардлагатай бүх нэгтгэлийг уншиж, шаардлагатай хэлбэрээр хадгалах нь яагаад боломжгүй юм бэ? Яагаад VictoriaMetrics, ClickHouse гэх мэт зарим системд асар их хэмжээг хэмнээд дараа нь тэдэнд маш их цаг зарцуулдаг вэ?

Илүү ойлгомжтой болгохын тулд би жишээ хэлье. Жижиг тоглоомын хурд хэмжигч хэрхэн ажилладагийг хэлье? Энэ нь таны туулсан зайг бүртгэж, нэг утгад нэмж, хоёр дахь удаагаа бүртгэдэг. Тэгээд хуваадаг. Мөн дундаж хурдыг авдаг. Та ижил зүйлийг хийж болно. Шаардлагатай бүх баримтуудыг шууд нэмж оруулаарай.

За, би асуултыг ойлгож байна. Таны жишээ өөрийн гэсэн байр суурийг эзэлдэг. Хэрэв та ямар агрегатууд хэрэгтэйг мэддэг бол энэ нь хамгийн сайн хэрэглүүр юм. Гэхдээ асуудал нь хүмүүс эдгээр хэмжигдэхүүн, зарим өгөгдлийг ClickHouse-д хадгалдаг бөгөөд ирээдүйд тэдгээрийг хэрхэн нэгтгэж, шүүхээ мэдэхгүй байгаа тул бүх түүхий өгөгдлийг хадгалах хэрэгтэй болдог. Гэхдээ хэрэв та ямар нэг зүйлийг дунджаар тооцоолох хэрэгтэй гэдгийг мэдэж байгаа бол олон тооны түүхий утгыг хадгалахын оронд яагаад тооцоолж болохгүй гэж? Гэхдээ энэ нь танд яг юу хэрэгтэй байгааг мэдэж байгаа тохиолдолд л болно.

Дашрамд хэлэхэд, цаг хугацааны цуваа хадгалах мэдээллийн сан нь агрегатуудын тооллогыг дэмждэг. Жишээлбэл, Прометей дэмждэг бичлэг хийх дүрэм. Өөрөөр хэлбэл, танд ямар нэгж хэрэгтэй болохыг мэдэж байвал үүнийг хийж болно. VictoriaMetrics-т хараахан ийм зүйл байхгүй, гэхдээ үүнийг ихэвчлэн Прометей гэж нэрлэдэг бөгөөд үүнийг дахин кодлох дүрэмд хийж болно.

Жишээлбэл, би өмнөх ажилдаа сүүлийн нэг цагийн турш гулсах цонхон дээрх үйл явдлын тоог тоолох шаардлагатай болсон. Асуудал нь би Go-д захиалгат хэрэгжүүлэлт, өөрөөр хэлбэл энэ зүйлийг тоолох үйлчилгээ хийх шаардлагатай болсон явдал юм. Энэ үйлчилгээ нь эцсийн дүндээ энгийн зүйл биш байсан, учир нь үүнийг тооцоолоход хэцүү байдаг. Тогтмол хугацааны интервалаар зарим дүүргэгчийг тоолох шаардлагатай бол хэрэгжилт нь энгийн байж болно. Хэрэв та гүйдэг цонхонд үйл явдлыг тоолохыг хүсч байвал энэ нь санагдсан шиг тийм ч хялбар биш юм. Үүнийг ClickHouse эсвэл цагийн цуврал мэдээллийн санд хараахан хэрэгжүүлээгүй байгаа гэж би бодож байна, учир нь үүнийг хэрэгжүүлэхэд хэцүү байдаг.

Бас нэг асуулт. Бид зүгээр л дундажлах тухай ярьж байсан бөгөөд би нэг удаа нүүрстөрөгчийн арын хэсэгтэй графит гэж байсан гэдгийг санав. Мөн тэрээр хуучин өгөгдлийг хэрхэн нимгэрүүлэхээ мэддэг байсан, өөрөөр хэлбэл минут тутамд нэг цэг, цагт нэг цэг үлдээх гэх мэт. Зарчмын хувьд, харьцангуйгаар нэг сарын турш түүхий өгөгдөл хэрэгтэй бол энэ нь маш тохиромжтой бөгөөд бусад бүх зүйл боломжтой. нимгэрэх. Гэхдээ Prometheus болон VictoriaMetrics энэ функцийг дэмждэггүй. Үүнийг дэмжихээр төлөвлөж байгаа юу? Үгүй бол яагаад болохгүй гэж?

Асуулт тавьсанд баярлалаа. Манай хэрэглэгчид энэ асуултыг үе үе асуудаг. Тэд биднээс доош түүвэрлэлтийн дэмжлэгийг хэзээ нэмэх вэ гэж асуудаг. Энд хэд хэдэн асуудал байна. Нэгдүгээрт, хэрэглэгч бүр ойлгодог downsampling өөр зүйл: хэн нэгэн өгөгдсөн интервал дээр дурын цэгийг авахыг хүсдэг, хэн нэгэн хамгийн их, хамгийн бага, дундаж утгыг хүсдэг. Хэрэв олон систем таны мэдээллийн санд өгөгдөл бичдэг бол та бүгдийг нэгтгэж чадахгүй. Систем бүр өөр өөр сийрэгжилтийг шаарддаг байж магадгүй юм. Мөн үүнийг хэрэгжүүлэхэд хэцүү байдаг.

Хоёрдахь зүйл бол VictoriaMetrics нь ClickHouse шиг их хэмжээний түүхий өгөгдөл дээр ажиллахад оновчтой байдаг тул хэрэв таны системд олон цөм байгаа бол энэ нь нэг секундээс бага хугацаанд тэрбум мөрийг шүүж чадна. VictoriaMetrics дахь хугацааны цуврал цэгүүдийг сканнердаж байна – цөм тутамд секундэд 50 оноо. Мөн энэ гүйцэтгэл нь одоо байгаа цөмд хүрдэг. Жишээлбэл, хэрэв та 000 цөмтэй бол секундэд нэг тэрбум цэгийг сканнердах болно. VictoriaMetrics болон ClickHouse-ийн энэхүү өмч нь түүврийн хэмжээг багасгах хэрэгцээг бууруулдаг.

Өөр нэг онцлог нь VictoriaMetrics нь энэ өгөгдлийг үр дүнтэй шахдаг. Үйлдвэрлэлийн шахалт дунджаар нэг цэгт 0,4-0,8 байт байна. Цэг бүр нь цагийн тэмдэг + утга юм. Мөн энэ нь дунджаар нэг байт хүрэхгүй шахагдсан байдаг.

Сергей. Надад асуулт байна. Хамгийн бага бичлэг хийх квант гэж юу вэ?

Нэг миллисекунд. Бид саяхан бусад цагийн цуврал мэдээллийн баазын хөгжүүлэгчидтэй ярилцсан. Тэдний хамгийн бага хугацаа нь нэг секунд байна. Жишээлбэл, Графит дээр энэ нь бас нэг секунд юм. OpenTSDB-д энэ нь бас нэг секунд юм. InfluxDB нь нано секундын нарийвчлалтай. VictoriaMetrics-д энэ нь нэг миллисекунд, учир нь Прометейд энэ нь нэг миллисекунд юм. VictoriaMetrics нь анх Prometheus-д зориулсан алсын зайн хадгалах сан болгон бүтээгдсэн. Харин одоо бусад системүүдийн өгөгдлийг хадгалах боломжтой.

Миний ярилцсан хүн тэд хоёр дахь секундын нарийвчлалтай гэж хэлсэн - энэ нь цаг хугацааны цуврал мэдээллийн санд хадгалагдаж буй өгөгдлийн төрлөөс хамаардаг тул энэ нь тэдэнд хангалттай юм. Хэрэв энэ нь DevOps өгөгдөл эсвэл дэд бүтцийн өгөгдөл юм бол та үүнийг минут тутамд 30 секундын интервалтайгаар цуглуулдаг бол хоёр дахь нарийвчлал хангалттай, танд үүнээс бага зүйл хэрэггүй. Хэрэв та өндөр давтамжийн арилжааны системээс энэ өгөгдлийг цуглуулж байгаа бол танд нано секундын нарийвчлал хэрэгтэй.

VictoriaMetrics дахь миллисекундын нарийвчлал нь DevOps тохиолдолд тохиромжтой бөгөөд тайлангийн эхэнд миний дурдсан ихэнх тохиолдлуудад тохиромжтой байж болно. Энэ нь тохиромжгүй цорын ганц зүйл бол өндөр давтамжийн арилжааны систем юм.

Баярлалаа! Бас өөр асуулт. PromQL-д нийцтэй байдал гэж юу вэ?

Бүрэн буцаах нийцтэй байдал. VictoriaMetrics нь PromQL-ийг бүрэн дэмждэг. Нэмж дурдахад энэ нь PromQL-д нэмэлт дэвшилтэт функцийг нэмдэг бөгөөд үүнийг гэж нэрлэдэг MetricsQL. Энэхүү өргөтгөсөн функцын талаар YouTube дээр яриа байдаг. Би хавар Санкт-Петербургт болсон Мониторингийн уулзалт дээр үг хэлсэн.

Telegram суваг VictoriaMetrics.

Зөвхөн бүртгэлтэй хэрэглэгчид санал асуулгад оролцох боломжтой. Нэвтрэх, гуйя.

Prometheus-ийн урт хугацааны хадгалах сан болох VictoriaMetrics руу шилжихэд юу саад болж байна вэ? (Сэтгэгдэл хэсэгт бичээрэй, би үүнийг санал асуулгад оруулах болно))

  • 71,4%Би Prometheus5 ашигладаггүй

  • 28,6%VictoriaMetrics2-ийн талаар мэдэхгүй байсан

7 хэрэглэгч санал өгсөн. 12 хэрэглэгч түдгэлзсэн.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх