اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

أقترح قراءة نص تقرير نهاية عام 2019 بقلم ألكسندر فاليالكين "تحسينات الانتقال في VictoriaMetrics"

فيكتورياميتريكس - نظام DBMS سريع وقابل للتطوير لتخزين البيانات ومعالجتها في شكل سلسلة زمنية (يشكل السجل وقتًا ومجموعة من القيم المقابلة لهذا الوقت ، على سبيل المثال ، تم الحصول عليها من خلال استطلاع دوري لحالة أجهزة الاستشعار أو مجموعة المقاييس).

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

هنا رابط الفيديو الخاص بهذا التقرير - https://youtu.be/MZ5P21j_HLE

الشرائح

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

أخبرنا عن نفسك. أنا الكسندر فاليالكين. هنا حساب جيثب الخاص بي. أنا متحمس بشأن 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 هي القيم المقابلة. هذا هو استخدام وحدة المعالجة المركزية الحالي للصف المحدد.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

أين يمكن استخدام السلاسل الزمنية؟ هل يوجد لدى أحد أي فكرة؟

  • في DevOps ، يمكنك قياس وحدة المعالجة المركزية وذاكرة الوصول العشوائي والشبكة و rps والأخطاء وما إلى ذلك.
  • إنترنت الأشياء - يمكننا قياس درجة الحرارة والضغط والإحداثيات الجغرافية وشيء آخر.
  • التمويل أيضًا - يمكننا مراقبة أسعار جميع أنواع الأسهم والعملات.
  • بالإضافة إلى ذلك ، يمكن استخدام السلاسل الزمنية في مراقبة عمليات الإنتاج في المصانع. لدينا مستخدمون يستخدمون VictoriaMetrics لمراقبة توربينات الرياح للروبوتات.
  • أيضًا ، السلاسل الزمنية مفيدة في جمع المعلومات من أجهزة استشعار الأجهزة المختلفة. على سبيل المثال ، للمحرك ؛ لقياس ضغط الإطارات لقياس السرعة والمسافة. لقياس استهلاك البنزين ، إلخ.
  • أيضا ، يمكن استخدام السلاسل الزمنية لمراقبة الطائرات. تحتوي كل طائرة على صندوق أسود يجمع السلاسل الزمنية لمعايير صحة الطائرات المختلفة. تستخدم السلاسل الزمنية أيضًا في صناعة الطيران.
  • الرعاية الصحية هي ضغط الدم والنبض وما إلى ذلك.

ربما لا تزال هناك تطبيقات نسيتها ، لكن آمل أن تفهم أن السلاسل الزمنية تُستخدم بنشاط في العالم الحديث. ويتزايد استخدامها كل عام.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

ما هي قاعدة بيانات السلاسل الزمنية؟ لماذا لا يمكنك استخدام قاعدة بيانات ارتباطية عادية لتخزين السلاسل الزمنية؟

لأن السلاسل الزمنية تحتوي عادة على كمية كبيرة من المعلومات التي يصعب تخزينها ومعالجتها في قواعد البيانات التقليدية. لذلك ظهرت قواعد بيانات متخصصة للسلسلة الزمنية. هذه القواعد تخزن النقاط بشكل فعال (timestamp, value) بالمفتاح المحدد. أنها توفر واجهة برمجة تطبيقات لقراءة البيانات المخزنة عن طريق المفتاح ، أو عن طريق زوج واحد ذي قيمة رئيسية ، أو بواسطة عدة أزواج من هذا القبيل ، أو عن طريق التعبير العادي. على سبيل المثال ، تريد العثور على حمل وحدة المعالجة المركزية لجميع خدماتك في مركز بيانات في أمريكا ، فأنت بحاجة إلى استخدام هذا الاستعلام الزائف.

عادةً ما تكون قواعد بيانات السلاسل الزمنية لغات استعلام متخصصة لأن SQL للسلسلة الزمنية ليست مناسبة تمامًا. على الرغم من وجود قواعد بيانات تدعم SQL ، إلا أنها ليست مناسبة تمامًا. أفضل لغات الاستعلام المناسبة مثل برومكل, InfluxQL, تدفق, Q. آمل أن يكون شخص ما قد سمع واحدة على الأقل من هذه اللغات. ربما سمع الكثير منكم عن PromQL. هذه هي لغة استعلام بروميثيوس.

اذهب إلى التحسينات في 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.

تنفيذ الوظيفة: get metricIDs لأول label=value، ثم تصفح كل الباقي label=value، نحن نحصل metricIDs بالنسبة لهم. واستدعاء الوظيفة intersectInts، والتي سيتم مناقشتها أدناه. وتعيد هذه الدالة تقاطع هاتين القائمتين.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

كما ترى ، فإن تنفيذ الفهرس المقلوب ليس معقدًا للغاية. لكن هذا تنفيذ ساذج. ما هي عيوبها؟ العيب الرئيسي في التطبيق الساذج هو أننا نخزن مثل هذا الفهرس المقلوب في ذاكرة الوصول العشوائي. بعد إعادة تشغيل التطبيق ، نفقد هذا الفهرس. لا يوجد حفظ لهذا الفهرس على القرص. بالنسبة لقاعدة البيانات ، فإن هذا الفهرس المقلوب بالكاد مناسب.

العيب الثاني مرتبط أيضًا بالذاكرة. يجب أن يتناسب الفهرس المقلوب مع ذاكرة الوصول العشوائي. إذا تجاوز حجم ذاكرة الوصول العشوائي ، فمن الواضح أننا سنخرج - من خطأ في الذاكرة. ولن يعمل البرنامج.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

يمكن حل هذه المشكلة باستخدام حلول جاهزة مثل المستوىDBأو روكس دي بي.

باختصار ، نحتاج إلى قاعدة بيانات تتيح لنا القيام بثلاثة أشياء بسرعة.

  • العملية الأولى هي الكتابة ключ-значение لهذه القاعدة. هي تفعل هذا بسرعة كبيرة. ключ-значение هي سلاسل تعسفية.
  • العملية الثانية هي بحث سريع عن قيمة بواسطة مفتاح معين.
  • والعملية الثالثة هي البحث السريع عن جميع القيم ببادئة معينة.

LevelDB و RocksDB - تم تطوير قواعد البيانات هذه بواسطة Google و Facebook. جاء أولاً LevelDB. ثم أخذ الرجال من Facebook LevelDB وبدأوا في تحسينه ، وصنعوا RocksDB. تعمل الآن جميع قواعد البيانات الداخلية تقريبًا على RocksDB داخل Facebook ، بما في ذلك نقلها إلى RocksDB و MySQL. أطلقوا عليه اسم الآس.

يمكن تنفيذ مؤشر مقلوب باستخدام 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 والحصول على المجموعات المقابلة من metricIDs لهم. ثم نجد التقاطع.

اذهب إلى التحسينات في 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. من الواضح أن مجموعة الدمج تحتاج إلى التحسين للاسترجاع السريع timeseries_ids بواسطة المفتاح المحدد. تمت كتابة Mergeset بالكامل في Go. يمكنك ان ترى مصادر VictoriaMetrics على جيثب. تطبيق الدمج موجود في المجلد / lib / mergeset. يمكنك محاولة اكتشاف ما يحدث هناك.

واجهة برمجة التطبيقات المدمجة تشبه إلى حد بعيد LevelDB و RocksDB. أي أنه يسمح لك بحفظ السجلات الجديدة بسرعة واختيار السجلات بسرعة ببادئة معينة.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

سنتحدث عن عيوب مجموعة الدمج لاحقًا. الآن دعنا نتحدث عن مشاكل VictoriaMetrics في الإنتاج عند تطبيق المؤشر المقلوب.

لماذا نشأوا؟

السبب الأول هو معدل التموج المرتفع. ترجم إلى الروسية ، هذا تغيير متكرر في السلاسل الزمنية. هذا هو الوقت الذي تنتهي فيه السلسلة الزمنية وتبدأ سلسلة جديدة ، أو تبدأ العديد من السلاسل الزمنية الجديدة. وهذا يحدث كثيرًا.

السبب الثاني هو العدد الكبير من السلاسل الزمنية. في البداية ، عندما اكتسبت المراقبة شعبية ، كان عدد السلاسل الزمنية صغيرًا. على سبيل المثال ، في كل جهاز كمبيوتر تحتاج إلى مراقبة حمل المعالج والذاكرة والشبكة والقرص. 4 سلاسل زمنية لكل كمبيوتر. لنفترض أن لديك 100 جهاز كمبيوتر و 400 سلسلة زمنية. هذا قليل جدا.

بمرور الوقت ، توصل الناس إلى فكرة أنه يمكن قياس معلومات أكثر تفصيلاً. على سبيل المثال ، لقياس الحمل ليس من المعالج بأكمله ، ولكن بشكل منفصل عن كل نواة معالج. إذا كان لديك 40 مركزًا للمعالج ، فسيكون لديك ، وفقًا لذلك ، سلسلة زمنية أكثر 40 مرة لقياس حمل المعالج.

ولكن هذا ليس كل شيء. يمكن أن يكون لكل نواة معالج عدة حالات مثل الخمول عندما يكون خاملاً. بالإضافة إلى العمل في مساحة المستخدم ، اعمل في مساحة النواة وحالات أخرى. ويمكن أيضًا قياس كل حالة من هذه الحالات كسلسلة زمنية منفصلة. يؤدي هذا أيضًا إلى زيادة عدد الصفوف بمقدار 7-8 مرات.

من مقياس واحد ، حصلنا على 40 × 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، داخل هذه الحلقة نمر بجميع قيم الشريحة b. ونقارنهم. إذا كانت متطابقة ، فقد وجدنا تقاطعًا. واحفظه في result.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

ما هي العيوب؟ التعقيد التربيعي هو عيبه الرئيسي. على سبيل المثال ، إذا كان لديك أبعاد شريحة a и b مليون لكل منهما ، فلن تعيد هذه الوظيفة إجابة لك أبدًا. لأنه سيحتاج إلى إجراء تريليون تكرار ، وهو عدد كبير حتى بالنسبة لأجهزة الكمبيوتر الحديثة.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

التنفيذ الثاني يعتمد على الخريطة. نحن نقوم بإنشاء خريطة. نضع جميع القيم من شريحة في هذه الخريطة a. ثم نمر عبر حلقة منفصلة من خلال شريحة b. وتحقق مما إذا كانت هذه القيمة مأخوذة من شريحة b في الخريطة. إذا كان موجودًا ، فقم بإضافته إلى النتيجة.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

ما هي المنافع؟ الميزة هي أن هناك تعقيد خطي فقط. بمعنى ، سيتم تنفيذ الوظيفة بشكل أسرع للشرائح الكبيرة. بالنسبة للشريحة المليون ، ستعمل هذه الوظيفة في 2 مليون تكرار ، مقابل تريليون تكرار ، كما في الوظيفة السابقة.

والعيب هو أن هذه الوظيفة تتطلب ذاكرة أكبر لإنشاء هذه الخريطة.

العيب الثاني هو مقدار حمل كبير للتجزئة. هذا النقص ليس واضحا جدا. وبالنسبة لنا ، لم يكن الأمر واضحًا جدًا ، لذلك في البداية في VictoriaMetrics ، تم تنفيذ التقاطع من خلال الخريطة. ولكن بعد ذلك أظهر التنميط أن وقت المعالج الرئيسي يقضي في الكتابة إلى الخريطة والتحقق من وجود قيمة في هذه الخريطة.

لماذا تضيع هذه الأماكن وقت وحدة المعالجة المركزية؟ لأن Go في هذه السطور ينفذ عملية تجزئة. أي أنه يحسب التجزئة من المفتاح ، من أجل الوصول إليه لاحقًا في الفهرس المحدد في HashMap. تستغرق عملية حساب التجزئة عشرات النانو ثانية. هذا بطيء بالنسبة لـ VictoriaMetrics.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

قررت تنفيذ مجموعة بت مُحسّنة خصيصًا لهذه الحالة. هذا ما يبدو عليه تقاطع الشريحتين الآن. هنا نقوم بإنشاء مجموعة بت. نضيف عناصر من الشريحة الأولى إليها. ثم نتحقق من وجود هذه العناصر في الشريحة الثانية. وأضفهم إلى النتيجة. أي أنه لا يختلف تقريبًا عن المثال السابق. الشيء الوحيد هو أننا استبدلنا استدعاء التعيين بوظائف مخصصة هنا add и has.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

للوهلة الأولى ، يبدو أن هذا يجب أن يعمل بشكل أبطأ إذا تم استخدام الخريطة القياسية هناك من قبل ، ثم تم استدعاء بعض الوظائف الأخرى ، لكن التنميط يظهر أن هذا الشيء أسرع 10 مرات من الخريطة القياسية لحالة VictoriaMetrics.

بالإضافة إلى ذلك ، فإنه يستخدم ذاكرة أقل بكثير مقارنة بتنفيذ الخريطة. لأننا نخزن البتات هنا بدلاً من قيم ثمانية بايت.

عيب مثل هذا التنفيذ هو أنه ليس واضحًا جدًا ، وليس تافهاً.

عيب آخر قد لا يلاحظه الكثيرون هو أن هذا التنفيذ قد لا يعمل بشكل جيد في بعض الحالات. أي أنه تم تحسينه لحالة معينة ، في حالة تقاطع معرفات سلسلة VictoriaMetrics الزمنية. هذا لا يعني أنها مناسبة لجميع الحالات. إذا تم استخدامه بشكل غير صحيح ، فلن نحصل على زيادة في الأداء ، ولكن خطأ نفاد الذاكرة وتباطؤ في الأداء.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

النظر في تنفيذ هذا الهيكل. إذا كنت تريد رؤيته ، فهو موجود في مصادر VictoriaMetrics ، في المجلد ليب / 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 المطلوبة ، ثم نسمي الوظيفة addAlloc، مما سيجعل ملف bucket، وإضافته إلى هيكل الجرافة.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

هذا هو تنفيذ الوظيفة b32.add. إنه مشابه للتنفيذ السابق. نحسب ارتفاع 16 بت ، وانخفاض 16 بت.

ثم ننتقل إلى أعلى 16 بتًا. نجد مباريات. وإذا كان هناك تطابق ، فإننا نسمي طريقة الإضافة ، والتي سننظر فيها في الصفحة التالية من أجل bucket16.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

وهنا أدنى مستوى ، والذي يجب تحسينه قدر الإمكان. نحسب ل uint64 قيمة معرف في شريحة بت كذلك bitmask. هذا قناع لقيمة 64 بت هذه ، والتي من خلالها يمكنك التحقق من وجود هذا البت ، أو تعيينه. نتحقق لمعرفة ما إذا تم تعيين هذا البت وتعيينه وإعادة التواجد. هذا هو تطبيقنا الذي سمح لنا بتسريع عملية عبور معرفات السلاسل الزمنية بمقدار 10 مرات مقارنة بالخرائط التقليدية.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

بالإضافة إلى هذا التحسين ، تمتلك VictoriaMetrics العديد من التحسينات الأخرى. تمت إضافة معظم هذه التحسينات لسبب ما ، ولكن بعد تحديد الكود في الإنتاج.

هذه هي القاعدة الرئيسية للتحسين - لا تضيف التحسين ، على افتراض أنه سيكون هناك عنق زجاجة ، لأنه قد يتضح أنه لن يكون هناك عنق زجاجة. التحسين عادة يقلل من جودة الكود. لذلك ، فإن الأمر يستحق التحسين فقط بعد التنميط ، ويفضل أن يكون ذلك في الإنتاج ، بحيث تكون هذه بيانات حقيقية. بالنسبة لأولئك المهتمين ، يمكنك إلقاء نظرة على كود مصدر VictoriaMetrics واستكشاف التحسينات الأخرى الموجودة هناك.

اذهب إلى التحسينات في VictoriaMetrics. الكسندر فاليالكين

لدي سؤال حول bitset. مشابه جدًا لتطبيق C ++ من vector bool ، تم تحسين مجموعة البت. هل أخذت التنفيذ من هناك؟

لا ليس من هناك. عند تنفيذ مجموعة البتات هذه ، استرشدت بمعرفة بنية هذه السلسلة الزمنية للمعرفات ، والتي تُستخدم في VictoriaMetrics. وهيكلها بحيث أن أعلى 32 بتًا ثابتة بشكل أساسي. 32 بت السفلي عرضة للتغيير. كلما انخفض البت ، زاد احتمال تغيره. لذلك ، تم تحسين هذا التنفيذ لبنية البيانات هذه. تم تحسين تطبيق C ++ ، على حد علمي ، للحالة العامة. إذا كنت تقوم بالتحسين للحالة العامة ، فهذا يعني أنها لن تكون الأفضل لحالة معينة.

أنصحك بإلقاء نظرة على تقرير أليكسي ميلوفيد. منذ حوالي شهر ، تحدث عن التحسينات في ClickHouse لتخصصات محددة. يقول فقط أنه في الحالة العامة ، تم تصميم تطبيق C ++ أو بعض التطبيقات الأخرى للعمل الجيد في المتوسط ​​في المستشفى. قد يكون أداءه أسوأ من تنفيذ متخصص لمعرفة محددة ، مثل معرفتنا ، عندما نعلم أن الأجزاء الـ 32 بت العليا ثابتة في الغالب.

لدي سؤال ثان. ما هو الفرق الأساسي من InfluxDB؟

هناك العديد من الاختلافات الأساسية. إذا كان من حيث الأداء واستهلاك الذاكرة ، فإن InfluxDB في الاختبارات تُظهر 10 أضعاف استهلاك الذاكرة للسلسلة الزمنية ذات العلاقة الأساسية العالية ، عندما يكون لديك الكثير منها ، على سبيل المثال ، الملايين. على سبيل المثال ، تستهلك VictoriaMetrics 1 غيغابايت لكل مليون صف نشط ، بينما تستهلك InfluxDB 10 غيغابايت. وهذا فرق كبير.

الاختلاف الأساسي الثاني هو أن InfluxDB لديها لغات استعلام غريبة - Flux و InfluxQL. إنها ليست مريحة للغاية للعمل مع السلاسل الزمنية مقارنةً بـ برومكلالتي تدعمها VictoriaMetrics. PromQL هي لغة استعلام من بروميثيوس.

والفرق الآخر هو أن InfluxDB لديه نموذج بيانات غريب بعض الشيء ، حيث يمكن لكل سطر تخزين عدة حقول بمجموعة مختلفة من العلامات. يتم تقسيم هذه الأسطر كذلك إلى جميع أنواع الجداول. هذه التعقيدات الإضافية تعقد العمل اللاحق مع هذه القاعدة. من الصعب الحفاظ عليها وفهمها.

كل شيء أبسط بكثير في VictoriaMetrics. هناك ، كل سلسلة زمنية هي قيمة مفتاح. القيمة هي مجموعة من النقاط - (timestamp, value)، والمفتاح هو المجموعة label=value. لا يوجد فصل بين الحقول والقياسات. يتيح لك هذا تحديد أي بيانات ثم الجمع بينها وإضافتها وطرحها وضربها وتقسيمها ، على عكس InfluxDB ، حيث لا تزال الحسابات بين الصفوف المختلفة غير منفذة ، على حد علمي. حتى لو تم تنفيذه ، فإنه صعب ، عليك كتابة مجموعة من التعليمات البرمجية.

لدي سؤال توضيحي. لقد فهمت بشكل صحيح أن هناك نوعًا من المشاكل التي تحدثت عنها ، وأن هذا الفهرس المقلوب لا يتناسب مع الذاكرة ، لذلك هناك تقسيم يحدث هناك؟

أولاً ، أظهرت تنفيذًا ساذجًا لمؤشر مقلوب على خريطة Go القياسية. هذا التطبيق غير مناسب لقواعد البيانات لأن هذا الفهرس المقلوب لا يتم حفظه على القرص ، ويجب أن تحفظ قاعدة البيانات على القرص حتى تظل هذه البيانات متاحة عند إعادة التشغيل. في هذا التطبيق ، عند إعادة تشغيل التطبيق ، سيختفي الفهرس المقلوب. وستفقد الوصول إلى جميع البيانات لأنك لن تتمكن من العثور عليها.

مرحبًا! شكرا على التقرير! اسمي بافيل. أنا من Wildberries. لدي بعض الأسئلة لك. سؤال واحد. هل تعتقد أنك إذا اخترت مبدأ مختلفًا عند إنشاء بنية التطبيق وتقسيم البيانات حسب الوقت ، فربما يمكنك القيام بتقاطع البيانات عند البحث ، استنادًا إلى حقيقة أن قسمًا واحدًا يحتوي على بيانات لفترة واحدة من الوقت ، أي في فترة زمنية واحدة ولا داعي للقلق بشأن حقيقة أن قطعك مبعثرة بشكل مختلف؟ السؤال رقم 2 - نظرًا لأنك تقوم بتنفيذ خوارزمية مماثلة باستخدام bitset وكل شيء آخر ، فربما حاولت استخدام تعليمات المعالج؟ ربما جربت مثل هذه التحسينات؟

سأجيب على السؤال الثاني. لم نصل إلى هناك بعد. ولكن إذا لزم الأمر ، سنفعل. ما هو السؤال الأول؟

لقد ناقشت سيناريوهين. وقالوا إنهم اختاروا الثانية ذات التنفيذ الأكثر تعقيدًا. ولم يفضلوا النوع الأول ، حيث يتم تقسيم البيانات حسب الوقت.

نعم. في الحالة الأولى ، سيكون الحجم الإجمالي للفهرس أكبر ، لأنه في كل قسم سيتعين علينا تخزين بيانات مكررة لتلك السلاسل الزمنية التي تستمر عبر كل هذه الأقسام. وإذا كان لديك معدل إزعاج صغير للسلاسل الزمنية ، أي أن نفس السلسلة تستخدم باستمرار ، ففي الحالة الأولى سنخسر أكثر بكثير من حيث مساحة القرص المشغولة مقارنة بالحالة الثانية.

وهكذا - نعم ، يعد التقسيم بمرور الوقت خيارًا جيدًا. يستخدمه بروميثيوس. لكن بروميثيوس له عيب آخر. عند دمج هذه الأجزاء من البيانات ، فإنها تحتاج إلى الاحتفاظ بالمعلومات الوصفية في الذاكرة لجميع الملصقات والسلاسل الزمنية. لذلك ، إذا كانت أجزاء البيانات كبيرة ، والتي يتم دمجها ، فإن استهلاك الذاكرة ينمو بشدة عند الدمج ، على عكس VictoriaMetrics. عند الدمج ، لا تستهلك VictoriaMetrics الذاكرة على الإطلاق ، حيث يتم استهلاك بضعة كيلوبايت هناك ، بغض النظر عن حجم أجزاء البيانات التي يتم دمجها.

الخوارزمية التي لديك تستخدم الذاكرة. إنها تحدد علامات التسلسل الزمني التي لها قيم. وبهذه الطريقة تتحقق من التواجد المقترن في مصفوفة بيانات واحدة وفي أخرى. وأنت تفهم ما إذا كان التقاطع قد حدث أم لا. عادةً ما تقوم قواعد البيانات بتنفيذ المؤشرات والمكررات التي تخزن قيمتها الحالية وتعمل من خلال البيانات المصنفة ، بسبب التعقيد البسيط لهذه العمليات.

لماذا لا نستخدم المؤشرات لاجتياز البيانات؟

نعم.

في LevelDB الخاص بنا أو في مجموعة الدمج ، يتم تخزين الأسطر المرتبة فقط. يمكننا السير بالمؤشر وإيجاد التقاطع. لماذا لا نستخدمه؟ لأنها بطيئة. لأن المؤشرات تعني أنك بحاجة إلى استدعاء دالة لكل سطر. استدعاء دالة هو 5 نانوثانية. وإذا كان لديك 100 سطر ، فقد اتضح أننا نقضي نصف ثانية فقط في استدعاء دالة.

هناك شيء من هذا القبيل ، نعم. وسؤالي الأخير. قد يبدو السؤال غريباً بعض الشيء. لماذا ، وقت وصول البيانات ، من المستحيل حساب جميع المجاميع اللازمة وحفظها في النموذج المطلوب؟ لماذا توفر كميات ضخمة لبعض الأنظمة مثل VictoriaMetrics و ClickHouse وما إلى ذلك ، من أجل قضاء الكثير من الوقت عليها لاحقًا؟

سأعطي مثالا لتوضيح الأمر. لنفترض كيف يعمل عداد سرعة لعبة صغير؟ يسجل المسافة التي قطعتها ، ويضيفها طوال الوقت إلى قيمة واحدة ، إلى المرة الثانية. ويقسم. ويحصل على متوسط ​​السرعة. يمكنك أن تفعل الشيء نفسه إلى حد كبير. اجمع كل الحقائق الضرورية بسرعة.

حسنًا ، أفهم السؤال. مثالك له مكان للعيش فيه. إذا كنت تعرف المجاميع التي تحتاجها ، فهذا هو أفضل تطبيق. لكن المشكلة تكمن في أن الأشخاص يحفظون هذه المقاييس ، وبعض البيانات في ClickHouse ، ولا يزالون لا يعرفون كيف سيتم تجميعها وتصفيتها في المستقبل ، لذلك يتعين عليك حفظ جميع البيانات الأولية. ولكن إذا كنت تعلم أنك بحاجة إلى حساب شيء ما ، فلماذا لا تحسبه بدلاً من تخزين مجموعة من القيم الأولية هناك؟ لكن هذا فقط إذا كنت تعرف بالضبط ما تحتاجه.

بالمناسبة ، تدعم قواعد البيانات الخاصة بتخزين السلاسل الزمنية مجاميع العد. على سبيل المثال ، يدعم Prometheus ملفات قواعد التسجيل. وهذا يعني أنه يمكن القيام بذلك إذا كنت تعرف الوحدات التي تحتاجها. هذا غير متوفر حتى الآن في VictoriaMetrics ، ولكن عادة ما يسبقه Prometheus ، حيث يمكنك القيام بذلك في قواعد إعادة الترميز.

على سبيل المثال ، في وظيفة سابقة ، كان عليك حساب عدد الأحداث في نافذة منزلقة في آخر ساعة. المشكلة هي أنني اضطررت إلى إجراء تنفيذ مخصص في Go ، أي خدمة لحساب هذا الشيء. كانت هذه الخدمة في نهاية المطاف غير تافهة ، لأنه من الصعب حسابها. يمكن أن يكون التنفيذ بسيطًا إذا كنت بحاجة إلى حساب بعض المجاميع على فترات زمنية محددة. إذا كنت تريد عد الأحداث في نافذة منزلقة ، فهذا ليس سهلاً كما يبدو. أعتقد أن هذا لم يتم تنفيذه بعد في ClickHouse أو في قواعد بيانات المجموعات الزمنية ، لأنه من الصعب تنفيذه.

وسؤال آخر. كنا نتحدث فقط عن المتوسط ​​، وتذكرت أنه كان هناك شيء مثل الجرافيت مع خلفية كربون. وكان يعرف كيفية تقليص البيانات القديمة ، أي ترك نقطة واحدة في الدقيقة ، ونقطة واحدة في الساعة ، وما إلى ذلك. من حيث المبدأ ، يعد هذا مناسبًا تمامًا إذا احتجنا إلى بيانات أولية ، نسبيًا ، لمدة شهر ، ويمكن تقليل كل شيء آخر خارج. لكن بروميثيوس ، 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 ، والتي تسمى المقاييسQL. هناك حديث على موقع يوتيوب حول هذه الوظيفة الموسعة. لقد تحدثت في لقاء المراقبة في الربيع في سان بطرسبرج.

قناة برقية فيكتورياميتريكس.

يمكن للمستخدمين المسجلين فقط المشاركة في الاستطلاع. تسجيل الدخول، من فضلك.

ما الذي يمنعك من التحول إلى VictoriaMetrics كمخزن طويل الأجل لـ Prometheus؟ (اكتب في التعليقات سأضيف إلى الاستطلاع))

  • 71,4%عدم استخدام بروميثيوس 5

  • 28,6%لم أكن أعرف عن VictoriaMetrics2

صوت 7 مستخدمين. امتنع 12 مستخدما عن التصويت.

المصدر: www.habr.com

إضافة تعليق