מעקב אחרי הזמנות ב-BigQuery
אדמינים ב-BigQuery יכולים לעקוב אחרי הזמנות בפרויקט שלהם על ידי צפייה בשימוש במשבצות בפרויקט ובהזמנה, וגם לראות את החיוב לפי הקיבולת.
צפייה בשימוש במשבצות של פרויקטים והזמנות
יש כמה דרכים לבדוק את השימוש בפרויקט ובמשבצות להזמנה:
INFORMATION_SCHEMAצפיות. כדי לאחזר נתוני שימוש בפרויקט ובשריין, מריצים שאילתה על התצוגות שלINFORMATION_SCHEMA.JOBS*.השדה
reservation_idבתצוגותINFORMATION_SCHEMA.JOBS*מכיל את שם ההזמנה.Cloud de Confiance console. במסוף Cloud de Confiance יש תרשימים שמציגים את השימוש בחריצים. מידע נוסף זמין במאמר שימוש בתרשימים של משאבים אדמיניסטרטיביים.
יומני ביקורת. אפשר להשתמש ביומני ביקורת כדי לראות מדדים לגבי השימוש במשבצות.
השיטה
Jobs. משתמשים ב-method Jobsשל API כדי לראות מדדים לגבי השימוש במשבצות למשרה.Cloud Monitoring. אתם יכולים להשתמש ב-Cloud Monitoring כדי ליצור לוחות בקרה למעקב אחרי המשבצות שהוקצו לכם. באמצעות לוח בקרה של Cloud Monitoring, אתם יכולים לראות את השימוש במשבצות לכל הזמנה ולכל סוג עבודה, בכל הפרויקטים בהזמנה. כדי לראות את מדדי השימוש ביחידות קיבולת (Slot) לכל הפרויקטים שצורכים מהזמנה, צריך להוסיף במפורש את הפרויקטים האלה להיקף המדדים בפרויקט של הפרויקט שבו אתם עוקבים אחרי המדדים. מידע נוסף על המדדים שזמינים בלוח הבקרה של Cloud Monitoring זמין במאמר מדדים שזמינים להצגה.

הסבר על מדדים של משבצות
כדי לעקוב אחרי קיבולת המחשוב של BigQuery ולנהל אותה בצורה יעילה, צריך להבחין בין יחידות קיבולת שהוקצו לבין יחידות קיבולת שנמצאות בשימוש:
- משבצות שהוקצו
- הקיבולת שמוקצית לפרויקט באמצעות חריצי בסיס ומחויבויות לקיבולת פעילה. המשבצות שהוקצו משפיעות על המכסה ועל החיוב.
- יחידות קיבולת (Slots) בשימוש
- הקיבולת שנצרכת באופן פעיל על ידי הרצת משימות במהלך הרצת שאילתה. משבצות זמן שנוצלו מופיעות בתרשימים של ניצול משאבים.
מכיוון שמשבצות בסיסיות הן משאבים ייעודיים, הן מדווחות כ'בשימוש' על ידי מערכת המכסות גם כשלא מתבצעות שאילתות באופן פעיל. לכן, יכול להיות שהשימוש במכסות שמופיע בדף Quotas & System Limits יהיה גבוה יותר מהשימוש בפועל במשבצות שמופיע בדף Monitoring.
השוואה בין מדדים של משבצות
בטבלה הבאה מוצגת השוואה בין אופן החישוב וההצגה של מדדי משבצות המודעות במסוף Cloud de Confiance :
| דף המסוף שלCloud de Confiance | המדד שמוצג | מה נספר | מקור הפער |
|---|---|---|---|
| מכסות ומגבלות מערכת | המכסה בשימוש (מספר המשבצות הכולל; ראו תרשימים של ניצול המכסה) | יחידות קיבולת שהוקצו: יחידות קיבולת בסיסיות להזמנה והתחייבויות פעילות. | כולל משבצות בסיס לא פעילות והזמנות לגיבוי לא פעילות באזורים משניים. לא כולל משבצות של שינוי גודל אוטומטי. |
| מעקב | שימוש ביחידת קיבולת (תרשימי ניצול משאבים) | משבצות בשימוש: יחידות מחשוב שנצרכות באופן פעיל על ידי משימות שמופעלות. | כולל פרצי גידול אוטומטי שמעבדים באופן פעיל משימות. לא כולל משבצות בסיסיות פנויות והזמנות גיבוי לא פעילות. |
סיבות נפוצות לחוסר התאמה בשימוש במשבצות
כשמשווים בין מדדי משבצות בדף Quotas & System Limits לבין מדדים בדף Monitoring, חשוב לזכור את הסיבות הנפוצות הבאות להבדלים:
- משבצות זמן בסיסיות במצב המתנה: הזמנתם משבצות זמן בסיסיות שלא מריצות שאילתות באופן פעיל. מכיוון שמשבצות בסיסיות הן קיבולת ייעודית, מערכת המכסות מתייחסת אליהן כאל משבצות בשימוש, אבל בתרשימי הניצול מוצגות רק המשבצות שבהן מופעלים עומסי עבודה.
- שמירת מקום ליתירות כשל: אם מגדירים ניהול של תוכנית התאוששות מאסון (DR), יחידות הקיבולת (Slots) הבסיסיות לשמירת מקום ליתירות כשל מוקצות באזור המשני. המשבצות האלה מופיעות כמכסה בשימוש באזור המשני גם כשההזמנה לא פעילה ולא בוצע מעבר לגיבוי. מידע נוסף מופיע במאמר בנושא שיקולים לגבי מכסות בהזמנות של מעבר לגיבוי בעת כשל.
- פרצי שינוי גודל אוטומטי: תרשימי ניצול המשאבים כוללים משבצות של שינוי גודל אוטומטי שמעבדות עבודות באופן פעיל. לעומת זאת, בדף Quotas & System Limits מוצג רק קיבולת סטטית שהוקצתה (בסיסית והתחייבויות), ולא נספרים משבצות של שינוי גודל אוטומטי.
איך רואים את החשבון על בסיס הקיבולת
כדי לראות את החשבון שלכם בזמן אמת לפי הקיבולת, פועלים לפי השלבים הבאים:
נכנסים לדף Billing במסוף Cloud de Confiance .
בוחרים את הפרויקט של החשבון לחיוב שרוצים לראות את החשבון שלו.
עוברים לקטע דוחות ואז לקטע מסננים ופועלים לפי השלבים הבאים:
- ברשימה Services, בוחרים באפשרות BigQuery ובוחרים את כל האפשרויות הרלוונטיות.
- בוחרים באפשרות All SKUs (כל המק"טים) מתוך הרשימה SKUs (מק"טים).
שיוך עלויות של הזמנות
התכונה הזו מאפשרת לכם לייחס את העמלות על מקום שמור לשימוש בשאילתה ספציפית בפרויקטים שבהם נעשה שימוש במקום השמור. כך מתקבלות עלויות נטו מדויקות יותר לכל פרויקט.
לכל הלקוחות של BigQuery Reservations API יש שורה עם הכיתוב Analysis Slots Attribution בנתוני החיוב ב-Cloud. הפריט הזה מופיע בדף Billing ובייצוא של החיוב ב-Cloud.
בפריט הזה מוצגים השעות שבהן נעשה שימוש במשבצות זמן לכל פרויקט. השימוש בו לא כרוך בעלות והוא לא משפיע על הסכומים הכוללים בחשבונית.
יומני ביקורת
פעולות שקשורות להזמנות ב-BigQuery כמו יצירה, מחיקה ועדכון של משאבים, מתועדות ביומני הביקורת של בעלי הפרויקט. מידע נוסף זמין במאמר בנושא יומן ביקורת.
מעקב אחרי שינוי גודל אוטומטי באמצעות סכימת מידע
אפשר להשתמש בסקריפטים הבאים של SQL כדי לבדוק את מספר שניות השימוש במשבצות שחויבו במהדורה מסוימת. צריך להריץ את הסקריפטים האלה באותו פרויקט שבו נוצרו ההזמנות. בתסריט הראשון מוצגות שניות של משבצות זמן לחיוב שכלולות ב-commitment_plan, ובתסריט השני מוצגות שניות של משבצות זמן לחיוב שלא כלולות בהתחייבות.
כדי להריץ את הסקריפטים האלה, צריך להגדיר רק את הערך של שלושה משתנים:
start_timeend_timeedition_to_check
הסייגים הבאים חלים על הסקריפטים האלה:
הזמנות ומחויבויות לקיבולת שנמחקו יוסרו מתצוגות סכימת המידע בסוף תקופת שמירת הנתונים. כדי לקבל תוצאות מדויקות, צריך לציין חלון זמן מהזמן האחרון שלא כולל הזמנות ומחויבויות שנמחקו.
יכול להיות שהתוצאה של הסקריפטים לא תהיה זהה לחשבון לתשלום בגלל שגיאות קטנות של עיגול.
הסקריפט הבא מצטבר משבצות של שינוי גודל אוטומטי לפי מהדורה.
כדי לראות את הסקריפט לחישוב שניות של משבצות להרחבת הקיבולת לכל מהדורה, צריך להרחיב את הקטע.
SELECT edition, SUM(s.autoscale_current_slots) AS autoscale_slot_seconds FROM `region-us.INFORMATION_SCHEMA.RESERVATIONS_TIMELINE` m JOIN m.per_second_details s WHERE period_start BETWEEN '2025-09-28' AND '2025-09-29' GROUP BY edition ORDER BY edition
הסקריפט הבא מצטבר משבצות של הרחבת נפח האחסון לפי הזמנה.
כדי לראות את הסקריפט לחישוב שניות של משבצות לשינוי גודל אוטומטי לכל הזמנה, מרחיבים את הקטע.
select reservation_id, sum(s.autoscale_current_slots) as autoscale_slot_seconds from `region-us.INFORMATION_SCHEMA.RESERVATIONS_TIMELINE` m LEFT JOIN m.per_second_details s WHERE period_start between '2025-09-28' and '2025-09-29' group by reservation_id order by reservation_id
אפשר להרחיב כדי לראות את הסקריפט לחישוב שניות הפרסום במשבצת מתוך התחייבויות.
DECLARE start_time,end_time TIMESTAMP; DECLARE edition_to_check STRING; /* Google uses Pacific Time to calculate the billing period for all customers, regardless of their time zone. Use the following format if you want to match the billing report. Change the start_time and end_time values to match the desired window. */ /* The following three variables (start_time, end_time, and edition_to_check) are the only variables that you need to set in the script. During daylight savings time, the start_time and end_time variables should follow this format: 2024-02-20 00:00:00-08. */ SET start_time = "2023-07-20 00:00:00-07"; SET end_time = "2023-07-28 00:00:00-07"; SET edition_to_check = 'ENTERPRISE'; /* The following function returns the slot seconds for the time window between two capacity changes. For example, if there are 100 slots between (2023-06-01 10:00:00, 2023-06-01 11:00:00), then during that window the total slot seconds will be 100 * 3600. This script calculates a specific window (based on the variables defined above), which is why the following script includes script_start_timestamp_unix_millis and script_end_timestamp_unix_millis. */ CREATE TEMP FUNCTION GetSlotSecondsBetweenChanges( slots FLOAT64, range_begin_timestamp_unix_millis FLOAT64, range_end_timestamp_unix_millis FLOAT64, script_start_timestamp_unix_millis FLOAT64, script_end_timestamp_unix_millis FLOAT64) RETURNS INT64 LANGUAGE js AS r""" if (script_end_timestamp_unix_millis < range_begin_timestamp_unix_millis || script_start_timestamp_unix_millis > range_end_timestamp_unix_millis) { return 0; } var begin = Math.max(script_start_timestamp_unix_millis, range_begin_timestamp_unix_millis) var end = Math.min(script_end_timestamp_unix_millis, range_end_timestamp_unix_millis) return slots * Math.ceil((end - begin) / 1000.0) """; /* Sample CAPACITY_COMMITMENT_CHANGES data (unrelated columns ignored): +---------------------+------------------------+-----------------+--------+------------+--------+ | change_timestamp | capacity_commitment_id | commitment_plan | state | slot_count | action | +---------------------+------------------------+-----------------+--------+------------+--------+ | 2023-07-20 19:30:27 | 12954109101902401697 | ANNUAL | ACTIVE | 100 | CREATE | | 2023-07-27 22:29:21 | 11445583810276646822 | FLEX | ACTIVE | 100 | CREATE | | 2023-07-27 23:10:06 | 7341455530498381779 | MONTHLY | ACTIVE | 100 | CREATE | | 2023-07-27 23:11:06 | 7341455530498381779 | FLEX | ACTIVE | 100 | UPDATE | The last row indicates a special change from MONTHLY to FLEX, which happens because of commercial migration. */ WITH /* Information containing which commitment might have plan updated (e.g. renewal or commercial migration). For example: +------------------------+------------------+--------------------+--------+------------+--------+-----------+----------------------------+ | change_timestamp | capacity_commitment_id | commitment_plan | state | slot_count | action | next_plan | next_plan_change_timestamp | +---------------------+------------------------+-----------------+--------+------------+--------+-----------+----------------------------+ | 2023-07-20 19:30:27 | 12954109101902401697 | ANNUAL | ACTIVE | 100 | CREATE | ANNUAL | 2023-07-20 19:30:27 | | 2023-07-27 22:29:21 | 11445583810276646822 | FLEX | ACTIVE | 100 | CREATE | FLEX | 2023-07-27 22:29:21 | | 2023-07-27 23:10:06 | 7341455530498381779 | MONTHLY | ACTIVE | 100 | CREATE | FLEX | 2023-07-27 23:11:06 | | 2023-07-27 23:11:06 | 7341455530498381779 | FLEX | ACTIVE | 100 | UPDATE | FLEX | 2023-07-27 23:11:06 | */ commitments_with_next_plan AS ( SELECT *, IFNULL( LEAD(commitment_plan) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC ), commitment_plan) next_plan, IFNULL( LEAD(change_timestamp) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC ), change_timestamp) next_plan_change_timestamp FROM `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT` ), /* Insert a 'DELETE' action for those with updated plans. The FLEX commitment '7341455530498381779' is has no 'CREATE' action, and is instead labeled as an 'UPDATE' action. For example: +---------------------+------------------------+-----------------+--------+------------+--------+ | change_timestamp | capacity_commitment_id | commitment_plan | state | slot_count | action | +---------------------+------------------------+-----------------+--------+------------+--------+ | 2023-07-20 19:30:27 | 12954109101902401697 | ANNUAL | ACTIVE | 100 | CREATE | | 2023-07-27 22:29:21 | 11445583810276646822 | FLEX | ACTIVE | 100 | CREATE | | 2023-07-27 23:10:06 | 7341455530498381779 | MONTHLY | ACTIVE | 100 | CREATE | | 2023-07-27 23:11:06 | 7341455530498381779 | FLEX | ACTIVE | 100 | UPDATE | | 2023-07-27 23:11:06 | 7341455530498381779 | MONTHLY | ACTIVE | 100 | DELETE | */ capacity_changes_with_additional_deleted_event_for_changed_plan AS ( SELECT next_plan_change_timestamp AS change_timestamp, project_id, project_number, capacity_commitment_id, commitment_plan, state, slot_count, 'DELETE' AS action, commitment_start_time, commitment_end_time, failure_status, renewal_plan, user_email, edition, is_flat_rate, FROM commitments_with_next_plan WHERE commitment_plan <> next_plan UNION ALL SELECT * FROM `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT` ), /* The committed_slots change the history. For example: +---------------------+------------------------+------------------+-----------------+ | change_timestamp | capacity_commitment_id | slot_count_delta | commitment_plan | +---------------------+------------------------+------------------+-----------------+ | 2023-07-20 19:30:27 | 12954109101902401697 | 100 | ANNUAL | | 2023-07-27 22:29:21 | 11445583810276646822 | 100 | FLEX | | 2023-07-27 23:10:06 | 7341455530498381779 | 100 | MONTHLY | | 2023-07-27 23:11:06 | 7341455530498381779 | -100 | MONTHLY | | 2023-07-27 23:11:06 | 7341455530498381779 | 100 | FLEX | */ capacity_commitment_slot_data AS ( SELECT change_timestamp, capacity_commitment_id, CASE WHEN action = "CREATE" OR action = "UPDATE" THEN IFNULL( IF( LAG(action) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC ) IN UNNEST(['CREATE', 'UPDATE']), slot_count - LAG(slot_count) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC ), slot_count), slot_count) ELSE IF( LAG(action) OVER (PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC) IN UNNEST(['CREATE', 'UPDATE']), -1 * slot_count, 0) END AS slot_count_delta, commitment_plan FROM capacity_changes_with_additional_deleted_event_for_changed_plan WHERE state = "ACTIVE" AND edition = edition_to_check AND change_timestamp <= end_time ), /* The total_committed_slots history for each plan. For example: +---------------------+---------------+-----------------+ | change_timestamp | capacity_slot | commitment_plan | +---------------------+---------------+-----------------+ | 2023-07-20 19:30:27 | 100 | ANNUAL | | 2023-07-27 22:29:21 | 100 | FLEX | | 2023-07-27 23:10:06 | 100 | MONTHLY | | 2023-07-27 23:11:06 | 0 | MONTHLY | | 2023-07-27 23:11:06 | 200 | FLEX | */ running_capacity_commitment_slot_data AS ( SELECT change_timestamp, SUM(slot_count_delta) OVER ( PARTITION BY commitment_plan ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS capacity_slot, commitment_plan, FROM capacity_commitment_slot_data ), /* The slot_seconds between each changes, partitioned by each plan. For example: +---------------------+--------------+-----------------+ | change_timestamp | slot_seconds | commitment_plan | +---------------------+--------------+-----------------+ | 2023-07-20 19:30:27 | 64617300 | ANNUAL | | 2023-07-27 22:29:21 | 250500 | FLEX | | 2023-07-27 23:10:06 | 6000 | MONTHLY | | 2023-07-27 23:11:06 | 0 | MONTHLY | | 2023-07-27 23:11:06 | 5626800 | FLEX | */ slot_seconds_data AS ( SELECT change_timestamp, GetSlotSecondsBetweenChanges( capacity_slot, UNIX_MILLIS(change_timestamp), UNIX_MILLIS( IFNULL( LEAD(change_timestamp) OVER (PARTITION BY commitment_plan ORDER BY change_timestamp ASC), CURRENT_TIMESTAMP())), UNIX_MILLIS(start_time), UNIX_MILLIS(end_time)) AS slot_seconds, commitment_plan, FROM running_capacity_commitment_slot_data WHERE change_timestamp <= end_time ) /* The final result is similar to the following: +-----------------+--------------------+ | commitment_plan | total_slot_seconds | +-----------------+--------------------+ | ANNUAL | 64617300 | | MONTHLY | 6000 | | FLEX | 5877300 | */ SELECT commitment_plan, SUM(slot_seconds) AS total_slot_seconds FROM slot_seconds_data GROUP BY commitment_plan
הסקריפט הבא בודק את השימוש במשבצות שלא מכוסה על ידי התחייבויות במהדורה מסוימת. השימוש הזה כולל שני סוגים של משבצות: משבצות שניתנות להרחבה ומשבצות בסיסיות שלא מכוסות על ידי התחייבויות.
אפשר להרחיב כדי לראות את הסקריפט לחישוב שניות של משבצות שלא מכוסות על ידי התחייבויות
/* This script has several parts: 1. Calculate the baseline and scaled slots for reservations 2. Calculate the committed slots 3. Join the two results above to calculate the baseline not covered by committed slots 4. Aggregate the number */ -- variables DECLARE start_time, end_time TIMESTAMP; DECLARE edition_to_check STRING; /* Google uses Pacific Time to calculate the billing period for all customers, regardless of their time zone. Use the following format if you want to match the billing report. Change the start_time and end_time values to match the desired window. */ /* The following three variables (start_time, end_time, and edition_to_check) are the only variables that you need to set in the script. During daylight savings time, the start_time and end_time variables should follow this format: 2024-02-20 00:00:00-08. */ SET start_time = "2023-07-20 00:00:00-07"; SET end_time = "2023-07-28 00:00:00-07"; SET edition_to_check = 'ENTERPRISE'; /* The following function returns the slot seconds for the time window between two capacity changes. For example, if there are 100 slots between (2023-06-01 10:00:00, 2023-06-01 11:00:00), then during that window the total slot seconds will be 100 * 3600. This script calculates a specific window (based on the variables defined above), which is why the following script includes script_start_timestamp_unix_millis and script_end_timestamp_unix_millis. */ CREATE TEMP FUNCTION GetSlotSecondsBetweenChanges( slots FLOAT64, range_begin_timestamp_unix_millis FLOAT64, range_end_timestamp_unix_millis FLOAT64, script_start_timestamp_unix_millis FLOAT64, script_end_timestamp_unix_millis FLOAT64) RETURNS INT64 LANGUAGE js AS r""" if (script_end_timestamp_unix_millis < range_begin_timestamp_unix_millis || script_start_timestamp_unix_millis > range_end_timestamp_unix_millis) { return 0; } var begin = Math.max(script_start_timestamp_unix_millis, range_begin_timestamp_unix_millis) var end = Math.min(script_end_timestamp_unix_millis, range_end_timestamp_unix_millis) return slots * Math.ceil((end - begin) / 1000.0) """; /* Sample RESERVATION_CHANGES data (unrelated columns ignored): +---------------------+------------------+--------+---------------+---------------+ | change_timestamp | reservation_name | action | slot_capacity | current_slots | +---------------------+------------------+--------+---------------+---------------+ | 2023-07-27 22:24:15 | res1 | CREATE | 300 | 0 | | 2023-07-27 22:25:21 | res1 | UPDATE | 300 | 180 | | 2023-07-27 22:39:14 | res1 | UPDATE | 300 | 100 | | 2023-07-27 22:40:20 | res2 | CREATE | 300 | 0 | | 2023-07-27 22:54:18 | res2 | UPDATE | 300 | 120 | | 2023-07-27 22:55:23 | res1 | UPDATE | 300 | 0 | Sample CAPACITY_COMMITMENT_CHANGES data (unrelated columns ignored): +---------------------+------------------------+-----------------+--------+------------+--------+ | change_timestamp | capacity_commitment_id | commitment_plan | state | slot_count | action | +---------------------+------------------------+-----------------+--------+------------+--------+ | 2023-07-20 19:30:27 | 12954109101902401697 | ANNUAL | ACTIVE | 100 | CREATE | | 2023-07-27 22:29:21 | 11445583810276646822 | FLEX | ACTIVE | 100 | CREATE | | 2023-07-27 23:10:06 | 7341455530498381779 | MONTHLY | ACTIVE | 100 | CREATE | */ WITH /* The scaled_slots & baseline change history: +---------------------+------------------+------------------------------+---------------------+ | change_timestamp | reservation_name | autoscale_current_slot_delta | baseline_slot_delta | +---------------------+------------------+------------------------------+---------------------+ | 2023-07-27 22:24:15 | res1 | 0 | 300 | | 2023-07-27 22:25:21 | res1 | 180 | 0 | | 2023-07-27 22:39:14 | res1 | -80 | 0 | | 2023-07-27 22:40:20 | res2 | 0 | 300 | | 2023-07-27 22:54:18 | res2 | 120 | 0 | | 2023-07-27 22:55:23 | res1 | -100 | 0 | */ reservation_slot_data AS ( SELECT change_timestamp, reservation_name, CASE action WHEN "CREATE" THEN autoscale.current_slots WHEN "UPDATE" THEN IFNULL( autoscale.current_slots - LAG(autoscale.current_slots) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ), IFNULL( autoscale.current_slots, IFNULL( -1 * LAG(autoscale.current_slots) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ), 0))) WHEN "DELETE" THEN IF( LAG(action) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ) IN UNNEST(['CREATE', 'UPDATE']), -1 * autoscale.current_slots, 0) END AS autoscale_current_slot_delta, CASE action WHEN "CREATE" THEN slot_capacity WHEN "UPDATE" THEN IFNULL( slot_capacity - LAG(slot_capacity) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ), IFNULL( slot_capacity, IFNULL( -1 * LAG(slot_capacity) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ), 0))) WHEN "DELETE" THEN IF( LAG(action) OVER ( PARTITION BY project_id, reservation_name ORDER BY change_timestamp ASC, action ASC ) IN UNNEST(['CREATE', 'UPDATE']), -1 * slot_capacity, 0) END AS baseline_slot_delta, FROM `region-us.INFORMATION_SCHEMA.RESERVATION_CHANGES` WHERE edition = edition_to_check AND change_timestamp <= end_time ), -- Convert the above to running total /* +---------------------+-------------------------+----------------+ | change_timestamp | autoscale_current_slots | baseline_slots | +---------------------+-------------------------+----------------+ | 2023-07-27 22:24:15 | 0 | 300 | | 2023-07-27 22:25:21 | 180 | 300 | | 2023-07-27 22:39:14 | 100 | 300 | | 2023-07-27 22:40:20 | 100 | 600 | | 2023-07-27 22:54:18 | 220 | 600 | | 2023-07-27 22:55:23 | 120 | 600 | */ running_reservation_slot_data AS ( SELECT change_timestamp, SUM(autoscale_current_slot_delta) OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS autoscale_current_slots, SUM(baseline_slot_delta) OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS baseline_slots, FROM reservation_slot_data ), /* The committed_slots change history. For example: +---------------------+------------------------+------------------+ | change_timestamp | capacity_commitment_id | slot_count_delta | +---------------------+------------------------+------------------+ | 2023-07-20 19:30:27 | 12954109101902401697 | 100 | | 2023-07-27 22:29:21 | 11445583810276646822 | 100 | | 2023-07-27 23:10:06 | 7341455530498381779 | 100 | */ capacity_commitment_slot_data AS ( SELECT change_timestamp, capacity_commitment_id, CASE WHEN action = "CREATE" OR action = "UPDATE" THEN IFNULL( IF( LAG(action) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC ) IN UNNEST(['CREATE', 'UPDATE']), slot_count - LAG(slot_count) OVER ( PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC ), slot_count), slot_count) ELSE IF( LAG(action) OVER (PARTITION BY capacity_commitment_id ORDER BY change_timestamp ASC, action ASC) IN UNNEST(['CREATE', 'UPDATE']), -1 * slot_count, 0) END AS slot_count_delta FROM `region-us.INFORMATION_SCHEMA.CAPACITY_COMMITMENT_CHANGES_BY_PROJECT` WHERE state = "ACTIVE" AND edition = edition_to_check AND change_timestamp <= end_time ), /* The total_committed_slots history. For example: +---------------------+---------------+ | change_timestamp | capacity_slot | +---------------------+---------------+ | 2023-07-20 19:30:27 | 100 | | 2023-07-27 22:29:21 | 200 | | 2023-07-27 23:10:06 | 300 | */ running_capacity_commitment_slot_data AS ( SELECT change_timestamp, SUM(slot_count_delta) OVER (ORDER BY change_timestamp RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS capacity_slot FROM capacity_commitment_slot_data ), /* Add next_change_timestamp to the above data, which will be used when joining with reservation data. For example: +---------------------+-----------------------+---------------+ | change_timestamp | next_change_timestamp | capacity_slot | +---------------------+-----------------------+---------------+ | 2023-07-20 19:30:27 | 2023-07-27 22:29:21 | 100 | | 2023-07-27 22:29:21 | 2023-07-27 23:10:06 | 200 | | 2023-07-27 23:10:06 | 2023-07-31 00:14:37 | 300 | */ running_capacity_commitment_slot_data_with_next_change AS ( SELECT change_timestamp, IFNULL(LEAD(change_timestamp) OVER (ORDER BY change_timestamp ASC), CURRENT_TIMESTAMP()) AS next_change_timestamp, capacity_slot FROM running_capacity_commitment_slot_data ), /* Whenever we have a change in reservations or commitments, the scaled_slots_and_baseline_not_covered_by_commitments will be changed. Hence we get a collection of all the change_timestamp from both tables. +---------------------+ | change_timestamp | +---------------------+ | 2023-07-20 19:30:27 | | 2023-07-27 22:24:15 | | 2023-07-27 22:25:21 | | 2023-07-27 22:29:21 | | 2023-07-27 22:39:14 | | 2023-07-27 22:40:20 | | 2023-07-27 22:54:18 | | 2023-07-27 22:55:23 | | 2023-07-27 23:10:06 | */ merged_timestamp AS ( SELECT change_timestamp FROM running_reservation_slot_data UNION DISTINCT SELECT change_timestamp FROM running_capacity_commitment_slot_data ), /* Change running reservation-slots and make sure we have one row when commitment changes. +---------------------+-------------------------+----------------+ | change_timestamp | autoscale_current_slots | baseline_slots | +---------------------+-------------------------+----------------+ | 2023-07-20 19:30:27 | 0 | 0 | | 2023-07-27 22:24:15 | 0 | 300 | | 2023-07-27 22:25:21 | 180 | 300 | | 2023-07-27 22:29:21 | 180 | 300 | | 2023-07-27 22:39:14 | 100 | 300 | | 2023-07-27 22:40:20 | 100 | 600 | | 2023-07-27 22:54:18 | 220 | 600 | | 2023-07-27 22:55:23 | 120 | 600 | | 2023-07-27 23:10:06 | 120 | 600 | */ running_reservation_slot_data_with_merged_timestamp AS ( SELECT change_timestamp, IFNULL( autoscale_current_slots, IFNULL( LAST_VALUE(autoscale_current_slots IGNORE NULLS) OVER (ORDER BY change_timestamp ASC), 0)) AS autoscale_current_slots, IFNULL( baseline_slots, IFNULL(LAST_VALUE(baseline_slots IGNORE NULLS) OVER (ORDER BY change_timestamp ASC), 0)) AS baseline_slots FROM running_reservation_slot_data RIGHT JOIN merged_timestamp USING (change_timestamp) ), /* Join the above, so that we will know the number for baseline not covered by commitments. +---------------------+-----------------------+-------------------------+------------------------------------+ | change_timestamp | next_change_timestamp | autoscale_current_slots | baseline_not_covered_by_commitment | +---------------------+-----------------------+-------------------------+------------------------------------+ | 2023-07-20 19:30:27 | 2023-07-27 22:24:15 | 0 | 0 | | 2023-07-27 22:24:15 | 2023-07-27 22:25:21 | 0 | 200 | | 2023-07-27 22:25:21 | 2023-07-27 22:29:21 | 180 | 200 | | 2023-07-27 22:29:21 | 2023-07-27 22:39:14 | 180 | 100 | | 2023-07-27 22:39:14 | 2023-07-27 22:40:20 | 100 | 100 | | 2023-07-27 22:40:20 | 2023-07-27 22:54:18 | 100 | 400 | | 2023-07-27 22:54:18 | 2023-07-27 22:55:23 | 220 | 400 | | 2023-07-27 22:55:23 | 2023-07-27 23:10:06 | 120 | 400 | | 2023-07-27 23:10:06 | 2023-07-31 00:16:07 | 120 | 300 | */ scaled_slots_and_baseline_not_covered_by_commitments AS ( SELECT r.change_timestamp, IFNULL(LEAD(r.change_timestamp) OVER (ORDER BY r.change_timestamp ASC), CURRENT_TIMESTAMP()) AS next_change_timestamp, r.autoscale_current_slots, IF( r.baseline_slots - IFNULL(c.capacity_slot, 0) > 0, r.baseline_slots - IFNULL(c.capacity_slot, 0), 0) AS baseline_not_covered_by_commitment FROM running_reservation_slot_data_with_merged_timestamp r LEFT JOIN running_capacity_commitment_slot_data_with_next_change c ON r.change_timestamp >= c.change_timestamp AND r.change_timestamp < c.next_change_timestamp ), /* The slot_seconds between each changes. For example: +---------------------+--------------------+ | change_timestamp | slot_seconds | +---------------------+--------------+ | 2023-07-20 19:30:27 | 0 | | 2023-07-27 22:24:15 | 13400 | | 2023-07-27 22:25:21 | 91580 | | 2023-07-27 22:29:21 | 166320 | | 2023-07-27 22:39:14 | 13200 | | 2023-07-27 22:40:20 | 419500 | | 2023-07-27 22:54:18 | 40920 | | 2023-07-27 22:55:23 | 459160 | | 2023-07-27 23:10:06 | 11841480 | */ slot_seconds_data AS ( SELECT change_timestamp, GetSlotSecondsBetweenChanges( autoscale_current_slots + baseline_not_covered_by_commitment, UNIX_MILLIS(change_timestamp), UNIX_MILLIS(next_change_timestamp), UNIX_MILLIS(start_time), UNIX_MILLIS(end_time)) AS slot_seconds FROM scaled_slots_and_baseline_not_covered_by_commitments WHERE change_timestamp <= end_time AND next_change_timestamp > start_time ) /* Final result for this example: +--------------------+ | total_slot_seconds | +--------------------+ | 13045560 | */ SELECT SUM(slot_seconds) AS total_slot_seconds FROM slot_seconds_data
פתרון בעיות
בקטע הזה מוסבר איך לפתור בעיות נפוצות כשעוקבים אחרי הזמנות של BigQuery ושימוש במשבצות.
מדדי השימוש במשבצות לא תואמים INFORMATION_SCHEMA
אם יש הבדלים בין מדדי השימוש במשבצות בתרשימי המשאבים לבין הנתונים ב-INFORMATION_SCHEMA, נסו את הפעולות הבאות:
- צמצום רמת הפירוט. שינוי רמת הפירוט של התרשים למרווחים של שנייה אחת במקום מרווחים של שעה אחת.
- יישור הצבירה. חשוב לוודא שאתם משתמשים בשיטות צבירה שתואמות בין תרשימי המשאבים לבין נתוני
INFORMATION_SCHEMA. לדוגמה, כדי לשקף בצורה טובה יותר את השימוש בשיא בתרשימי משאבים, צריך לשנות את צבירת המדדים ל-p99 או ל-p90 באופן עקבי.
משבצות מושאלות מופיעות כשהמשבצות הפנויות מושבתות
יכול להיות שבתרשימי המעקב יוצג ערך שאינו אפס במאפיין borrowed_slots גם אם המאפיין ignore_idle_slots=true מוגדר להזמנה אחת או יותר. ההגדרה הזו מונעת מהזמנה לשאול משבצות פנויות, אבל היא לא מונעת ממנה להשאיל משבצות לא בשימוש להזמנות אחרות.
משבצות מושאלות מופיעות במקרים הבאים:
השאלה למקומות שמורים אחרים: מקום שמור עם הערך
ignore_idle_slots=trueיכול להשאיל את יחידות הקיבולת הבסיסיות הלא מנוצלות שלו למקומות שמורים אחרים באותה מהדורה שכן מאפשרות השאלה של יחידות קיבולת בלי פעילות (ignore_idle_slots=false). אם כל המקומות השמורים במהדורה מסוימת הם עם הערךignore_idle_slots=true, יחידות הקיבולת בלי פעילות לא משותפות ביניהן.לדוגמה, נניח שהזמנה א' כוללת 100 משבצות, לא נעשה בה שימוש והיא מוגדרת עם
ignore_idle_slots=true. הזמנה B היא באותו מהדורה ובאותו פרויקט, יש בה 100 משבצות, היא צריכה 150 משבצות לעומס העבודה שלה והיא מוגדרת עםignore_idle_slots=false. הזמנה ב' יכולה לשאול 50 משבצות זמן פנויות מהזמנה א' כדי לענות על הצרכים שלה. במקרה כזה, בתרשימי המעקב יופיעו 50lent_slotsל-Reservation A ו-50borrowed_slotsל-Reservation B.השימוש חורג מהקיבולת: אם השימוש במשבצות בהזמנה חורג באופן זמני מהקיבולת שלה (בסיס + משבצות שנוספו באמצעות שינוי גודל אוטומטי), ההפרש הזה מוצג בתרשימי המעקב כ-
borrowed_slots. זה יכול לקרות גם בהזמנות עםignore_idle_slots=true.
לפעמים השימוש במשבצות יכול לחרוג מהסכום של משבצות הבסיס והמשבצות המותאמות. לא תחויבו על שימוש במשבצות שגדול יותר ממכסת הבסיס בתוספת המשבצות המותאמות.
משבצות מושאלות מופיעות לפני שהניצול של ההזמנה הושלם
לוחות הבקרה של המעקב מתבססים על נתונים מדוגמים, ולכן יכול להיות שהם לא ישקפו בצורה מדויקת את התזמון המדויק של השימוש במשבצת במהלך מרווח הדגימה.
כדי לקבל ניתוח מדויק יותר של השימוש ביחידות קיבולת (Slot), אפשר לשלוח שאילתה לעמודות שקשורות ליחידות קיבולת (Slot) בלי פעילות, כמו העמודות borrowed_slots ו-lent_slots בתצוגה INFORMATION_SCHEMA.RESERVATIONS_TIMELINE.