עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

אני מציע לך לקרוא את התמליל של הדו"ח של סוף 2019 מאת אלכסנדר ולילקין "עבור אופטימיזציות ב-VictoriaMetrics"

VictoriaMetrics - DBMS מהיר וניתן להרחבה לאחסון ועיבוד נתונים בצורה של סדרת זמן (הרשומה יוצרת זמן ומערכת של ערכים התואמים לזמן זה, למשל, המתקבלים באמצעות סקר תקופתי של מצב חיישנים או איסוף של מדדים).

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

הנה קישור לסרטון של הדו"ח הזה - https://youtu.be/MZ5P21j_HLE

שקופיות

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

ספר לנו על עצמך. אני אלכסנדר וליאלקין. כאן חשבון GitHub שלי. אני נלהב מ-Go ואופטימיזציה של ביצועים. כתבתי הרבה ספריות שימושיות ולא כל כך שימושיות. הם מתחילים עם אחד מהם fast, או עם quick קידומת.

כרגע אני עובד על VictoriaMetrics. מה זה ומה אני עושה שם? אדבר על כך במצגת זו.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

מתווה הדו"ח הוא כדלקמן:

  • ראשית, אני אגיד לך מה זה VictoriaMetrics.
  • אז אני אגיד לך מהן סדרות זמן.
  • אז אני אגיד לך איך עובד מסד נתונים של סדרות זמן.
  • לאחר מכן, אספר לכם על ארכיטקטורת מסד הנתונים: ממה היא מורכבת.
  • ואז בואו נעבור לאופטימיזציות שיש ל-VictoriaMetrics. זוהי אופטימיזציה לאינדקס ההפוך ואופטימיזציה ליישום ה-bitset ב-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 - הערכים המתאימים. זהו השימוש במעבד בזמן נתון עבור שורה נתונה.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

היכן ניתן להשתמש בסדרות זמן? למישהו יש מושג?

  • ב-DevOps, אתה יכול למדוד מעבד, זיכרון RAM, רשת, rps, מספר שגיאות וכו'.
  • IoT - אנחנו יכולים למדוד טמפרטורה, לחץ, קואורדינטות גיאוגרפיות ועוד משהו.
  • גם פיננסים - אנחנו יכולים לעקוב אחר מחירים לכל מיני מניות ומטבעות.
  • בנוסף, ניתן להשתמש בסדרות זמן במעקב אחר תהליכי ייצור במפעלים. יש לנו משתמשים שמשתמשים ב-VictoriaMetrics כדי לנטר טורבינות רוח, עבור רובוטים.
  • סדרות זמן שימושיות גם לאיסוף מידע מחיישנים של מכשירים שונים. למשל, למנוע; למדידת לחץ אוויר בצמיגים; למדידת מהירות, מרחק; למדידת צריכת בנזין וכו'.
  • ניתן להשתמש בסדרות זמן גם לניטור מטוסים. לכל מטוס יש קופסה שחורה האוספת סדרות זמן לפרמטרים שונים של בריאות המטוס. סדרות זמן משמשות גם בתעשייה האווירית.
  • שירותי בריאות הם לחץ דם, דופק וכו'.

אולי יש עוד יישומים ששכחתי מהם, אבל אני מקווה שאתה מבין שסדרות זמן משמשות באופן פעיל בעולם המודרני. והיקף השימוש בהם גדל מדי שנה.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

למה אתה צריך מסד נתונים של סדרות זמן? מדוע אינך יכול להשתמש במסד נתונים יחסי רגיל כדי לאחסן סדרות זמן?

מכיוון שסדרות זמן מכילות בדרך כלל כמות גדולה של מידע, שקשה לאחסן ולעבד אותו במאגרי מידע קונבנציונליים. לכן, הופיעו מאגרי מידע מיוחדים לסדרות זמן. בסיסים אלה מאחסנים למעשה נקודות (timestamp, value) עם המפתח הנתון. הם מספקים ממשק API לקריאת נתונים מאוחסנים לפי מפתח, לפי זוג מפתח-ערך בודד, או לפי מספר צמדי מפתח-ערך, או לפי regexp. לדוגמה, אתה רוצה למצוא את עומס המעבד של כל השירותים שלך במרכז נתונים באמריקה, אז אתה צריך להשתמש בשאילתה פסאודו זו.

בדרך כלל מסדי נתונים של סדרות זמן מספקות שפות שאילתות מיוחדות מכיוון שסדרת זמן SQL אינה מתאימה במיוחד. למרות שיש מסדי נתונים שתומכים ב-SQL, זה לא מתאים במיוחד. שפות שאילתות כגון PromQL, 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), אשר ימפה את המחרוזת ל-slice ints. השורה מכילה label=value.

יישום פונקציה: קבל metricIDs לראשונה label=value, ואז אנחנו עוברים על כל השאר label=value, אנחנו מבינים metricIDs בשבילם. ותקרא לפונקציה intersectInts, שעליו נדון להלן. והפונקציה הזו מחזירה את ההצטלבות של הרשימות הללו.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

כפי שאתה יכול לראות, יישום אינדקס הפוך אינו מסובך במיוחד. אבל זה יישום נאיבי. אילו חסרונות יש לזה? החיסרון העיקרי של היישום הנאיבי הוא שאינדקס הפוך שכזה מאוחסן ב-RAM. לאחר הפעלה מחדש של האפליקציה אנו מאבדים את האינדקס הזה. אין שמירה של האינדקס הזה בדיסק. אינדקס הפוך כזה לא סביר שיתאים למסד נתונים.

החיסרון השני קשור גם לזיכרון. האינדקס ההפוך חייב להתאים ל-RAM. אם זה חורג מגודל ה-RAM, אז ברור שנקבל - מתוך שגיאת זיכרון. והתוכנית לא תעבוד.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

ניתן לפתור בעיה זו באמצעות פתרונות מוכנים כגון רמה DBאו סלעים DB.

בקיצור, אנחנו צריכים מסד נתונים שמאפשר לנו לבצע שלוש פעולות במהירות.

  • הפעולה הראשונה היא הקלטה ключ-значение למסד הנתונים הזה. היא עושה את זה מהר מאוד, איפה ключ-значение הם מחרוזות שרירותיות.
  • הפעולה השנייה היא חיפוש מהיר של ערך באמצעות מפתח נתון.
  • והפעולה השלישית היא חיפוש מהיר של כל הערכים לפי קידומת נתונה.

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 וקבל את קבוצות ה-metricID המתאימות עבורם. ואז נמצא את הצומת.

עבור לאופטימיזציות ב-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.

Mergeset מבוסס על מבנה הנתונים MergeTree. מבנה נתונים זה מושאל מ-ClickHouse. ברור ש-mergeset צריך להיות מותאם לחיפוש מהיר timeseries_ids לפי המפתח הנתון. Mergeset כתוב כולו ב-Go. אתה יכול לראות מקורות VictoriaMetrics ב-GitHub. היישום של mergeset נמצא בתיקייה /lib/mergeset. אתה יכול לנסות להבין מה קורה שם.

ה-API של המיזוג דומה מאוד ל-LevelDB ול-RocksDB. כלומר, הוא מאפשר לשמור שם במהירות רשומות חדשות ולבחור במהירות רשומות לפי קידומת נתונה.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

על החסרונות של Mergeset נדבר מאוחר יותר. עכשיו בואו נדבר על אילו בעיות התעוררו עם VictoriaMetrics בייצור בעת יישום אינדקס הפוך.

למה הם קמו?

הסיבה הראשונה היא שיעור הנטישה הגבוה. בתרגום לרוסית, זהו שינוי תכוף בסדרות הזמן. זה כאשר סדרת זמן מסתיימת ומתחילה סדרה חדשה, או מתחילות סדרות זמן חדשות רבות. וזה קורה לעתים קרובות.

הסיבה השנייה היא המספר הגדול של סדרות זמן. בהתחלה, כאשר הניטור צבר פופולריות, מספר סדרות הזמן היה קטן. לדוגמה, עבור כל מחשב אתה צריך לפקח על מעבד, זיכרון, רשת ועומס דיסק. 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. ביציאה, הוא אמור להחזיר לנו את ההצטלבות של הפרוסות הללו.

יישום נאיבי נראה כך. אנו חוזרים על כל הערכים מ-Slice a, בתוך הלולאה הזו אנו עוברים על כל הערכים של פרוסה b. ואנחנו משווים ביניהם. אם הם תואמים, אז מצאנו צומת. ותשמור את זה בפנים result.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

מהם החסרונות? המורכבות הריבועית היא החיסרון העיקרי שלו. לדוגמה, אם המידות שלך הן פרוסה a и b מיליון בכל פעם, אז הפונקציה הזו לעולם לא תחזיר לך תשובה. כי הוא יצטרך לבצע טריליון איטרציות, וזה הרבה אפילו עבור מחשבים מודרניים.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

היישום השני מבוסס על מפה. אנחנו יוצרים מפה. שמנו את כל הערכים מ-Slice לתוך המפה הזו a. ואז אנחנו עוברים פרוסה בלולאה נפרדת b. ואנחנו בודקים אם הערך הזה הוא מפרוסה b במפה. אם הוא קיים, הוסף אותו לתוצאה.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

מה הם היתרונות? היתרון הוא שיש רק מורכבות ליניארית. כלומר, הפונקציה תתבצע הרבה יותר מהר עבור פרוסות גדולות יותר. עבור פרוסה בגודל מיליון, פונקציה זו תבוצע ב-2 מיליון איטרציות, בניגוד לטריליון האיטרציות של הפונקציה הקודמת.

החיסרון הוא שפונקציה זו דורשת יותר זיכרון כדי ליצור את המפה הזו.

החיסרון השני הוא התקורה הגדולה עבור hashing. חסרון זה אינו ברור במיוחד. ואצלנו זה גם לא היה ברור במיוחד, אז בהתחלה ב-VictoriaMetrics היישום של צומת היה דרך מפה. אבל אז הפרופיל הראה שזמן המעבד הראשי מושקע בכתיבה למפה ובדיקת נוכחות של ערך במפה זו.

למה זמן CPU מבוזבז במקומות האלה? מכיוון שגו מבצע פעולת גיבוב בקווים אלו. כלומר, הוא מחשב את ה-hash של המפתח כדי לגשת אליו לאחר מכן באינדקס נתון ב-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 לעתים קרובות שוללת את אורך ה-bitset באלגוריתמים שלה.

  • השדה השני הוא 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 ערך מזהה ב-Slice Bit וגם bitmask. זוהי מסיכה עבור ערך נתון של 64 סיביות, שניתן להשתמש בה כדי לבדוק את נוכחותו של סיביות זו, או להגדיר אותה. אנחנו בודקים אם הביט הזה מוגדר ומגדירים אותו, ומחזירים נוכחות. זהו היישום שלנו, שאפשר לנו להאיץ את פעולתם של מזהים מצטלבים של סדרות זמן פי 10 בהשוואה למפות קונבנציונליות.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

בנוסף לאופטימיזציה זו, ל-VictoriaMetrics יש אופטימיזציות רבות אחרות. רוב האופטימיזציות הללו נוספו מסיבה כלשהי, אך לאחר יצירת פרופיל של הקוד בייצור.

זה הכלל העיקרי של אופטימיזציה - אל תוסיף אופטימיזציה בהנחה שיהיה כאן צוואר בקבוק, כי יכול להיות שיתברר שלא יהיה שם צוואר בקבוק. אופטימיזציה בדרך כלל פוגעת באיכות הקוד. לכן כדאי לבצע אופטימיזציה רק ​​לאחר הפרופיל ורצוי בהפקה, כך שמדובר בנתונים אמיתיים. אם מישהו מעוניין, אתה יכול להסתכל בקוד המקור של VictoriaMetrics ולחקור אופטימיזציות אחרות שיש.

עבור לאופטימיזציות ב-VictoriaMetrics. אלכסנדר ולילקין

יש לי שאלה לגבי Bitset. דומה מאוד למימוש ה-bool הווקטור של C++, Bitset אופטימלי. לקחתם את היישום משם?

לא, לא משם. בעת יישום ה-bitset הזה, הודרך על ידי הידע של המבנה של סדרות הזמנים האלה של ids, המשמשות ב-VictoriaMetrics. והמבנה שלהם הוא כזה ש-32 הביטים העליונים הם בעצם קבועים. 32 הסיביות התחתונות כפופים לשינויים. ככל שהביט נמוך יותר, כך הוא יכול להשתנות לעתים קרובות יותר. לכן, יישום זה מותאם במיוחד עבור מבנה נתונים זה. היישום C++, עד כמה שידוע לי, מותאם למקרה הכללי. אם תבצע אופטימיזציה למקרה הכללי, זה אומר שזה לא יהיה האופטימלי ביותר למקרה ספציפי.

אני גם ממליץ לך לצפות בדו"ח של אלכסיי מילוביד. לפני כחודש הוא דיבר על אופטימיזציה ב-ClickHouse להתמחויות ספציפיות. הוא רק אומר שבמקרה הכללי, יישום C++ או יישום אחר מותאם לעבוד טוב בממוצע בבית חולים. הוא עשוי לבצע ביצועים גרועים יותר מיישום ספציפי לידע כמו שלנו, שבו אנו יודעים ש-32 הסיביות העליונות לרוב קבועות.

יש לי שאלה שנייה. מה ההבדל המהותי מ-InfluxDB?

ישנם הבדלים מהותיים רבים. מבחינת ביצועים וצריכת זיכרון, InfluxDB בבדיקות מראה פי 10 יותר צריכת זיכרון עבור סדרות זמן עם קרדינליות גבוהה, כאשר יש לך הרבה מהם, למשל, מיליונים. לדוגמה, VictoriaMetrics צורכת 1 GB למיליון שורות פעילות, בעוד InfluxDB צורכת 10 GB. וזה הבדל גדול.

ההבדל הבסיסי השני הוא שלInfluxDB יש שפות שאילתות מוזרות - Flux ו- InfluxQL. הם לא מאוד נוחים לעבודה עם סדרות זמן לעומת PromQL, אשר נתמך על ידי VictoriaMetrics. PromQL היא שפת שאילתה מ-Prometheus.

והבדל נוסף הוא שלInfluxDB יש מודל נתונים קצת מוזר, שבו כל שורה יכולה לאחסן מספר שדות עם סט שונה של תגים. שורות אלה מחולקות עוד יותר לטבלאות שונות. סיבוכים נוספים אלה מסבכים את העבודה שלאחר מכן עם מסד נתונים זה. קשה לתמוך ולהבין.

ב-VictoriaMetrics הכל הרבה יותר פשוט. שם, כל סדרת זמן היא ערך מפתח. הערך הוא קבוצה של נקודות - (timestamp, value), והמפתח הוא הסט label=value. אין הפרדה בין שדות למידות. זה מאפשר לך לבחור כל נתונים ואז לשלב, להוסיף, להחסיר, להכפיל, לחלק, בניגוד ל-InfluxDB שבו חישובים בין שורות שונות עדיין לא מיושמים עד כמה שידוע לי. גם אם הם מיושמים, זה קשה, צריך לכתוב הרבה קוד.

יש לי שאלת הבהרה. האם הבנתי נכון שיש איזושהי בעיה שדיברת עליה, שהאינדקס ההפוך הזה לא נכנס לזיכרון, אז יש שם חלוקה?

ראשית, הראיתי יישום נאיבי של אינדקס הפוך על מפת Go סטנדרטית. יישום זה אינו מתאים לבסיסי נתונים מכיוון שהאינדקס ההפוך הזה לא נשמר בדיסק, ועל מסד הנתונים לשמור בדיסק כדי שהנתונים הללו יישארו זמינים בעת הפעלה מחדש. ביישום זה, כאשר אתה מפעיל מחדש את היישום, האינדקס ההפוך שלך ייעלם. ואתה תאבד את הגישה לכל הנתונים כי לא תוכל למצוא אותם.

שלום! תודה על הדיווח! שמי פאבל. אני מ-Wildberries. יש לי כמה שאלות אליך. שאלה ראשונה. האם אתה חושב שאם היית בוחר עיקרון אחר בעת בניית הארכיטקטורה של האפליקציה שלך ומחלק את הנתונים לאורך זמן, אז אולי היית יכול לחתוך נתונים בעת חיפוש, רק על סמך העובדה שמחיצה אחת מכילה נתונים עבור אחד פרק זמן , כלומר במרווח זמן אחד ולא תצטרך לדאוג מהעובדה שהחתיכות שלך מפוזרות אחרת? שאלה מספר 2 - מכיוון שאתה מיישם אלגוריתם דומה עם Bitset וכל השאר, אז אולי ניסית להשתמש בהוראות מעבד? אולי ניסית אופטימיזציות כאלה?

אני אענה על השני מיד. עוד לא הגענו למצב הזה. אבל אם צריך, נגיע לשם. והראשון, מה הייתה השאלה?

דיברת על שני תרחישים. והם אמרו שהם בחרו בשני עם יישום מורכב יותר. והם לא העדיפו את הראשון, שבו הנתונים מחולקים לפי זמן.

כן. במקרה הראשון, הנפח הכולל של האינדקס יהיה גדול יותר, מכיוון שבכל מחיצה נצטרך לאחסן נתונים כפולים עבור אותן סדרות זמן שנמשכות בכל המחיצות הללו. ואם קצב הנטישה של סדרות הזמן שלך קטן, כלומר כל הזמן נעשה שימוש באותן סדרות, אז במקרה הראשון נפסיד הרבה יותר בכמות שטח הדיסק התפוס בהשוואה למקרה השני.

ולכן - כן, חלוקת זמן היא אפשרות טובה. פרומתאוס משתמש בזה. אבל לפרומתאוס יש חיסרון נוסף. בעת מיזוג פיסות נתונים אלה, הוא צריך לשמור בזיכרון מטא מידע עבור כל התוויות וסדרות הזמן. לכן, אם פיסות הנתונים שהוא ממזג גדולות, אזי צריכת הזיכרון עולה מאוד במהלך המיזוג, בניגוד ל-VictoriaMetrics. בעת מיזוג, VictoriaMetrics לא צורכת זיכרון כלל; רק כמה קילובייט נצרכים, ללא קשר לגודל פיסות הנתונים הממוזגות.

האלגוריתם שבו אתה משתמש משתמש בזיכרון. זה מסמן תגיות של סדרות זמן המכילות ערכים. ובדרך זו אתה בודק נוכחות זוגית במערך נתונים אחד ובאחר. ואתה מבין אם התרחש מפגש או לא. בדרך כלל, מסדי נתונים מיישמים סמנים ואיטרטורים המאחסנים את התוכן הנוכחי שלהם ופועלים דרך הנתונים הממוינים בשל המורכבות הפשוטה של ​​פעולות אלו.

למה אנחנו לא משתמשים בסמנים כדי לעבור נתונים?

כן.

אנו מאחסנים שורות ממוינות ב-LevelDB או ב-mergeset. נוכל להזיז את הסמן ולמצוא את הצומת. למה שלא נשתמש בזה? כי זה איטי. כי סמנים אומרים שאתה צריך לקרוא לפונקציה עבור כל שורה. קריאת פונקציה היא 5 ננו שניות. ואם יש לך 100 שורות, אז מסתבר שאנחנו מבלים חצי שנייה רק ​​בקריאת הפונקציה.

יש דבר כזה, כן. והשאלה האחרונה שלי. השאלה אולי נשמעת קצת מוזרה. מדוע לא ניתן לקרוא את כל האגרגטים הדרושים ברגע הגעת הנתונים ולשמור אותם בצורה הנדרשת? למה לחסוך נפחים עצומים במערכות מסוימות כמו VictoriaMetrics, ClickHouse וכו', ואז להשקיע בהן הרבה זמן?

אני אתן דוגמה כדי להבהיר את זה. נגיד איך פועל מד מהירות צעצוע קטן? הוא מתעד את המרחק שעברת, כל הזמן מוסיף אותו לערך אחד, והשני - זמן. ומחלק. ומקבל מהירות ממוצעת. אתה יכול לעשות בערך אותו דבר. הוסף את כל העובדות הנחוצות תוך כדי תנועה.

אוקיי, הבנתי את השאלה. לדוגמא שלך יש מקום. אם אתה יודע איזה אגרגטים אתה צריך, אז זה היישום הטוב ביותר. אבל הבעיה היא שאנשים שומרים את המדדים האלה, חלק מהנתונים ב-ClickHouse והם עדיין לא יודעים איך הם יצטברו ויסוננו אותם בעתיד, אז הם צריכים לשמור את כל הנתונים הגולמיים. אבל אם אתה יודע שאתה צריך לחשב משהו בממוצע, אז למה לא לחשב אותו במקום לאחסן שם חבורה של ערכים גולמיים? אבל זה רק אם אתה יודע בדיוק מה אתה צריך.

אגב, מסדי נתונים לאחסון סדרות זמן תומכים בספירת אגרגטים. לדוגמה, פרומתאוס תומך כללי הקלטה. כלומר, זה יכול להיעשות אם אתה יודע אילו יחידות תצטרך. ל-VictoriaMetrics אין את זה עדיין, אבל בדרך כלל מקדים אותו Prometheus, שבו ניתן לעשות זאת בכללי הקידוד.

לדוגמה, בעבודה הקודמת שלי הייתי צריך לספור את מספר האירועים בחלון הזזה במהלך השעה האחרונה. הבעיה היא שהייתי צריך לעשות יישום מותאם אישית ב-Go, כלומר שירות לספירת הדבר הזה. השירות הזה היה בסופו של דבר לא טריוויאלי, כי קשה לחשב אותו. היישום יכול להיות פשוט אם אתה צריך לספור כמה אגרגטים במרווחי זמן קבועים. אם אתה רוצה לספור אירועים בחלון הזזה, אז זה לא פשוט כמו שזה נראה. אני חושב שזה עדיין לא יושם ב-ClickHouse או במסדי נתונים של סדרות זמן, כי זה קשה ליישום.

ועוד שאלה אחת. רק דיברנו על ממוצע, ונזכרתי שהיה פעם דבר כזה גרפיט עם קצה קרבון. והוא ידע לדלל נתונים ישנים, כלומר להשאיר נקודה אחת לדקה, נקודה אחת לשעה וכו'. עקרונית זה די נוח אם אנחנו צריכים נתונים גולמיים, יחסית, לחודש, וכל השאר יכול להיות דליל . אבל Prometheus ו-VictoriaMetrics אינם תומכים בפונקציונליות זו. האם מתוכנן לתמוך בו? אם לא, למה לא?

תודה על השאלה. המשתמשים שלנו שואלים שאלה זו מדי פעם. הם שואלים מתי נוסיף תמיכה להורדת דגימה. יש כאן כמה בעיות. ראשית, כל משתמש מבין downsampling משהו אחר: מישהו רוצה לקבל כל נקודה שרירותית במרווח נתון, מישהו רוצה ערכים מקסימליים, מינימום, ממוצעים. אם מערכות רבות כותבות נתונים למסד הנתונים שלך, אז אתה לא יכול לאחד את הכל ביחד. יכול להיות שכל מערכת דורשת דילול שונה. וזה קשה ליישום.

והדבר השני הוא ש-VictoriaMetrics, כמו ClickHouse, מותאמת לעבודה עם כמויות גדולות של נתונים גולמיים, כך שהיא יכולה לדחוף מיליארד שורות בפחות משנייה אם יש לך הרבה ליבות במערכת שלך. סריקת נקודות סדרת זמן ב-VictoriaMetrics – 50 נקודות לשנייה לכל ליבה. והביצועים האלה מתקדמים לליבות קיימות. כלומר, אם יש לך 000 ליבות, למשל, תסרוק מיליארד נקודות בשנייה. והנכס הזה של VictoriaMetrics ו-ClickHouse מפחית את הצורך בהורדה.

תכונה נוספת היא ש-VictoriaMetrics דוחסת נתונים אלה ביעילות. הדחיסה בממוצע בייצור היא בין 0,4 ל-0,8 בתים לנקודה. כל נקודה היא חותמת זמן + ערך. והוא דחוס לפחות מבייט אחד בממוצע.

סרגיי. יש לי שאלה. מהו קוונטי זמן ההקלטה המינימלי?

אלפית שנייה אחת. לאחרונה ניהלנו שיחה עם מפתחי מסדי נתונים אחרים של סדרות זמן. פרוסת הזמן המינימלית שלהם היא שנייה אחת. ובגרפיט, למשל, זה גם שנייה אחת. ב-OpenTSDB זה גם שנייה אחת. ל-InfluxDB יש דיוק של ננו-שניות. ב-VictoriaMetrics זה מילי שנייה אחת, כי בפרומתאוס זה מילי שנייה אחת. ו-VictoriaMetrics פותחה במקור כאחסון מרוחק עבור פרומתאוס. אבל עכשיו זה יכול לשמור נתונים ממערכות אחרות.

האדם שאיתו דיברתי אומר שיש להם דיוק של שניות לשניה - זה מספיק להם כי זה תלוי בסוג הנתונים המאוחסנים במסד הנתונים של סדרות הזמן. אם מדובר בנתוני DevOps או נתונים מתשתית, שבה אתה אוסף אותם במרווחים של 30 שניות, לדקה, אז דיוק שניה מספיק, אתה לא צריך פחות. ואם אתה אוסף את הנתונים האלה ממערכות מסחר בתדירות גבוהה, אז אתה צריך דיוק ננו-שניות.

דיוק אלפיות השנייה ב-VictoriaMetrics מתאים גם למקרה של DevOps, ויכול להתאים לרוב המקרים שהזכרתי בתחילת הדוח. הדבר היחיד שאולי זה לא מתאים לו הוא מערכות מסחר בתדירות גבוהה.

תודה! ועוד שאלה. מהי תאימות ב-PromQL?

תאימות מלאה לאחור. VictoriaMetrics תומכת באופן מלא ב-PromQL. בנוסף, הוא מוסיף פונקציונליות מתקדמת נוספת ב-PromQL, הנקראת MetricsQL. יש דיבור ביוטיוב על הפונקציונליות המורחבת הזו. דיברתי במפגש ניטור באביב בסנט פטרסבורג.

ערוץ מברק VictoriaMetrics.

רק משתמשים רשומים יכולים להשתתף בסקר. להתחברבבקשה.

מה מונע ממך לעבור ל-VictoriaMetrics כאחסון לטווח ארוך עבור Prometheus? (תרשמו בתגובות, אני אוסיף לסקר))

  • 71,4%אני לא משתמש ב-Prometheus5

  • 28,6%לא ידעתי על VictoriaMetrics2

7 משתמשים הצביעו. 12 משתמשים נמנעו.

מקור: www.habr.com

הוספת תגובה