بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

پیشنهاد می کنم متن گزارش اواخر سال 2019 توسط الکساندر والیالکین "بهینه سازی های برو در ویکتوریا متریکس" را بخوانید.

ویکتوریا متریکس - یک DBMS سریع و مقیاس پذیر برای ذخیره و پردازش داده ها در قالب یک سری زمانی (رکورد زمان و مجموعه ای از مقادیر مربوط به این زمان را تشکیل می دهد، به عنوان مثال، از طریق نظرسنجی دوره ای وضعیت سنسورها یا جمع آوری معیارهای).

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

اینم لینک ویدیوی این گزارش - https://youtu.be/MZ5P21j_HLE

اسلایدها

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

از خودتان بگویید. من الکساندر والیالکین هستم. اینجا حساب GitHub من. من مشتاق Go و بهینه سازی عملکرد هستم. من بسیاری از کتابخانه های مفید و نه چندان مفید نوشتم. آنها با هر دو شروع می کنند fast، یا با quick پیشوند

من در حال حاضر روی VictoriaMetrics کار می کنم. چیست و من آنجا چه می کنم؟ من در این ارائه در مورد این صحبت خواهم کرد.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

خلاصه گزارش به شرح زیر است:

  • ابتدا به شما می گویم VictoriaMetrics چیست.
  • سپس به شما می گویم سری های زمانی چیست.
  • سپس به شما خواهم گفت که پایگاه داده سری زمانی چگونه کار می کند.
  • بعد، در مورد معماری پایگاه داده به شما خواهم گفت: از چه چیزی تشکیل شده است.
  • و سپس بیایید به بهینه سازی هایی که VictoriaMetrics دارد برویم. این یک بهینه‌سازی برای شاخص معکوس و یک بهینه‌سازی برای اجرای بیت‌ست در Go است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

آیا کسی از مخاطبان می داند VictoriaMetrics چیست؟ وای، خیلی ها از قبل می دانند. این یک خبر خوب است. برای کسانی که نمی دانند، این یک پایگاه داده سری زمانی است. این بر اساس معماری ClickHouse، بر اساس برخی از جزئیات اجرای ClickHouse است. به عنوان مثال، در مواردی مانند: MergeTree، محاسبه موازی بر روی تمام هسته های پردازنده موجود و بهینه سازی عملکرد با کار بر روی بلوک های داده ای که در حافظه پنهان پردازنده قرار می گیرند.

VictoriaMetrics فشرده سازی داده ها را بهتر از سایر پایگاه های داده سری زمانی ارائه می دهد.

به صورت عمودی مقیاس می شود - یعنی می توانید پردازنده های بیشتری، رم بیشتری را در یک رایانه اضافه کنید. 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، تعداد خطاها و غیره را اندازه گیری کنید.
  • اینترنت اشیا - ما می توانیم دما، فشار، مختصات جغرافیایی و چیزهای دیگر را اندازه گیری کنیم.
  • همچنین امور مالی - ما می‌توانیم قیمت‌ها را برای انواع سهام و ارز نظارت کنیم.
  • علاوه بر این می توان از سری های زمانی در نظارت بر فرآیندهای تولید در کارخانه ها استفاده کرد. ما کاربرانی داریم که از VictoriaMetrics برای نظارت بر توربین‌های بادی برای روبات‌ها استفاده می‌کنند.
  • سری های زمانی نیز برای جمع آوری اطلاعات از حسگرهای دستگاه های مختلف مفید هستند. به عنوان مثال، برای یک موتور؛ برای اندازه گیری فشار لاستیک؛ برای اندازه گیری سرعت، مسافت؛ برای اندازه گیری مصرف بنزین و غیره
  • همچنین می توان از سری های زمانی برای نظارت بر هواپیما استفاده کرد. هر هواپیما یک جعبه سیاه دارد که سری های زمانی پارامترهای مختلف سلامت هواپیما را جمع آوری می کند. سری های زمانی نیز در صنعت هوافضا استفاده می شوند.
  • مراقبت های بهداشتی فشار خون، نبض و غیره است.

ممکن است برنامه های بیشتری وجود داشته باشد که فراموش کرده ام، اما امیدوارم متوجه شده باشید که سری های زمانی به طور فعال در دنیای مدرن استفاده می شوند. و حجم استفاده از آنها هر سال در حال افزایش است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

چرا به پایگاه داده سری زمانی نیاز دارید؟ چرا نمی توانید از یک پایگاه داده رابطه ای معمولی برای ذخیره سری های زمانی استفاده کنید؟

زیرا سری های زمانی معمولا حاوی مقدار زیادی اطلاعات هستند که ذخیره و پردازش آن در پایگاه های داده معمولی مشکل است. بنابراین پایگاه‌های اطلاعاتی تخصصی سری‌های زمانی پدیدار شد. این پایه ها به طور موثر نقاط را ذخیره می کنند (timestamp, value) با کلید داده شده آنها یک API برای خواندن داده های ذخیره شده توسط کلید، توسط یک جفت کلید-مقدار واحد، یا توسط چندین جفت کلید-مقدار، یا توسط regexp ارائه می کنند. به عنوان مثال، شما می خواهید بار CPU تمام خدمات خود را در یک مرکز داده در آمریکا پیدا کنید، سپس باید از این شبه پرس و جو استفاده کنید.

معمولاً پایگاه‌های داده سری زمانی، زبان‌های پرس و جوی تخصصی را ارائه می‌دهند، زیرا سری زمانی SQL چندان مناسب نیست. اگرچه پایگاه داده هایی وجود دارند که از SQL پشتیبانی می کنند، اما چندان مناسب نیستند. زبان های پرس و جو مانند PromQL, InfluxQL, شار, Q. امیدوارم کسی حداقل یکی از این زبان ها را شنیده باشد. احتمالاً بسیاری از مردم در مورد PromQL شنیده اند. این زبان پرس و جو Prometheus است.

بهینه سازی در 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) که رشته را برای برش دادن اینت ها ترسیم می کند. خط شامل label=value.

اجرای تابع: دریافت metricIDs برای اولین label=value، سپس از همه چیزهای دیگر عبور می کنیم label=value، ما آن را دریافت می کنیم metricIDs برای آنها. و تابع را فراخوانی کنید intersectInts، که در ادامه به آن پرداخته خواهد شد. و این تابع محل تلاقی این لیست ها را برمی گرداند.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

همانطور که می بینید، پیاده سازی یک شاخص معکوس چندان پیچیده نیست. اما این یک اجرای ساده لوحانه است. چه معایبی دارد؟ نقطه ضعف اصلی اجرای ساده این است که چنین شاخص معکوس در RAM ذخیره می شود. پس از راه اندازی مجدد برنامه، این شاخص را از دست می دهیم. هیچ ذخیره ای از این شاخص در دیسک وجود ندارد. بعید است که چنین شاخص معکوس برای پایگاه داده مناسب باشد.

اشکال دوم نیز مربوط به حافظه است. شاخص معکوس باید در حافظه RAM قرار گیرد. اگر از اندازه RAM بیشتر شود، بدیهی است که خطای حافظه خارج می شود. و برنامه کار نخواهد کرد.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

این مشکل با استفاده از راه حل های آماده ای مانند LevelDBیا RocksDB.

به طور خلاصه، ما به یک پایگاه داده نیاز داریم که به ما امکان می دهد سه عملیات را به سرعت انجام دهیم.

  • اولین عملیات ضبط است ключ-значение به این پایگاه داده او این کار را خیلی سریع انجام می دهد، جایی که ключ-значение رشته های دلخواه هستند
  • عملیات دوم جستجوی سریع یک مقدار با استفاده از یک کلید داده شده است.
  • و عملیات سوم جستجوی سریع برای همه مقادیر با پیشوند معین است.

LevelDB و RocksDB - این پایگاه های داده توسط گوگل و فیس بوک توسعه داده شده اند. ابتدا LevelDB آمد. سپس بچه‌های فیسبوک LevelDB را گرفتند و شروع به بهبود آن کردند، RocksDB را ساختند. اکنون تقریباً تمام پایگاه‌های داده داخلی روی RocksDB در فیسبوک کار می‌کنند، از جمله آنهایی که به RocksDB و MySQL منتقل شده‌اند. اسمش را گذاشتند 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 و مجموعه های متریک آی دی های مربوطه را برای آنها دریافت کنید. سپس تقاطع را پیدا می کنیم.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

به نظر می رسد همه چیز خوب است، اما این راه حل دارای اشکالاتی است. VictoriaMetrics در ابتدا یک شاخص معکوس بر اساس LevelDB پیاده سازی کرد. اما در نهایت مجبور شدم آن را رها کنم.

چرا؟ زیرا LevelDB کندتر از پیاده سازی ساده است. در یک پیاده سازی ساده، با دادن یک کلید مشخص، ما بلافاصله کل برش را بازیابی می کنیم metricIDs. این یک عملیات بسیار سریع است - کل برش برای استفاده آماده است.

در LevelDB هر بار که یک تابع فراخوانی می شود GetValues باید تمام خطوطی که با آن شروع می شوند را مرور کنید label=value. و مقدار هر خط را بدست آورید timeseries_ids. از جمله timeseries_ids یک تکه از اینها را جمع کنید timeseries_ids. بدیهی است که این بسیار کندتر از دسترسی ساده به یک نقشه معمولی توسط کلید است.

دومین اشکال این است که LevelDB به زبان C نوشته شده است. فراخوانی توابع C از Go خیلی سریع نیست. صدها نانوثانیه طول می کشد. این خیلی سریع نیست، زیرا در مقایسه با یک فراخوانی تابع معمولی نوشته شده در go، که 1-5 نانوثانیه طول می کشد، تفاوت عملکرد ده ها برابر است. برای VictoriaMetrics این یک نقص مهلک بود :)

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

بنابراین من پیاده سازی خود را از شاخص معکوس نوشتم. و او را صدا زد ادغام.

Mergeset بر اساس ساختار داده MergeTree است. این ساختار داده از ClickHouse به عاریت گرفته شده است. بدیهی است که mergeset باید برای جستجوی سریع بهینه شود timeseries_ids با توجه به کلید داده شده Mergeset به طور کامل در Go نوشته شده است. میتوانی ببینی منابع VictoriaMetrics در GitHub. اجرای mergeset در پوشه است /lib/mergeset. می توانید سعی کنید بفهمید آنجا چه خبر است.

API mergeset بسیار شبیه به LevelDB و RocksDB است. یعنی به شما امکان می دهد رکوردهای جدید را به سرعت در آنجا ذخیره کنید و به سرعت رکوردها را با یک پیشوند مشخص انتخاب کنید.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

بعداً در مورد معایب mergeset صحبت خواهیم کرد. حال بیایید در مورد مشکلاتی که در هنگام اجرای یک شاخص معکوس با VictoriaMetrics در تولید ایجاد شد صحبت کنیم.

چرا به وجود آمدند؟

اولین دلیل، نرخ ریزش زیاد است. این یک تغییر مکرر در سری های زمانی است که به روسی ترجمه شده است. این زمانی است که یک سری زمانی به پایان می رسد و یک سری جدید شروع می شود، یا بسیاری از سری های زمانی جدید شروع می شوند. و این اغلب اتفاق می افتد.

دلیل دوم تعداد زیاد سری های زمانی است. در ابتدا، زمانی که نظارت در حال افزایش بود، تعداد سری های زمانی کم بود. به عنوان مثال، برای هر کامپیوتر شما نیاز به نظارت بر CPU، حافظه، شبکه و بار دیسک دارید. 4 سری زمانی در هر کامپیوتر. فرض کنید 100 کامپیوتر و 400 سری زمانی دارید. این خیلی کم است.

با گذشت زمان، مردم متوجه شدند که می توانند اطلاعات دقیق تری را اندازه گیری کنند. به عنوان مثال، بار کل پردازنده را نه، بلکه به طور جداگانه از هر هسته پردازنده اندازه گیری کنید. اگر 40 هسته پردازنده دارید، 40 برابر سری زمانی بیشتری برای اندازه گیری بار پردازنده دارید.

اما این همه ماجرا نیست. هر هسته پردازنده می تواند چندین حالت داشته باشد، مانند حالت بیکار، زمانی که بیکار است. و همچنین در فضای کاربر، کار در فضای هسته و سایر حالت ها کار کنید. و هر یک از این حالت ها را می توان به عنوان یک سری زمانی جداگانه نیز اندازه گیری کرد. این علاوه بر این تعداد ردیف ها را 7-8 برابر افزایش می دهد.

از یک متریک، تنها برای یک کامپیوتر، 40 x 8 = 320 معیار دریافت کردیم. با ضرب در 100 به جای 32 عدد 000 به دست می آید.

سپس Kubernetes آمد. و بدتر شد زیرا Kubernetes می تواند سرویس های مختلفی را میزبانی کند. هر سرویس در Kubernetes از پادهای زیادی تشکیل شده است. و همه اینها نیاز به نظارت دارد. علاوه بر این، ما به طور مداوم نسخه های جدید خدمات شما را به کار می گیریم. برای هر نسخه جدید، سری زمانی جدید باید ایجاد شود. در نتیجه تعداد سری های زمانی به صورت تصاعدی رشد می کند و با مشکل تعداد زیادی سری زمانی مواجه می شویم که به آن کاردینالیته بالا می گویند. VictoriaMetrics در مقایسه با سایر پایگاه‌های داده سری زمانی با آن کنار می‌آید.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

بیایید نگاهی دقیق تر به نرخ ریزش بالا بیندازیم. چه چیزی باعث افزایش نرخ ریزش در تولید می شود؟ زیرا برخی از معانی برچسب ها و برچسب ها دائما در حال تغییر هستند.

به عنوان مثال، Kubernetes را در نظر بگیرید که دارای مفهوم است deployment، یعنی زمانی که نسخه جدیدی از برنامه شما عرضه می شود. به دلایلی، توسعه دهندگان Kubernetes تصمیم گرفتند شناسه استقرار را به برچسب اضافه کنند.

این به چه چیزی منجر شد؟ علاوه بر این، با هر استقرار جدید، تمام سری‌های زمانی قدیمی قطع می‌شوند و به جای آن‌ها، سری‌های زمانی جدید با یک مقدار برچسب جدید شروع می‌شوند. deployment_id. می تواند صدها هزار و حتی میلیون ها ردیف از این قبیل وجود داشته باشد.

نکته مهم در مورد همه اینها این است که تعداد کل سری های زمانی رشد می کند، اما تعداد سری های زمانی که در حال حاضر فعال هستند و داده ها را دریافت می کنند ثابت می ماند. به این حالت نرخ ریزش زیاد می گویند.

مشکل اصلی نرخ بالا رفتن اطمینان از سرعت جستجوی ثابت برای تمام سری‌های زمانی برای مجموعه معینی از برچسب‌ها در یک بازه زمانی معین است. معمولاً این فاصله زمانی برای آخرین ساعت یا آخرین روز است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

چگونه این مسئله را می توان حل کرد؟ در اینجا اولین گزینه است. این برای تقسیم شاخص معکوس به بخش های مستقل در طول زمان است. یعنی چند بازه زمانی می گذرد، کار را با شاخص معکوس فعلی تمام می کنیم. و یک شاخص معکوس جدید ایجاد کنید. بازه زمانی دیگری می گذرد، دیگری و دیگری ایجاد می کنیم.

و هنگام نمونه برداری از این شاخص های معکوس، مجموعه ای از شاخص های معکوس را پیدا می کنیم که در بازه داده شده قرار می گیرند. و بر این اساس، شناسه سری زمانی را از آنجا انتخاب می کنیم.

این باعث صرفه جویی در منابع می شود زیرا ما مجبور نیستیم به قسمت هایی نگاه کنیم که در بازه زمانی داده شده قرار نمی گیرند. یعنی معمولاً اگر داده‌های ساعت آخر را انتخاب کنیم، برای بازه‌های زمانی قبلی از پرس‌وجوها صرفنظر می‌کنیم.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

گزینه دیگری برای حل این مشکل وجود دارد. این برای ذخیره کردن لیست جداگانه ای از شناسه سری های زمانی است که در آن روز رخ داده است.

مزیت این راه حل نسبت به راه حل قبلی این است که اطلاعات سری زمانی را که در طول زمان ناپدید نمی شوند، کپی نمی کنیم. آنها دائما حضور دارند و تغییر نمی کنند.

اشکال این است که چنین راه حلی برای پیاده سازی دشوارتر و اشکال زدایی دشوارتر است. و VictoriaMetrics این راه حل را انتخاب کرد. از نظر تاریخی اینگونه بود. این راه حل نیز در مقایسه با راه حل قبلی عملکرد خوبی دارد. زیرا این راه حل به دلیل اینکه لازم است داده های تکراری در هر پارتیشن برای سری های زمانی که تغییر نمی کنند، یعنی با گذشت زمان ناپدید نمی شوند، اجرا نشد. VictoriaMetrics در درجه اول برای مصرف فضای دیسک بهینه شده بود و اجرای قبلی مصرف فضای دیسک را بدتر کرد. اما این پیاده سازی برای به حداقل رساندن مصرف فضای دیسک مناسب تر است، بنابراین انتخاب شد.

مجبور شدم باهاش ​​بجنگم مبارزه این بود که در این پیاده سازی هنوز باید تعداد بسیار بیشتری را انتخاب کنید timeseries_ids برای داده ها نسبت به زمانی که شاخص معکوس زمان پارتیشن بندی شده است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

چگونه این مشکل را حل کردیم؟ ما آن را به روشی اصلی حل کردیم - با ذخیره چندین شناسه سری زمانی در هر ورودی شاخص معکوس به جای یک شناسه. یعنی کلید داریم label=value، که در هر سری زمانی رخ می دهد. و اکنون ما چندین را ذخیره می کنیم timeseries_ids در یک ورودی

در اینجا یک مثال است. قبلاً N ورودی داشتیم، اما اکنون یک ورودی داریم که پیشوند آن مانند همه ورودی‌های دیگر است. برای ورودی قبلی، مقدار شامل تمام شناسه های سری زمانی است.

این باعث شد تا سرعت اسکن چنین شاخص معکوس تا 10 برابر افزایش یابد. و به ما این امکان را داد که مصرف حافظه کش را کاهش دهیم، زیرا اکنون رشته را ذخیره می کنیم label=value فقط یک بار در حافظه نهان با هم N بار. و اگر خطوط طولانی را در برچسب‌ها و برچسب‌های خود ذخیره کنید، این خط می‌تواند بزرگ باشد، که Kubernetes دوست دارد آنها را در آنجا جابجا کند.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

گزینه دیگری برای افزایش سرعت جستجو در فهرست معکوس، اشتراک گذاری است. ایجاد چندین نمایه معکوس به جای یک و به اشتراک گذاری داده ها بین آنها توسط کلید. این یک مجموعه است key=value بخار. یعنی چندین شاخص وارونه مستقل دریافت می کنیم که می توانیم به صورت موازی در چندین پردازنده از آنها پرس و جو کنیم. پیاده‌سازی‌های قبلی فقط اجازه عملکرد در حالت تک پردازنده را می‌دادند، یعنی اسکن داده‌ها فقط روی یک هسته. این راه حل به شما اجازه می دهد تا داده ها را روی چندین هسته به طور همزمان اسکن کنید، همانطور که ClickHouse دوست دارد انجام دهد. این همان چیزی است که ما در نظر داریم اجرا کنیم.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

حالا بیایید به گوسفندمان برگردیم - به تابع تقاطع timeseries_ids. بیایید در نظر بگیریم که چه پیاده سازی هایی ممکن است وجود داشته باشد. این تابع به شما امکان می دهد پیدا کنید timeseries_ids برای یک مجموعه داده شده label=value.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

گزینه اول یک پیاده سازی ساده لوحانه است. دو حلقه تو در تو. در اینجا ما ورودی تابع را دریافت می کنیم intersectInts دو برش - a и b. در خروجی، باید محل تقاطع این برش ها را به ما برگرداند.

یک پیاده سازی ساده لوحانه به این شکل به نظر می رسد. ما روی همه مقادیر از برش تکرار می کنیم a، در داخل این حلقه تمام مقادیر slice را مرور می کنیم b. و ما آنها را با هم مقایسه می کنیم. اگر مطابقت داشته باشند، ما یک تقاطع پیدا کرده ایم. و آن را در آن ذخیره کنید result.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

معایب چیست؟ پیچیدگی درجه دوم اشکال اصلی آن است. به عنوان مثال، اگر ابعاد شما تکه ای باشد a и b یک میلیون در یک زمان، سپس این تابع هرگز به شما پاسخ نمی دهد. زیرا نیاز به انجام یک تریلیون تکرار دارد که حتی برای کامپیوترهای مدرن بسیار زیاد است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

اجرای دوم بر اساس نقشه است. ما نقشه ایجاد می کنیم. ما تمام مقادیر را از slice در این نقشه قرار می دهیم a. سپس در یک حلقه جداگانه از برش عبور می کنیم b. و بررسی می کنیم که آیا این مقدار از برش است یا خیر b در نقشه اگر وجود دارد، آن را به نتیجه اضافه کنید.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

مزایای آن چیست؟ مزیت این است که فقط پیچیدگی خطی وجود دارد. یعنی این تابع برای برش های بزرگتر بسیار سریعتر اجرا می شود. برای یک برش میلیونی، این تابع در 2 میلیون تکرار اجرا می شود، برخلاف تریلیون تکرار تابع قبلی.

نکته منفی این است که این تابع برای ایجاد این نقشه به حافظه بیشتری نیاز دارد.

دومین ایراد، سربار زیاد برای هش است. این ایراد چندان مشهود نیست. و برای ما نیز خیلی واضح نبود، بنابراین در ابتدا در VictoriaMetrics اجرای تقاطع از طریق نقشه بود. اما سپس نمایه سازی نشان داد که زمان پردازنده اصلی صرف نوشتن روی نقشه و بررسی وجود یک مقدار در این نقشه می شود.

چرا زمان CPU در این مکان ها تلف می شود؟ زیرا Go عملیات هش را روی این خطوط انجام می دهد. به این معنا که هش کلید را محاسبه می کند تا سپس به آن در یک شاخص معین در HashMap دسترسی پیدا کند. عملیات محاسبه هش در ده ها نانوثانیه کامل می شود. این برای VictoriaMetrics کند است.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

من تصمیم گرفتم یک بیت مجموعه بهینه سازی شده مخصوص این مورد را پیاده سازی کنم. این همان چیزی است که محل تلاقی دو برش اکنون به نظر می رسد. در اینجا ما یک مجموعه بیت ایجاد می کنیم. عناصر از اولین برش را به آن اضافه می کنیم. سپس وجود این عناصر را در برش دوم بررسی می کنیم. و آنها را به نتیجه اضافه کنید. یعنی تقریبا هیچ تفاوتی با مثال قبلی ندارد. تنها چیزی که در اینجا وجود دارد این است که ما دسترسی به نقشه را با توابع سفارشی جایگزین کردیم add и has.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

در نگاه اول به نظر می رسد که اگر قبلاً از یک نقشه استاندارد در آنجا استفاده می شد و سپس برخی از توابع دیگر فراخوانی می شد ، این باید کندتر کار کند ، اما پروفایل نشان می دهد که این مورد 10 برابر سریعتر از نقشه استاندارد در مورد VictoriaMetrics کار می کند.

علاوه بر این، در مقایسه با اجرای نقشه از حافظه بسیار کمتری استفاده می کند. زیرا ما بیت ها را به جای مقادیر هشت بایتی در اینجا ذخیره می کنیم.

عیب این پیاده سازی این است که آنقدر آشکار نیست، بی اهمیت نیست.

اشکال دیگری که ممکن است بسیاری متوجه آن نشوند این است که این پیاده سازی ممکن است در برخی موارد به خوبی کار نکند. یعنی برای یک مورد خاص، برای این مورد از تقاطع شناسه های سری زمانی VictoriaMetrics بهینه شده است. این بدان معنا نیست که برای همه موارد مناسب است. در صورت استفاده نادرست، نه افزایش عملکرد، بلکه خطای کمبود حافظه و کاهش سرعت عملکرد را دریافت خواهیم کرد.

بهینه سازی در 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 با مقدار hi-value مورد نیاز، سپس تابع را فراخوانی می کنیم addAlloc، که یک مورد جدید تولید می کند bucket، آن را به ساختار سطل اضافه کنید.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

این اجرای تابع است b32.add. شبیه اجرای قبلی است. مهم ترین 16 بیت و کم اهمیت ترین 16 بیت را محاسبه می کنیم.

سپس تمام 16 بیت بالایی را مرور می کنیم. ما کبریت پیدا می کنیم. و در صورت وجود تطابق متد add را فراخوانی می کنیم که در صفحه بعد برای آن در نظر می گیریم bucket16.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

و اینجا پایین ترین سطح است که باید تا حد امکان بهینه شود. برای محاسبه می کنیم uint64 مقدار شناسه در بیت برش و همچنین bitmask. این یک ماسک برای یک مقدار معین 64 بیتی است که می تواند برای بررسی وجود این بیت یا تنظیم آن استفاده شود. بررسی می کنیم که آیا این بیت تنظیم شده است یا خیر و آن را تنظیم می کنیم و حضور را برمی گردانیم. این پیاده سازی ما است که به ما امکان می دهد تا عملیات شناسه های متقاطع سری های زمانی را در مقایسه با نقشه های معمولی 10 برابر سرعت دهیم.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

علاوه بر این بهینه سازی، VictoriaMetrics بهینه سازی های بسیار دیگری نیز دارد. اکثر این بهینه‌سازی‌ها به دلایلی اضافه شدند، اما پس از پروفایل کد در تولید.

این قانون اصلی بهینه‌سازی است - با فرض وجود گلوگاه در اینجا، بهینه‌سازی را اضافه نکنید، زیرا ممکن است مشخص شود که گلوگاهی در آنجا وجود نخواهد داشت. بهینه سازی معمولاً کیفیت کد را کاهش می دهد. بنابراین، ارزش بهینه سازی را فقط پس از پروفایل و ترجیحاً در تولید دارد تا این داده واقعی باشد. اگر کسی علاقه‌مند است، می‌توانید به کد منبع VictoriaMetrics نگاه کنید و سایر بهینه‌سازی‌های موجود در آنجا را بررسی کنید.

بهینه سازی در VictoriaMetrics را انجام دهید. الکساندر والیالکین

من یک سوال در مورد بیت ست دارم. بسیار شبیه به پیاده سازی C++ vector bool، مجموعه بیت بهینه شده. پیاده سازی را از آنجا گرفتید؟

نه از اونجا نه هنگام اجرای این بیت‌ست، من با دانش ساختار این سری‌های زمانی ID که در VictoriaMetrics استفاده می‌شوند راهنمایی شدم. و ساختار آنها به گونه ای است که 32 بیت بالایی اساسا ثابت هستند. 32 بیت پایین در معرض تغییر هستند. هر چه بیت کمتر باشد، بیشتر اوقات می تواند تغییر کند. بنابراین، این پیاده سازی به طور خاص برای این ساختار داده بهینه شده است. پیاده سازی C++، تا آنجا که من می دانم، برای حالت کلی بهینه شده است. اگر برای حالت کلی بهینه سازی کنید، به این معنی است که برای یک مورد خاص بهینه ترین نخواهد بود.

همچنین توصیه می کنم گزارش الکسی میلووید را تماشا کنید. او حدود یک ماه پیش در مورد بهینه سازی در کلیک هاوس برای تخصص های خاص صحبت کرد. او فقط می‌گوید که در حالت کلی، یک پیاده‌سازی ++C یا برخی پیاده‌سازی‌های دیگر طوری طراحی شده است که به طور متوسط ​​در یک بیمارستان خوب کار کند. ممکن است بدتر از یک پیاده سازی خاص دانش مانند ما باشد، جایی که می دانیم 32 بیت برتر عمدتاً ثابت هستند.

من یک سوال دوم دارم. تفاوت اساسی با InfluxDB چیست؟

تفاوت های اساسی زیادی وجود دارد. از نظر کارایی و مصرف حافظه، InfluxDB در تست‌ها، مصرف حافظه را برای سری‌های زمانی با کاردینالیته بالا، ۱۰ برابر بیشتر نشان می‌دهد، در صورتی که تعداد زیادی از آن‌ها، مثلاً میلیون‌ها، داشته باشید. به عنوان مثال، VictoriaMetrics 10 گیگابایت در هر میلیون ردیف فعال مصرف می کند، در حالی که InfluxDB 1 گیگابایت مصرف می کند. و این یک تفاوت بزرگ است.

دومین تفاوت اساسی این است که 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 هنوز این را ندارد، اما معمولاً Prometheus قبل از آن است که در قوانین رمزگذاری مجدد می توان این کار را انجام داد.

برای مثال، در کار قبلی‌ام نیاز داشتم که تعداد رویدادها را در یک پنجره کشویی در یک ساعت گذشته بشمارم. مشکل این است که مجبور شدم یک پیاده سازی سفارشی در Go ایجاد کنم، یعنی یک سرویس برای شمارش این چیز. این سرویس در نهایت بی اهمیت بود، زیرا محاسبه آن دشوار است. در صورتی که نیاز به شمارش تعدادی در فواصل زمانی ثابت داشته باشید، پیاده سازی می تواند ساده باشد. اگر می خواهید رویدادها را در یک پنجره کشویی بشمارید، آنقدرها هم که به نظر می رسد ساده نیست. من فکر می کنم این هنوز در ClickHouse یا در پایگاه داده های timeseries پیاده سازی نشده است، زیرا پیاده سازی آن دشوار است.

و یک سوال دیگر ما فقط در مورد میانگین صحبت می کردیم، و من به یاد آوردم که زمانی چیزی به نام گرافیت با پسوند کربن وجود داشت. و او می‌دانست که چگونه داده‌های قدیمی را نازک کند، یعنی یک نقطه در دقیقه، یک نقطه در ساعت و غیره بگذارد. در اصل، اگر به داده‌های خام، به طور نسبی، برای یک ماه، و هر چیز دیگری نیاز داشته باشیم، این کاملاً راحت است. لاغر شدن . اما Prometheus و VictoriaMetrics از این قابلیت پشتیبانی نمی کنند. آیا برای حمایت از آن برنامه ریزی شده است؟ اگر نه، چرا که نه؟

ممنون بابت سوال کاربران ما این سوال را به صورت دوره ای می پرسند. آنها می پرسند چه زمانی پشتیبانی برای نمونه برداری پایین اضافه خواهیم کرد. در اینجا چندین مشکل وجود دارد. اولاً هر کاربر می فهمد downsampling چیزی متفاوت است: کسی می خواهد هر نقطه دلخواه را در یک بازه معین به دست آورد، کسی مقادیر حداکثر، حداقل و میانگین را می خواهد. اگر بسیاری از سیستم ها داده ها را در پایگاه داده شما می نویسند، نمی توانید همه آنها را با هم جمع کنید. ممکن است هر سیستم به نازک شدن متفاوتی نیاز داشته باشد. و اجرای این امر دشوار است.

و دومین نکته این است که VictoriaMetrics، مانند ClickHouse، برای کار با حجم زیادی از داده های خام بهینه شده است، بنابراین اگر هسته های زیادی در سیستم خود دارید، می تواند یک میلیارد خط را در کمتر از یک ثانیه بیل کند. اسکن نقاط سری زمانی در VictoriaMetrics – 50 نقطه در ثانیه در هر هسته. و این عملکرد به هسته های موجود مقیاس می شود. یعنی اگر مثلا 000 هسته داشته باشید در هر ثانیه یک میلیارد نقطه اسکن می کنید. و این ویژگی VictoriaMetrics و ClickHouse نیاز به downsamling را کاهش می دهد.

ویژگی دیگر این است که VictoriaMetrics به طور موثر این داده ها را فشرده می کند. فشرده سازی به طور متوسط ​​در تولید از 0,4 تا 0,8 بایت در هر نقطه است. هر نقطه یک مهر زمان + مقدار است. و به طور متوسط ​​به کمتر از یک بایت فشرده می شود.

سرگئی من یک سوال دارم. کوانتومی حداقل زمان ضبط چقدر است؟

یک میلی ثانیه اخیراً با سایر توسعه دهندگان پایگاه داده سری های زمانی گفتگویی داشتیم. حداقل برش زمانی آنها یک ثانیه است. و در گرافیت، برای مثال، آن نیز یک ثانیه است. در OpenTSDB نیز یک ثانیه است. InfluxDB دارای دقت نانوثانیه است. در VictoriaMetrics یک میلی ثانیه است، زیرا در Prometheus یک میلی ثانیه است. و VictoriaMetrics در ابتدا به عنوان ذخیره سازی از راه دور برای Prometheus توسعه داده شد. اما اکنون می تواند داده های سیستم های دیگر را ذخیره کند.

شخصی که با او صحبت کردم می‌گوید که دقت ثانیه به ثانیه دارد - این برای او کافی است زیرا بستگی به نوع داده‌ای دارد که در پایگاه داده سری زمانی ذخیره می‌شود. اگر این داده‌های DevOps یا داده‌های زیرساخت است، جایی که آن‌ها را در فواصل زمانی 30 ثانیه در دقیقه جمع‌آوری می‌کنید، پس دقت ثانیه کافی است، به چیزی کمتر نیاز ندارید. و اگر این داده ها را از سیستم های معاملاتی با فرکانس بالا جمع آوری کنید، به دقت نانوثانیه نیاز دارید.

دقت میلی ثانیه در VictoriaMetrics برای کیس DevOps نیز مناسب است و برای اکثر مواردی که در ابتدای گزارش به آنها اشاره کردم می تواند مناسب باشد. تنها چیزی که ممکن است برای آن مناسب نباشد، سیستم های معاملاتی با فرکانس بالا است.

متشکرم! و یه سوال دیگه سازگاری در PromQL چیست؟

سازگاری کامل به عقب VictoriaMetrics به طور کامل از PromQL پشتیبانی می کند. علاوه بر این، قابلیت های پیشرفته دیگری را در PromQL اضافه می کند که به آن گفته می شود MetricsQL. در مورد این قابلیت توسعه یافته در یوتیوب صحبتی وجود دارد. من در نشست نظارتی در بهار در سن پترزبورگ صحبت کردم.

کانال تلگرام ویکتوریا متریکس.

فقط کاربران ثبت نام شده می توانند در نظرسنجی شرکت کنند. ورود، لطفا.

چه چیزی شما را از تغییر به VictoriaMetrics به عنوان فضای ذخیره بلندمدت برای Prometheus باز می دارد؟ (در نظرات بنویسید، من آن را به نظرسنجی اضافه می کنم))

  • ٪۱۰۰من از Prometheus5 استفاده نمی کنم

  • ٪۱۰۰درباره VictoriaMetrics2 نمی دانستم

7 کاربر رای دادند. 12 کاربر رای ممتنع دادند.

منبع: www.habr.com

اضافه کردن نظر