כיצד למעקב אחר ביצועי MongoDB

הסופר בחר ב־קרן האינטרנט הפתוחה/הפותרות לפטירת דעת לקבל תרומה כחלק מתוכנית כתיבה למענה לתרומות.

הקדמה

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

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

דרישות מוקדמות

כדי לעקוב אחרי המדריך הזה, יהיה עליך לצייד:

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

שלב 1 — הכנת הנתונים לבדיקה

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

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

  1. mongo -u AdminSammy -p --authenticationDatabase admin

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

הערה: בחיבור חדש, כסלים של MongoDB יתחברו למסד הנתונים test כברירת מחדל. ניתן להשתמש בבסיס נתונים זה בבטחה לנסות דברים עם MongoDB וכסלי המסד הנתונים שלו.

  1. use database_name

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

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

An example bank account document
{
    "number": "1000-987321",
    "currency": "USD",
    "balance": 431233431
}

מסמך הדוגמה הזה מכיל את המידע הבא:

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

במקום להכניס ידנית מספר רב של מסמכים, תוכל לבצע את קוד ה-JavaScript הבא כדי ליצור באופן סימולטני אוסף בשם חשבונות ולהכניס מיליון מסמכים כאלה בו:

  1. for (let i = 1; i <= 1000000; ++i) {
  2. db.accounts.insertOne({
  3. "number": "1000-" + i,
  4. "currency": i > 500000 ? "USD" : "EUR",
  5. "balance": Math.random() * 100000
  6. })
  7. }

הקוד הזה מפעיל לולאת for שרצה מיליון פעמים רצוף. בכל פעם שהלולאה עוברת על כך, היא מבצעת את השיטה insertOne() על אוסף החשבונות כדי להכניס מסמך חדש. בכל איטרציה, השיטה נותנת ערך לשדה number המורכב מהקידומת 1000- עם הערך המוחזק בערך i של אותה איטרציה. זה אומר כי בפעם הראשונה שהלולאה מבצעת איטרציה זו, ערך השדה number יוגדר ל- 1000-1; בפעם האחרונה שהיא מבצעת איטרציה זו, הוא יוגדר ל- 1000-1000000.

המטבע מיוצג תמיד כ- USD עבור חשבונות עם מספרים גבוהים מ- 500000 וכ- EUR עבור חשבונות עם מספרים נמוכים מכך. השדה המאזן משתמש בפונקציית Math.random() כדי ליצור מספר אקראי בין 0 ל-1, ואז מכפיל את המספר האקראי ב-100000 כדי לספק ערכים גדולים יותר.

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

הפלט יידלק אותך על הצלחה ויחזיר את ה- ObjectId של המסמך האחרון שהוכנס:

Output
{ "acknowledged" : true, "insertedId" : ObjectId("61a38a4beedf737ac8e54e82") }

ניתן לוודא כי המסמכים הוכנסו באופן תקין על ידי הרצת השיטה count() בלי פרמטרים, שתחזיר את מספר המסמכים באוסף:

  1. db.accounts.count()
Output
1000000

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

שלב 2 — בדיקת סטטיסטיקות שימוש בשרת

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

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

ספציפית, השיטה serverStatus() שמתוארת בשלב זה וכן הפקודות mongostat ו־mongotop המודגשות בשלב הבא, דורשות מהמשתמשים להיות מוענקות הרשאת התקן clusterMonitor כדי להריץ אותן. באופן דומה, השיטה setProfilingLevel() המוצגת בשלב 4 דורשת הרשאת מנהל מסד נתונים dbAdmin.

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

ראשית, החלף לבסיס הנתונים של הזיהוי של המשתמש שלך. בדוגמה הבאה, זה admin, אך התחבר לבסיס הנתונים של הזיהוי של המשתמש שלך אם זה שונה:

  1. use admin
Output
switched to db admin

לאחר מכן, הפעל את השיטה grantRolesToUser() והענק למשתמש שלך את התפקיד clusterMonitor יחד עם התפקיד dbAdmin על בסיס הנתונים שבו יצרת את אוסף ה- accounts. בדוגמה הבאה מניחה שאוסף ה- accounts נמצא בבסיס הנתונים test:

  1. db.grantRolesToUser(
  2. "AdminSammy",
  3. [
  4. "clusterMonitor",
  5. { role : "dbAdmin", db : "test" }
  6. ]
  7. )

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

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

  1. db.createUser(
  2. {
  3. user: "MonitorSammy",
  4. pwd: passwordPrompt(),
  5. roles: [ { role : "dbAdmin", db : "test" }, "clusterMonitor", "readWriteAnyDatabase" ]
  6. }
  7. )

לאחר שהענקת התפקידים המתאימים למשתמש שלך, נווט בחזרה אל בסיס הנתונים שבו מאוחסן אוסף ה- accounts:

  1. use test
Output
switched to db test

התחל על ידי בדיקת הסטטיסטיקות הכלליות של בסיס הנתונים על ידי ביצוע השיטה stats():

  1. db.stats(1024*1024)

הפרמטר של השיטה זו (1024*1024) הוא גורם הקנה מידה ומספר ל-MongoDB להחזיר מידע אחסון במגהבייטים. אם תוותר על זה, הערכים יוצגו כולם בבתים.

השיטה stats() מחזירה פלט קצר ומתואר ברובו בעל מספרים חשובים הקשורים לבסיס הנתונים הנוכחי:

Output
{ "db" : "test", "collections" : 3, "views" : 0, "objects" : 1000017, "avgObjSize" : 80.8896048767171, "dataSize" : 77.14365005493164, "storageSize" : 24.109375, "indexes" : 4, "indexSize" : 9.9765625, "totalSize" : 34.0859375, "scaleFactor" : 1048576, "fsUsedSize" : 4238.12109375, "fsTotalSize" : 24635.703125, "ok" : 1 }

הפלט הזה מספק סקירה של הנתונים שבהם המונגו־די-בי הזה מאוחסן. המפתחות הבאים שמוחזרים בפלט הזה יכולים להיות שימושיים במיוחד:

  • המפתח objects מציין את מספר המסמכים הכולל בבסיס הנתונים. ניתן להשתמש בזה כדי להעריך את גודל הבסיס נתונים ו, כאשר מתבצעת ניטור לאורך זמן, את הצמיחה שלו.
  • avgObjectSize מציין את הגודל הממוצע של מסמכים אלה, נותן מבט לתוך האם הבסיס נתונים פועל על מסמכים גדולים ומורכבים או קטנים. ערך זה מוצג תמיד בבתים, בלתי תלוי אם צוין גורם סקאלה.
  • המפתחות collections ו־indexes מציינים כמה אוספים ואינדקסים כרגע מוגדרים בבסיס הנתונים.
  • המפתח totalSize מציין כמה אחסון הבסיס הנתונים משתמש בו בדיסק.

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

  1. db.serverStatus()

פלט של השיטה הזו ארוך ומספק כמויות של מידע על שימוש השרת:

Output
{ "host" : "ubuntu-mongo-rs", "version" : "4.4.6", "process" : "mongod", "pid" : NumberLong(658997), "uptime" : 976, . . . "ok" : 1 }

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

Output
. . . "connections" : { "current" : 4, "available" : 51196, "totalCreated" : 4, "active" : 2, "exhaustIsMaster" : 1, "exhaustHello" : 0, "awaitingTopologyChanges" : 1 }, . . .

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

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

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

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

Output
. . . "globalLock" : { "totalTime" : NumberLong(975312000), "currentQueue" : { "total" : 0, "readers" : 0, "writers" : 0 }, "activeClients" : { "total" : 0, "readers" : 0, "writers" : 0 } },

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

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

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

לבסוף, מצא את הקטע opcounters:

Output
"opcounters" : { "insert" : NumberLong(10000007), "query" : NumberLong(6), "update" : NumberLong(6), "delete" : NumberLong(0), "getmore" : NumberLong(0), "command" : NumberLong(1298) },

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

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

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

שלב 3 — השימוש ב־mongostat ו־mongotop כדי לקבל סטטיסטיקות בזמן אמת של בסיס הנתונים

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

‏MongoDB מספקת שני כלים מערכתיים שימושיים למעקב בזמן אמת המנתחים את פעילות בסיס הנתונים ומרעננים באופן קבוע את המידע שהם מספקים: mongostat ו־mongotop. mongostat מספק סקירה קצרה של מצב המופע של MongoDB כרגע, בעוד ש־mongotop מעקב אחר כמה זמן המופע מבצע פעולות קריאה וכתיבה. שני הכלים הללו מופעלים מהשורת פקודה, בניגוד לתוך MongoDB shell.

‏כדי להשתמש ב־mongostat, שמור על החיבור הנוכחי שלך ל־MongoDB shell, ופתח חלון טרמינל נוסף כדי לגשת לשורת הפקודה של השרת שלך. בשורת הפקודה שנייה של השרת, הפעל את פקודת mongostat:

  1. mongostat -u AdminSammy --authenticationDatabase admin

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

בהגדרת ברירת מחדל, mongostat מדפיס את המוניטור של שאילתות שמתבצעות כרגע במרווחי שנייה:

Output
insert query update delete getmore command dirty used flushes vsize res qrw arw net_in net_out conn time *0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.4k 7 Nov 28 15:40:40.621 *0 *0 *0 *0 0 2|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 224b 84.8k 7 Nov 28 15:40:41.619 *0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 223b 84.5k 7 Nov 28 15:40:42.621 *0 *0 *0 *0 0 3|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 365b 85.0k 7 Nov 28 15:40:43.619

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

עליך עדיין להשאיר את החלון הראשון פתוח ומחובר לקופסת האמת של MongoDB. הכנס כמה מסמכים נוספים לאוסף accounts ובדוק אם mongostat יזהה את הפעילות:

  1. for (let i = 1; i <= 10000; ++i) {
  2. db.accounts.insertOne({
  3. "number": "2000-" + i,
  4. "currency": "USD",
  5. "balance": Math.random() * 100000
  6. })
  7. }

זהו לולאת for דומה לאלה שהרצת בשלב 1. הפעם, למרות זאת, הלולאה מכניסה רק 10000 רשומות. מספרי החשבונות מתחילים בקידומת של 2000, והמטבע הוא תמיד דולר אמריקאי.

בזמן שהמסמכים החדשים מתקבלים, בדוק את פלט ה-mongostat:

Output
. . . *0 *0 *0 *0 0 1|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 112b 42.5k 4 Nov 28 15:50:33.294 *0 *0 *0 *0 0 0|0 0.0% 38.7% 0 1.54G 210M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:34.295 755 *0 *0 *0 0 1|0 0.1% 38.8% 0 1.54G 210M 0|0 1|0 154k 79.4k 4 Nov 28 15:50:35.294 2853 *0 *0 *0 0 0|0 0.4% 39.1% 0 1.54G 211M 0|0 1|0 585k 182k 4 Nov 28 15:50:36.295 2791 *0 *0 *0 0 1|0 0.7% 39.4% 0 1.54G 212M 0|0 1|0 572k 179k 4 Nov 28 15:50:37.293 2849 *0 *0 *0 0 0|0 1.0% 39.7% 0 1.54G 213M 0|0 1|0 584k 182k 4 Nov 28 15:50:38.296 745 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 153k 79.2k 4 Nov 28 15:50:39.294 *0 *0 *0 *0 0 0|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 111b 42.2k 4 Nov 28 15:50:40.295 *0 *0 *0 *0 0 2|0 1.1% 39.8% 0 1.54G 213M 0|0 1|0 167b 42.7k 4 Nov 28 15:50:41.293 . . .

כאשר השאילתה רצה, השורות החדשות שמוחזרות על ידי mongostat מתחילות להציג ערכים שונים מ- 0. בעמודת insert המציינת את מספר השאילתות שמכניסות נתונים חדשים למסד הנתונים, הערכים היו גבוהים למספר שניות. מאחר ו- mongostat מציג נתונים במרווחי שנייה אחת, תוכל למצוא לא רק את יחס ההכנסות לעומת סוגי הפעולות האחרות של בסיס הנתונים, אלא גם כמה מהיר במסד הנתונים מכניס את הנתונים החדשים. בדוגמה זו, השרת הגיע לכמעט 3000 הכנסות לשניה.

תוכל להשתמש ב- mongostat כדי לפקוח על העומס הנוכחי של שרת בסיס הנתונים, מקובץ לפי סוגי השאילתות. הכלי השני שמגיע עם MongoDB – mongotop – מציג פעילות שרת בסיס הנתונים, מקובץ לפי אוספים.

עצור את mongostat מהרצה בחלון הטרמינל השני שלך על ידי לחיצה על CTRL + C. לאחר מכן, הפעל את mongotop באותו טרמינל. שוב, אם יש לך אימות מופעל, תצטרך להתחבר כמשתמש עם הרשאות מתאימות:

  1. mongotop -u AdminSammy --authenticationDatabase admin

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

Output
2021-11-28T15:54:42.290+0000 connected to: mongodb://localhost/ ns total read write 2021-11-28T15:54:43Z admin.system.roles 0ms 0ms 0ms admin.system.version 0ms 0ms 0ms config.system.sessions 0ms 0ms 0ms config.transactions 0ms 0ms 0ms local.system.replset 0ms 0ms 0ms test.accounts 0ms 0ms 0ms . . .

נסה להכניס מסמכים נוספים לבסיס הנתונים כדי לראות אם הפעילות רושמת ב- mongotop. במסד הנתונים של MongoDB, בצע את לולאת ה- for הבאה; לאחר הרצתה, תסתכל על חלון הטרמינל עם mongotop ברציפות:

  1. for (let i = 1; i <= 10000; ++i) {
  2. db.accounts.insertOne({
  3. "number": "3000-" + i,
  4. "currency": "USD",
  5. "balance": Math.random() * 100000
  6. })
  7. }

הפעם, הפעילות תהיה נראית בסטטיסטיקות של mongotop.

Output
. . . ns total read write 2021-11-28T15:57:27Z test.accounts 127ms 0ms 127ms admin.$cmd.aggregate 0ms 0ms 0ms admin.system.roles 0ms 0ms 0ms admin.system.version 0ms 0ms 0ms config.system.sessions 0ms 0ms 0ms config.transactions 0ms 0ms 0ms local.system.replset 0ms 0ms 0ms ns total read write 2021-11-28T15:57:28Z test.accounts 130ms 0ms 130ms admin.$cmd.aggregate 0ms 0ms 0ms admin.system.roles 0ms 0ms 0ms admin.system.version 0ms 0ms 0ms config.system.sessions 0ms 0ms 0ms config.transactions 0ms 0ms 0ms local.system.replset 0ms 0ms 0ms . . .

כאן, mongotop מראה שכל הפעילות במסד הנתונים קרתה באוסף accounts במסד הנתונים test ושכל הפעולות בחלון הזמן היו פעולות כתיבה. כל זה צריך להיות מותאם עם הפעולה של לולאת for שביצעת.

כמו גם עם mongostat, אפשר לעצור את mongotop מהרצתו על ידי לחיצה על CTRL + C.

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

שלב 4 — שימוש בפרופיילר בסיס הנתונים של MongoDB כדי לזהות שאילתות איטיות

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

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

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

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

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

  1. db.accounts.find({"number": "1000-20"})

הפקודה תבקש את החשבון המדויק שביקשת:

Output
{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }

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

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

  1. db.setProfilingLevel(1, { slowms: 100 })

שיטת setProfilingLevel() מקבלת שני ארגומנטים. הראשון הוא רמת הפרופיל, שיכולה להיות 0, 1, או 2:

  • 0 משבית את הפרופילר
  • 1 מאפשר את הפרופילר רק על שאילתות איטיות שעונות על התנאי
  • 2 מפעיל את הפרופיילר עבור כל השאילתות

בדוגמה זו, הפרופיילר ינתח שאילתות שרצות לפחות 100 מילישניות, כפי שמוגדר בארגומנט השני, { slowms: 100 }.

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

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

השיטה הזו תחזיר הודעת הצלחה:

Output
{ "was" : 0, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }

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

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

  1. db.accounts.count()

הפקודה הזו תחזיר מהר את מספר המסמכים באוסף:

Output
1020000

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

  1. db.accounts.find().limit(3)

שוב, הבסיס נתונים יחזיר את התוצאות במהירות:

Output
{ "_id" : ObjectId("61ef40640f2ba52efc56ee17"), "number" : "1000-1", "currency" : "EUR", "balance" : 25393.132960293842 } { "_id" : ObjectId("61ef40640f2ba52efc56ee18"), "number" : "1000-2", "currency" : "EUR", "balance" : 63629.42056192393 } { "_id" : ObjectId("61ef40640f2ba52efc56ee19"), "number" : "1000-3", "currency" : "EUR", "balance" : 75602.12331602155 }

לבסוף, הריצו שאילתת חיפוש עבור החשבון הבנקי המסוים פעם נוספת:

  1. db.accounts.find({"number": "1000-20"})

השאילתה הזו תחזיר את התוצאה, אך, כמו קודם, יידרש רגע או שניים יותר מהפעולות הקודמות:

Output
{ "_id" : ObjectId("61a38fd5eedf737ac8e54e96"), "number" : "1000-20", "currency" : "EUR", "balance" : 24101.14770458518 }

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

כדי לקבל מידע על שאילתות שזוהו על ידי הפרופילר, עליך לשאול את אוסף המערכת system.profile בדרך כזו:

  1. db.system.profile.find().sort({ "ts" : -1 }).pretty()

השאילתה הזו משתמשת בשיטת find(), כפי שרגיל. היא כוללת גם עורך sort שמכיל את { "ts" : -1 } כארגומנט. זה ימיין את סט התוצאות עם השאילתות האחרונות ביותר ראשונות. לבסוף, השיטה pretty() בסוף תציג את הפלט בפורמט קריא יותר.

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

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

Output
{ "op" : "query", "ns" : "test.accounts", "command" : { "find" : "accounts", "filter" : { "number" : "1000-20" }, . . . }, "nreturned" : 1, "keysExamined" : 0, "docsExamined" : 1030000, . . . "millis" : 434, "planSummary" : "COLLSCAN", . . . }

הפלט הזה מספק מספר פרטים אודות ביצועי השאילתה האיטית:

  • המפתח op מציין איזו פעולה מסוג זה מייצגת מידע זה. כאן, זהו query, מאחר והוא מייצג פעולה שבה השתמשת ב- find() כדי לאחזר מידע ממסד הנתונים.
  • המפתח ns מציין איזה מסד נתונים ואוסף היו מעורבים בפעולה. כפי שהפלט מראה, הפעולה הזו שאילתה את אוסף ה- accounts במסד הנתונים test.
  • המפתח command מספק מידע נוסף אודות השאילתה עצמה. במקרה זה, התת-מפתח filter מכיל את מסמך המסנן במלואו. באמצעות המידע שמגיע משדות op ו- command, אתה יכול לשחזר את השאילתה בשאלה.
  • בשדה millis, תמצא את הזמן המדויק שנדרש כדי להשלים את השאילתה. בדוגמה זו, כמעט חצי שנייה.
  • השדה docsExamined מספק את מספר המסמכים שנסרקו כדי להחזיר את קבוצת התוצאות.
  • nreturned מייצג את מספר המסמכים שהשאילתה החזירה. בדוגמה זו, נחזיר רק מסמך אחד מתוך מעל מיליון שנסרקו.
  • ה- planSummary מציג את השיטה שמונגו נעשה בה שימוש בכדי לבצע את השאילתה. COLLSCAN מתאים לסריקה מלאה של אוסף, שפונה לסרוק כל מסמך באוסף אחד לפי אחד כדי למצוא את החשבון הבנקי התואם.

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

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

כדי לסיים את סשן הפרופילינג, ניתן לנטר את הפרופילר על ידי הגדרת רמת הפרופילינג לאפס:

  1. db.setProfilingLevel(0)

הפעולה תצליח עם הודעת אישור:

Output
{ "was" : 1, "slowms" : 100, "sampleRate" : 1, "ok" : 1 }

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

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

מסקנה

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

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

Source:
https://www.digitalocean.com/community/tutorials/how-to-monitor-mongodb-s-performance