שיפור זמן השאילתה באמצעות הוספה לאינדקס בהתאמה אישית

במאמר הזה מוסבר איך להוסיף שדות LogEntry עם אינדקס לקטגוריות ב-Cloud Logging כדי להריץ שאילתות על נתוני היומנים מהר יותר.

סקירה כללית

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

כדי לשפר את ביצועי השאילתות, מערכת Logging יוצרת באופן אוטומטי אינדקס לשדות LogEntry הבאים:

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

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

באמצעות Google Cloud CLI או Logging API, אתם יכולים להוסיף אינדקסים בהתאמה אישית למאגרי יומנים קיימים או חדשים. כשבוחרים שדות נוספים להכללה באינדקס המותאם אישית, חשוב לשים לב למגבלות הבאות:

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

לפני שמתחילים

לפני שמתחילים להגדיר אינדקס בהתאמה אישית:

  • מוודאים שמשתמשים בגרסה העדכנית ביותר של ה-CLI של gcloud. מידע נוסף זמין במאמר ניהול רכיבים של Google Cloud CLI.

    .
  • צריך לוודא שיש לכם תפקיד בניהול זהויות והרשאות גישה (IAM) עם ההרשאות הבאות:

    במאמר בקרת גישה באמצעות IAM מוסבר בהרחבה על התפקידים האלה.

הגדרת האינדקס המותאם אישית

לכל שדה שמוסיפים לאינדקס בהתאמה אישית של מאגר, מגדירים שני מאפיינים: נתיב שדה וסוג שדה:

  • fieldPath: מתאר את הנתיב הספציפי לשדה LogEntry ברשומות היומן. לדוגמה, jsonPayload.req_status.
  • type: מציין אם השדה הוא מסוג מחרוזת או מספר שלם. הערכים האפשריים הם INDEX_TYPE_STRING ו-INDEX_TYPE_INTEGER.

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

כדי להגדיר אינדקס בהתאמה אישית כשיוצרים קטגוריה:

gcloud

משתמשים בפקודה gcloud logging buckets create ומגדירים את הדגל --index:

gcloud logging buckets create BUCKET_NAME \
--location=LOCATION \
--description="DESCRIPTION" \
--index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

פקודה לדוגמה:

gcloud logging buckets create int_index_test_bucket \
--location=global \
--description="Bucket with integer index" \
--index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

כדי ליצור קטגוריה, משתמשים ב-projects.locations.buckets.create ב-Logging API. מכינים את הארגומנטים של השיטה באופן הבא:

  1. מגדירים את הפרמטר parent בתור המשאב שבו רוצים ליצור את הדלי: projects/PROJECT_ID/locations/LOCATION

    המשתנה LOCATION מתייחס לאזור שבו רוצים לאחסן את היומנים.

    לדוגמה, אם רוצים ליצור קטגוריה לפרויקט my-project באזור asia-east2, הפרמטר parent ייראה כך: projects/my-project/locations/asia-east2

  2. מגדירים את הפרמטר bucketId. לדוגמה, my-bucket.

  3. בגוף הבקשה LogBucket, מגדירים את האובייקט IndexConfig כדי ליצור את האינדקס בהתאמה אישית.

  4. מריצים את הפקודה projects.locations.buckets.create כדי ליצור את הקטגוריה.

כדי לעדכן באקט קיים ולהוסיף לו אינדקס בהתאמה אישית:

gcloud

משתמשים בפקודה gcloud logging buckets update ומגדירים את הדגל --add-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--add-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

פקודה לדוגמה:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--add-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

משתמשים ב-projects.locations.buckets.patch ב-Logging API. בגוף הבקשה LogBucket, מגדירים את האובייקט IndexConfig כך שיכלול את השדות LogEntry שרוצים ליצור להם אינדקס.

מחיקה של שדה מותאם אישית עם אינדקס

כדי למחוק שדה מאינדקס בהתאמה אישית של דלי:

gcloud

משתמשים בפקודה gcloud logging buckets update ומגדירים את הדגל --remove-indexes :

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--remove-indexes=INDEX_FIELD_NAME

פקודה לדוגמה:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--remove-indexes=jsonPayload.req_status

API

משתמשים ב-projects.locations.buckets.patch ב-Logging API. בגוף הבקשה LogBucket, מסירים את השדות LogEntry מהאובייקט IndexConfig.

עדכון סוג הנתונים של שדה מותאם אישית באינדקס

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

gcloud

משתמשים בפקודה gcloud logging buckets update ומגדירים את הדגל --update-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--update-index=fieldPath=INDEX_FIELD_NAME,type=INDEX_TYPE

פקודה לדוגמה:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--update-index=fieldPath=jsonPayload.req_status,type=INDEX_TYPE_INTEGER

API

משתמשים ב-projects.locations.buckets.patch ב-Logging API. בגוף הבקשה LogBucket, מעדכנים את האובייקט IndexConfig כדי לספק את סוג הנתונים הנכון לשדה LogEntry.

עדכון הנתיב של שדה מותאם אישית עם אינדקס

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

gcloud

משתמשים בפקודה gcloud logging buckets update ומגדירים את הדגלים --remove-indexes ו---update-index:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--remove-indexes=OLD_INDEX_FIELD_NAME \
--update-index=fieldPath=NEW_INDEX_FIELD_NAME,type=INDEX_TYPE

פקודה לדוגמה:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--remove-indexes=jsonPayload.req_status_old_path \
--add-index=fieldPath=jsonPayload.req_status_new_path,type=INDEX_TYPE_INTEGER

API

משתמשים ב-projects.locations.buckets.patch ב-Logging API. בגוף הבקשה LogBucket, מעדכנים את האובייקט IndexConfig כדי לספק את נתיב השדה הנכון לשדה LogEntry.

הצגת רשימה של כל השדות שעברו אינדוקס לקטגוריה

כדי להציג את פרטי הקטגוריה, כולל השדות המותאמים אישית שמוגדרים בה:

gcloud

משתמשים בפקודה gcloud logging buckets describe:

gcloud logging buckets describe BUCKET_NAME \
--location=LOCATION

פקודה לדוגמה:

gcloud logging buckets describe indexed-bucket \
--location global

API

משתמשים ב-projects.locations.buckets.get ב-Logging API.

מחיקת שדות מותאמים אישית עם אינדקס

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

gcloud

משתמשים בפקודה gcloud logging buckets update ומוסיפים את הדגל --clear-indexes:

gcloud logging buckets update BUCKET_NAME \
--location=LOCATION \
--clear-indexes

פקודה לדוגמה:

gcloud logging buckets update int_index_test_bucket \
--location=global \
--clear-indexes

API

משתמשים ב-projects.locations.buckets.patch ב-Logging API. בגוף הבקשה LogBucket, מוחקים את האובייקט IndexConfig.

שליחת שאילתות והצגת נתונים שנוספו לאינדקס

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

gcloud

כדי לקרוא יומנים מקטגוריה ביומן, משתמשים בפקודה gcloud logging read ומוסיפים את האפשרות LOG_FILTER כדי לכלול את הנתונים שנוספו לאינדקס:

gcloud logging read LOG_FILTER --bucket=BUCKET_ID --location=LOCATION --view=LOG_VIEW_ID

API

כדי לקרוא יומנים מקטגוריית יומנים, משתמשים בשיטה entries.list. מגדירים את resourceNames כדי לציין את הקטגוריה ואת תצוגת היומן המתאימות, ומגדירים את filter כדי לבחור את הנתונים שעברו אינדוקס.

מידע מפורט על תחביר הסינון זמין במאמר בנושא שפת השאילתות של Logging.

הוספה לאינדקס וסוגי שדות

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

בזמן הכתיבה

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

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

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

בזמן השאילתה

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

כשמגדירים אינדקס בהתאמה אישית לקטגוריה, התנהגויות של התאמת סכימה שונות כשמתקיימים שני התנאים הבאים:

  • סוג הנתונים של שדה במקור לא תואם לסוג האינדקס של השדה הזה.
  • המשתמש מחיל אילוץ על השדה הזה.

כדאי לעיין במטענים הייעודיים (payloads) הבאים של JSON:

{"jsonPayload": {"name": "A", "value": 12345}}
{"jsonPayload": {"name": "B", "value": "3"}}

עכשיו נחיל את המסנן הזה על כל אחד מהם:

jsonPayload.value > 20

אם בשדה jsonPayoad.value אין הוספה לאינדקס בהתאמה אישית, הרישום ביומן יתבצע בהתאם להתאמה של סוגים גמישים:

  • במקרה של 'A', מערכת הרישום רואה שהערך של המפתח 'value' הוא למעשה מספר שלם, ושאפשר להמיר את האילוץ '20' למספר שלם. הפונקציה Logging בוחנת את 12345 > 20 ומחזירה את הערך true כי זה המקרה מבחינה מספרית.

  • במקרה של 'B', הרישום ביומן מראה שהערך של המפתח 'value' הוא למעשה מחרוזת. לאחר מכן הפונקציה בודקת את "3" > "20" ומחזירה את הערך true, כי זה המקרה לפי סדר אלפאנומרי.

אם השדה jsonPayload.value כלול באינדקס המותאם אישית, מערכת Logging מעריכה את האילוץ הזה באמצעות האינדקס במקום באמצעות הלוגיקה הרגילה של Logging. ההתנהגות משתנה:

  • אם האינדקס הוא מסוג מחרוזת, כל ההשוואות הן השוואות של מחרוזות.
    • הערך 'A' לא תואם, כי '12345' לא גדול מ-'20' מבחינה אלפאנומרית. הערך 'B' תואם, כי המחרוזת '3' גדולה מ-'20'.
  • אם האינדקס הוא מסוג integer, כל ההשוואות הן השוואות של מספרים שלמים.
    • הערך 'B' לא תואם, כי הערך '3' לא גדול מהערך '20' מבחינה מספרית. הערך 'A' תואם, כי '12345' גדול מ-'20'.

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

סינון מקרי קצה

נניח שמסננים ערך מחרוזת באינדקס jsonPayload.value מסוג מספר שלם:

jsonPayload.value = "hello"

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

עם זאת, נניח שבאינדקס מסוג מחרוזת, מעבירים ערך מספרי:

jsonPayload.value > 50

אף אחד מהערכים A ו-B לא תואם, כי אף אחד מהערכים '12345' ו-'3' לא גדול יותר מבחינה אלפאנומרית מהערך '50'.