הרצת אלגוריתמים של Spanner Graph

במאמר הזה מוסבר איך להריץ אלגוריתמים ב-Spanner Graph.

מבנה של שאילתת אלגוריתם ב-Spanner Graph

שאילתת אלגוריתם של Spanner Graph כוללת את המבנה הבא:

EXPORT DATA OPTIONS (<export_option_list>) AS
GRAPH graph_name
<match_clause>
<call_statement> algorithm_name(<common_input>, <algorithm_specific_input>)
  YIELD <algorithm_specific_output>
RETURN <results>

השאילתה מורכבת מהצהרת EXPORT DATA, שמגדירה איך לשמור את התוצאות, וממשפט GRAPH שמפיק את תוצאת שאילתת האלגוריתם.

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

אופציונלית, אפשר להשתמש בפסוקית graph בהצהרות MATCH נתמכות כדי לבחור רכיבים שמעניינים אתכם. במקרה כזה, משתמשים בסעיף PER () כדי לקבץ את כל השורות שמוחזרות על ידי MATCH כקלט לאלגוריתם. האלגוריתם פועל על תת-גרף לוגי שמורכב מהקבוצה הייחודית של הצמתים והקשתות שנבחרו.

השאילתה לא מחזירה נתונים. התוצאות נשמרות בהתאם ל-export_option_list.

מידע נוסף על שאילתות של אלגוריתם גרף ב-Spanner זמין בקטעים הבאים במאמר הזה:

פרמטרים נפוצים של קלט לאלגוריתמים

מציינים את פרמטרי הקלט עם השמות בפורמט הבא: NAME => VALUE, ....

שם סוג הערך חובה ערך ברירת המחדל תיאור
node_labels ARRAY לא (ללא) נתמך רק כשמשתמשים ב-CALL. רשימה של תוויות צמתים שייכללו בקלט של האלגוריתם. אם מציינים תווית, נכללים רק צמתים עם תווית אחת לפחות שתואמת לתווית שצוינה.
edge_labels ARRAY לא (ללא) נתמך רק כשמשתמשים ב-CALL. רשימה של תוויות קצה שייכללו בקלט של האלגוריתם. אם מציינים תווית, רק קצוות עם תווית אחת לפחות שתואמת לתווית שצוינה ייכללו.
edge_weight_property STRING לא (ללא) השם של מאפיין הקצה שמכיל את המשקלים. אם לא מוגדר משקל, המערכת מקצה משקל ברירת מחדל של 1 לכל הקצוות. סוג ערך המאפיין חייב להיות מספרי.
machine_category STRING לא ברירת מחדל קטגוריית המכונה שבה יש להשתמש להרצת האלגוריתם. הערכים הנתמכים הם: default, ‏ large
zone STRING לא (ללא) האזור שבו מתבצעת ההרצה של האלגוריתם. חייב להיות אחד מהאזורים באזור שבו מתקבלת השאילתה.
max_idle_time STRING לא ‫30 דקות המדיניות מציינת כמה זמן מופע החישוב צריך להישאר פעיל לשימוש חוזר אחרי שהאלגוריתם מסתיים. הפורמט הוא רצף של מספרים עשרוניים, שלכל אחד מהם יש סיומת של יחידה, כמו 4m, 1.5h או 1h45m. יחידות זמן תקינות: ns,‏ us (או µs), ‏ ms, ‏ s,‏ m, ‏ h.

טיפול בפלט של אלגוריתם

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

שמירת התוצאות ב-Cloud Storage

כדי להשתמש באפשרות הזו, צריך לוודא שהתפקיד אדמין של אובייקט אחסון (roles/storage.objectAdmin) הוקצה לחשבון השירות של Spanner service-PROJECT_NUMBER@gcp-sa-spanner.iam.gserviceaccount.com שמנוהל על ידי Google.

אלה האפשרויות של EXPORT DATA שנתמכות כששומרים תוצאות ב-Cloud Storage. מציינים את האפשרויות בתבנית הבאה: NAME=VALUE, ....

שם סוג הערך חובה תיאור
uri STRING כן ה-URI של היעד לייצוא, בפורמט gs://bucket/path/file. אם מייצאים כמות גדולה של נתונים, אפשר להשתמש בתו כללי ב-uri כדי לייצא נתונים לכמה קבצים. לדוגמה, gs://bucket/path/file_*.csv.
format STRING כן הפורמט של הנתונים המיוצאים. ערכים נתמכים: CSV, ‏ PARQUET, ‏ AVRO.
header BOOL לא אם בוחרים באפשרות true, המערכת מדפיסה את כותרות העמודות בשורה הראשונה של כל קובץ נתונים. ערך ברירת המחדל הוא false. המאפיין הזה רלוונטי רק לקובצי CSV.
overwrite BOOL לא אם true, המערכת דורסת קבצים קיימים עם אותו URI. אחרת, אם קיימים קבצים עם אותו URI, יוחזר ערך שגיאה. ערך ברירת המחדל הוא false.
field_delimiter STRING לא התו המפריד בין השדות. ברירת מחדל: , (פסיק). המאפיין הזה רלוונטי רק לקובצי CSV.
compression STRING לא מציינים את פורמט הדחיסה. אם לא מציינים פורמט דחיסה, הקבצים לא נדחסים.
  • הערך הנתמך של CSV הוא GZIP.
  • הערכים הנתמכים של PARQUET הם: SNAPPY,‏ GZIP,‏ ZSTD.
  • הערכים הנתמכים של AVRO הם: DEFLATE,‏ SNAPPY.

שמות העמודות בסעיף RETURN מגדירים את שמות העמודות בקובצי הפלט של Cloud Storage.

ייצוא נתונים לקובץ אחד או יותר

שאילתות של Spanner Graph תומכות באופרטור תו כללי לחיפוש יחיד (*) ב-uri. תו כללי יכול להופיע ברכיב של שם הקובץ, אבל לא בשם של קטגוריה, שם של תיקייה או סיומת של קובץ. אם קבוצת התוצאות גדולה, שימוש באופרטור התו הכללי יורה ל-Spanner Graph ליצור כמה קבצים מפולחים על סמך התבנית שסיפקתם. המערכת מחליפה את האופרטור של התו הכללי במספר, החל מאפס, עם ריפוד משמאל ל-12 ספרות. לדוגמה, ה-URI‏ gs://my-bucket/file-*.csv יוצר קבצים כמו gs://my-bucket/file-000000000000.csv,‏ gs://my-bucket/file-000000000001.csv וקבצים דומים.

אם משתמשים בפונקציה uri בלי תו כללי, התוצאה היא קובץ יחיד, כמו gs://my-bucket/file.csv.

סוגי הנתונים

כשמייצאים נתונים, סוגי הנתונים של גרף Spanner מומרים באופן הבא, בהתאם לפורמט:

CSV

כל סוגי הנתונים מומרים לייצוג המחרוזת שלהם:

  • הערכים BOOL מומרים ל-true או ל-false.
  • ערכי BYTES מקודדים ב-Base64.
  • פורמט הערכים TIMESTAMP של YYYY-MM-DD HH:MM:SS.ffffff UTC.
  • הערכים של NULL מופיעים כמחרוזות ריקות.

אי אפשר לייצא נתונים מקוננים וחוזרים בפורמט CSV.

Avro

סוג הנתונים ב-Spanner סוג הנתונים Avro
BOOL BOOLEAN
INT64 LONG
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC BYTES עם סוג לוגי DECIMAL(38,9)
STRING STRING
BYTES BYTES
TIMESTAMP LONG (מיקרו-שניות מאז תחילת התקופה של זמן מערכת)
NULL null

Parquet

סוג הנתונים ב-Spanner סוג הנתונים ב-Parquet
BOOL BOOLEAN
INT64 INT64
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC DECIMAL(38,9)
STRING STRING
BYTES BYTE_ARRAY
TIMESTAMP TIMESTAMP_MICROS
NULL null

שמירת התוצאות ב-Spanner

אלה האפשרויות של EXPORT DATA שנתמכות כשמעבירים את התוצאות בחזרה למופע המקור של Spanner. מציינים את האפשרויות בפורמט הבא: NAME=VALUE, ....

שם סוג הערך חובה תיאור
format STRING כן הפורמט של הנתונים המיוצאים. חייב להיות CLOUD_SPANNER.
table STRING כן השם של טבלת היעד ב-Spanner שאליה ייכתבו התוצאות. יכולה להיות כל טבלה במופע Spanner.
write_mode STRING כן מצב הכתיבה שבו רוצים להשתמש. ערכים נתמכים:
  • update_ignore_all: עדכון של שורות קיימות בטבלת היעד.
  • upsert_ignore_all: הוספה של שורות חדשות או עדכון של שורות קיימות בטבלת היעד.

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

דרישות

כששומרים את תוצאות האלגוריתם בחזרה ב-Spanner, שאילתת האלגוריתם צריכה לעמוד בדרישות הבאות:

  • טבלת היעד חייבת להתקיים.
  • צריכות להיות עמודות עם סוג תואם: כל שמות העמודות שצוינו בסעיף RETURN צריכים כבר להיות קיימים בטבלת היעד עם סוג נתונים תואם. אם צריך, משתמשים בשמות חלופיים כדי להתאים את שמות העמודות בטבלת היעד. דוגמה: RETURN node.id AS person_id.
  • הכללה של כל העמודות של המפתח הראשי: סעיף RETURN חייב לכלול את כל העמודות של המפתח הראשי בטבלת היעד.

כתיבה של נתוני סמנטיקה

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

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

המערכת כותבת את תוצאות האלגוריתם בחזרה ל-Spanner Graph באמצעות MEDIUM priority.

הרצת שאילתות אלגוריתם לדוגמה

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

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

כדי להריץ את השאילתות לדוגמה של אלגוריתם Spanner Graph, צריך קודם לבצע את הפעולות הבאות:

  1. כדי ליצור Spanner Graph, פועלים לפי ההוראות במאמר הגדרה של Spanner Graph והפעלת שאילתות.
  2. ודאו שיש לכם את ההרשאות הנדרשות.
  3. אופציונלי: אם אתם שומרים את הפלט ב-Spanner, אתם יכולים להוסיף לסכימת Spanner Graph.

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

-- Add `page_rank` as a column. Data type of this column matches the data type defined in `PageRank` output signature.
ALTER TABLE Account ADD COLUMN page_rank FLOAT64;

-- Rerun the graph definition DDL to pickup `page_rank` as a new property.
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (`Account`, `Person`)
  EDGE TABLES (
    `PersonOwnAccount`
      SOURCE KEY (id) REFERENCES `Person` (id)
      DESTINATION KEY (account_id) REFERENCES `Account` (id)
      LABEL `Owns`,
    `AccountTransferAccount`
      SOURCE KEY (id) REFERENCES `Account` (id)
      DESTINATION KEY (to_id) REFERENCES `Account` (id)
      LABEL `Transfers`
  );

הפעלת אלגוריתם בגרף מלא עם מסנן תוויות ושמירת התוצאות ב-Cloud Storage

בדוגמה הזו מריצים את הפקודה PageRank כדי לדרג את Account על סמך Transactions שהם משתתפים בהם, ושומרים את התוצאות ב-Cloud Storage בפורמט CSV בשם my-bucket-name/my-output.csv.

EXPORT DATA OPTIONS (
  uri = "gs://my-bucket-name/my-output.csv",
  format = "csv"
) AS
GRAPH FinGraph
CALL PageRank(node_labels => ['Account'], edge_labels => ['Transfers']) YIELD node, score
RETURN node.id, score AS page_rank

ב-Cloud Storage, אחרי שהשאילתה הזו מסתיימת בהצלחה, אמור להופיע קובץ CSV עם שתי עמודות (id ו-page_rank).

הפעלת אלגוריתם על תת-גרף שמוגדר על ידי MATCH ושמירת התוצאות בגרף

בדוגמה הזו נעשה שימוש בתבנית MATCH כדי להתאים באופן דינמי תת-גרף לוגי שמכיל את כל הצמתים Account ורק קשתות Transfer עם סכום שקטן מ-500. הגרף המשני הלוגי הזה הוא הקלט לאלגוריתם PageRank. ‫Spanner שומר את תוצאות האלגוריתם בחזרה בטבלה Account.

EXPORT DATA OPTIONS (
  format = "CLOUD_SPANNER",
  table = "Account",
  write_mode = 'update_ignore_all'
) AS
GRAPH FinGraph
MATCH (n:Account)
RETURN n
FULL UNION ALL
MATCH -[e:Transfers WHERE e.amount < 500]->
RETURN e
NEXT
CALL PER () PageRank() YIELD node, score
RETURN node.id, score AS page_rank

אחרי שהשאילתה מסתיימת בהצלחה, מריצים את השאילתה הבאה:

GRAPH FinGraph
MATCH (n:Account)
RETURN n.id, ROUND(n.page_rank, 2) AS page_rank
ORDER BY page_rank DESC, id ASC

אתם אמורים לראות תוצאות דומות לאלה:

id page_rank
20 0.49
16 0.46
7 0.05

בדיקת סטטוס ההפעלה של האלגוריתם

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

GRAPH_OPERATION_EXECUTION_STATUS סכימה

שם עמודה סוג תיאור
QUERY_ID STRING המזהה של שאילתת אלגוריתם הגרף.
QUERY_TEXT STRING הטקסט של הצהרת השאילתה.
START_TIMESTAMP TIMESTAMP השעה שבה התחיל הביצוע של השאילתה.
LAST_UPDATE_TIMESTAMP TIMESTAMP השעה שבה הסטטוס עודכן לאחרונה.
PROGRESS FLOAT אחוז משוער של השלמת הצפייה. הערך הוא בין 0 ל-1, כאשר 0 מייצג התחלה ו-1 מייצג סיום.
STATUS STRING המצב הנוכחי של הביצוע. הערכים האפשריים הם PENDING, ‏ IN_PROGRESS, ‏ OK, ‏ CANCELLED, ‏ DEADLINE_EXCEEDED, ‏ UNKNOWN.
ERROR_MESSAGE STRING הודעת שגיאה אם ביצוע השאילתה נכשל.

השאילתה לדוגמה הבאה מציגה רשימה של שאילתות גרף שעדיין לא הושלמו בהצלחה:

SELECT
  query_id,
  query_text,
  start_timestamp,
  last_update_timestamp,
  progress,
  status,
  error_message
FROM
  SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS
WHERE
  status != "OK"
ORDER BY
  start_timestamp DESC;

ביטול ההרצה של האלגוריתם

כדי לבטל שאילתת אלגוריתם של תרשים שנמצאת בתהליך, מאתרים את query_id בטבלה SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS, ואז קוראים ל-cancel_query עבור אותו query_id.

המאמרים הבאים