במאמר הזה מוסבר איך להשתמש בצינורות של חילוץ, טרנספורמציה וטעינה (ETL) הפוכים כדי להעביר נתונים של גרפים מ-BigQuery ל-Spanner Graph ולסנכרן אותם באופן רציף. הוא כולל את ההיבטים העיקריים הבאים:
- תרחישים נפוצים לדוגמה לשימוש ב-ETL הפוך עם נתונים גרפיים.
- השלבים שנדרשים בצינור reverse ETL.
- אסטרטגיות לניהול שינויים בנתוני הגרף, כולל הוספות, עדכונים ומחיקות.
- שיטות לניהול ולתחזוקה של צינורות ETL הפוך
- שיטות מומלצות לאופטימיזציה של תהליך ה-ETL ההפוך
כדי להשתמש ב-Reverse ETL לייצוא נתונים מ-BigQuery ל-Spanner, אפשר לעיין במאמר ייצוא נתונים ל-Spanner.
BigQuery מבצע מניפולציות מורכבות של נתונים בקנה מידה גדול כפלטפורמת עיבוד אנליטי, בעוד ש-Spanner מותאם לתרחישי שימוש שדורשים QPS גבוה וחביון נמוך של הצגת נתונים. Spanner Graph ו-BigQuery משתלבים בצורה יעילה כדי להכין נתוני גרפים בצינורות ניתוח נתונים של BigQuery, וכך מאפשרים ל-Spanner להציג מעברים בגרפים עם השהיה נמוכה.
לפני שמתחילים
יוצרים מופע Spanner עם מסד נתונים שמכיל נתוני גרף. מידע נוסף זמין במאמר הגדרה של Spanner Graph ושליחת שאילתות.
ב-BigQuery, יוצרים מקום שמור (slot) ברמה Enterprise או Enterprise Plus. כדי להפחית את עלויות החישוב ב-BigQuery, אפשר להריץ ייצוא ל-Spanner Graph. כדי לעשות זאת, מגדירים קיבולת בסיסית של אפס משבצות ומפעילים את התאמה אוטומטית לעומס.
הקצאת תפקידים בניהול הזהויות והרשאות הגישה (IAM) שנותנים למשתמשים את ההרשאות הנדרשות לביצוע כל משימה שמופיעה במאמר הזה.
התפקידים הנדרשים
כדי לקבל את ההרשאות שנדרשות לייצוא נתוני גרף של BigQuery אל Spanner Graph, צריך לבקש מהאדמין להקצות לכם בפרויקט את תפקידי ה-IAM הבאים:
-
ייצוא נתונים מטבלה ב-BigQuery:
BigQuery Data Viewer (
roles/bigquery.dataViewer) -
מריצים משימת ייצוא:
BigQuery User (
roles/bigquery.user) -
הצגת הפרמטרים של מכונת Spanner:
Cloud Spanner Viewer (
roles/spanner.viewer) -
כתיבת נתונים לטבלה של Spanner Graph:
Cloud Spanner Database User (
roles/spanner.databaseUser)
להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
תרחישים לדוגמה לשימוש ב-Reverse ETL
הנה כמה תרחישים לדוגמה. אחרי שמנתחים ומעבדים נתונים ב-BigQuery, אפשר להעביר את הנתונים ל-Spanner Graph באמצעות ETL הפוך.
צבירה וסיכום של נתונים – אפשר להשתמש ב-BigQuery כדי לחשב צבירות של נתונים מפורטים, וכך להתאים אותם יותר לתרחישי שימוש תפעוליים.
טרנספורמציה של נתונים והעשרה שלהם – אפשר להשתמש ב-BigQuery כדי לנקות ולתקנן נתונים שמתקבלים ממקורות נתונים שונים.
סינון ובחירה של נתונים – אפשר להשתמש ב-BigQuery כדי לסנן מערך נתונים גדול למטרות ניתוח. לדוגמה, אפשר לסנן נתונים שלא נדרשים לאפליקציות בזמן אמת.
עיבוד מקדים של פיצ'רים והנדסת פיצ'רים – ב-BigQuery, משתמשים בפונקציה ML.TRANSFORM כדי לבצע טרנספורמציה של נתונים, או בפונקציה ML.FEATURE_CROSS כדי ליצור שילובי פיצ'רים של פיצ'רים של קלט. לאחר מכן, משתמשים ב-ETL הפוך כדי להעביר את הנתונים שמתקבלים אל Spanner Graph.
הסבר על צינור ה-ETL ההפוך
הנתונים עוברים מ-BigQuery ל-Spanner Graph בצינור ETL הפוך בשני שלבים:
BigQuery משתמש במשבצות זמן שהוקצו למשימת צינור הנתונים כדי לחלץ ולשנות את נתוני המקור.
צינור ה-ETL ההפוך של BigQuery משתמש בממשקי API של Spanner כדי לטעון נתונים למופע Spanner שהוקצה.
בתרשים הבא מוצגים השלבים בצינור עיבוד נתונים של ETL הפוך:
איור 1. תהליך צינור ה-ETL ההפוך ב-BigQuery
ניהול שינויים בנתוני הגרף
אפשר להשתמש ב-ETL הפוך כדי:
טעינת מערך נתונים של גרף מ-BigQuery ל-Spanner Graph.
סנכרון נתונים מגרף Spanner עם עדכונים שוטפים ממערך נתונים ב-BigQuery.
מגדירים צינור ETL הפוך עם שאילתת SQL כדי לציין את נתוני המקור ואת השינוי שרוצים להחיל. תהליך הצינור טוען את כל הנתונים שעומדים בתנאי של סעיף WHERE בהצהרת SELECT ל-Spanner באמצעות פעולת upsert. פעולת upsert שוות ערך להצהרות INSERT OR UPDATE. הוא מוסיף שורות חדשות ומעדכן שורות קיימות בטבלאות שמאחסנות נתוני גרף. הצינור מתבסס על מפתח ראשי של טבלת Spanner כדי ליצור שורות חדשות ולעדכן שורות קיימות.
הוספה ועדכון של נתונים בטבלאות עם יחסי תלות בסדר הטעינה
השיטות המומלצות לעיצוב סכימת Spanner Graph כוללות שימוש בטבלאות משולבות ובמפתחות זרים. אם אתם משתמשים בטבלאות משולבות או במפתחות זרים מאולצים, אתם צריכים לטעון את נתוני הצמתים והקשתות בסדר מסוים. כך מוודאים שהשורות שאליהן מתייחסים קיימות לפני שיוצרים את השורה שמתייחסת אליהן. מידע נוסף זמין במאמר בנושא יצירת טבלאות משולבות.
סכימת טבלת הקלט של הגרף בדוגמה הבאה משתמשת בטבלה משולבת ובאילוץ של מפתח זר כדי ליצור מודל של הקשר בין אדם לבין החשבונות שלו:
CREATE TABLE Person (
id INT64 NOT NULL,
name STRING(MAX)
) PRIMARY KEY (id);
CREATE TABLE Account (
id INT64 NOT NULL,
create_time TIMESTAMP,
is_blocked BOOL,
type STRING(MAX)
) PRIMARY KEY (id);
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id)
) PRIMARY KEY (id, account_id),
INTERLEAVE IN PARENT Person ON DELETE CASCADE;
CREATE PROPERTY GRAPH FinGraph
NODE TABLES (
Person,
Account
)
EDGE TABLES (
PersonOwnAccount
SOURCE KEY (id) REFERENCES Person
DESTINATION KEY (account_id) REFERENCES Account
LABEL Owns
);
בסכימה הזו לדוגמה, PersonOwnAccount היא טבלה משולבת ב-Person.
טוענים את הרכיבים בטבלה Person לפני הרכיבים בטבלה PersonOwnAccount. בנוסף, אילוץ המפתח הזר ב-PersonOwnAccount מבטיח שקיים שורה תואמת ב-Account, היעד של קשר הקצה. לכן, צריך לטעון את הטבלה Account לפני הטבלה PersonOwnAccount. הרשימה הבאה מסכמת את התלות בסדר הטעינה של הסכימה הזו:
כדי לטעון את הנתונים:
- טעינה של
PersonלפניPersonOwnAccount. - טעינה של
AccountלפניPersonOwnAccount.
Spanner אוכף את אילוצי השלמות ההפנייתית בסכימה לדוגמה. אם צינור הנתונים מנסה ליצור שורה בטבלה PersonOwnAccount בלי שורה תואמת בטבלה Person או בטבלה Account, Spanner מחזיר שגיאה. לאחר מכן, הפייפליין נכשל.
בצינור הזה של ETL הפוך נעשה שימוש בהצהרות EXPORTDATA ב-BigQuery כדי לייצא נתונים מהטבלאות Person, Account ו-PersonOwnAccount במערך נתונים, כדי לעמוד בתלות של סדר הטעינה:
BEGIN
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "Person",
"priority": "HIGH",
"tag" : "graph_data_load_person"
}"""
) AS
SELECT
id,
name
FROM
DATASET_NAME.Person;
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "Account",
"priority": "HIGH",
"tag" : "graph_data_load_account"
}"""
) AS
SELECT
id,
create_time,
is_blocked,
type
FROM
DATASET_NAME.Account;
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "PersonOwnAccount",
"priority": "HIGH",
"tag" : "graph_data_load_person_own_account"
}"""
) AS
SELECT
id,
account_id,
create_time
FROM
DATASET_NAME.PersonOwnAccount;
END;
סנכרון נתונים
כדי לסנכרן את BigQuery עם Spanner Graph, משתמשים בצינורות reverse ETL. אתם יכולים להגדיר צינור להעברת נתונים כך שיבצע אחת מהפעולות הבאות:
החלת כל ההוספות והעדכונים ממקור BigQuery על טבלת היעד של Spanner Graph. אפשר להוסיף רכיבי סכימה לטבלאות היעד כדי להעביר באופן לוגי את המידע על המחיקות, ולהסיר שורות מטבלאות היעד לפי לוח זמנים.
משתמשים בפונקציית סדרת זמן שמבצעת פעולות הוספה ועדכון ומזהה פעולות מחיקה.
אילוצים של מהימנות רפרנציאלית
בניגוד ל-Spanner, BigQuery לא אוכף אילוצים של מפתחות ראשיים ומפתחות זרים. אם הנתונים ב-BigQuery לא עומדים במגבלות שאתם יוצרים בטבלאות Spanner, יכול להיות שצינור ה-ETL ההפוך ייכשל בזמן טעינת הנתונים האלה.
תהליך ה-Reverse ETL מקבץ אוטומטית את הנתונים למנות שלא חורגות מהמגבלה המקסימלית של שינויים לכל פעולת Commit, ומחיל את המנות על טבלת Spanner בסדר שרירותי. אם אצווה מכילה נתונים שנכשלים בבדיקת שלמות רפרנציאלית, Spanner לא טוען את האצווה הזו. דוגמאות לכשלים כאלה כוללות שורת צאצאים משולבת שחסרה לה שורת הורה, או עמודת מפתח זר שנאכפת ללא ערך תואם בעמודה שאליה היא מפנה. אם אצווה נכשלת בבדיקה, הצינור נכשל עם שגיאה, והצינור מפסיק לטעון אצוות.
הסבר על שגיאות של אילוץ תקינות רפרנציאלית
בדוגמאות הבאות מוצגות שגיאות של אילוץ שלמות רפרנציאלית שאולי תיתקלו בהן:
פתרון שגיאות של אילוץ מפתח זר
שגיאה: "ההגבלה של המפתח הזר
FK_Accountהופרה בטבלהPersonOwnAccount. לא ניתן למצוא ערכים שמופנים אליהם ב-Account(id)"הסיבה: הוספת שורה לטבלה
PersonOwnAccountנכשלה כי חסרה שורה תואמת בטבלהAccount, שנדרשת על ידי המפתח הזרFK_Account.
פתרון שגיאות שקשורות לשורת הורה חסרה
שגיאה: "חסרה שורת האב של שורה [15,1] בטבלה
PersonOwnAccount"הסיבה: הוספת שורה ל-
PersonOwnAccount(id: 15ו-account_id: 1) נכשלה כי חסרה שורת אב בטבלהPerson(id: 15).
כדי להקטין את הסיכון לשגיאות של שלמות רפרנציאלית, כדאי לשקול את האפשרויות הבאות. לכל אפשרות יש יתרונות וחסרונות.
- כדי לאפשר ל-Spanner Graph לטעון נתונים, צריך להרחיב את האילוצים.
- מוסיפים לצינור לוגיקה להשמטת שורות שלא עומדות במגבלות של שלמות רפרנציאלית.
הסרת אילוצים של תקינות רפרנציאלית
אחת האפשרויות למניעת שגיאות של שלמות רפרנציאלית בזמן טעינת נתונים היא להקל על האילוצים, כך ש-Spanner לא יאכוף שלמות רפרנציאלית.
אתם יכולים ליצור טבלאות משולבות עם פסקה
INTERLEAVE INכדי להשתמש באותן מאפיינים של שילוב שורות פיזי. אם משתמשים ב-INTERLEAVE INבמקום ב-INTERLEAVE IN PARENT, מערכת Spanner לא אוכפת את שלמות ההפניה, אבל השאילתות נהנות ממיקום משותף של טבלאות קשורות.אפשר ליצור מפתחות זרים אינפורמטיביים באמצעות האפשרות
NOT ENFORCED. האפשרותNOT ENFORCEDמספקת יתרונות של אופטימיזציה של שאילתות. עם זאת, Spanner לא אוכף את השלמות הרפרנציאלית.
לדוגמה, כדי ליצור את טבלת הקלט של הקצה בלי בדיקות של שלמות רפרנציאלית, אפשר להשתמש ב-DDL הזה:
CREATE TABLE PersonOwnAccount (
id INT64 NOT NULL,
account_id INT64 NOT NULL,
create_time TIMESTAMP,
CONSTRAINT FK_Account FOREIGN KEY (account_id) REFERENCES Account (id) NOT ENFORCED
) PRIMARY KEY (id, account_id),
INTERLEAVE IN Person;
שמירה על תקינות הנתונים בצינורות reverse ETL
כדי לוודא שצינור הנתונים טוען רק שורות שעומדות בבדיקות שלמות ההפניה, צריך לכלול רק שורות PersonOwnAccount שיש להן שורות תואמות בטבלאות Person ו-Account. לאחר מכן, שומרים על סדר הטעינה, כך ש-Spanner טוען את השורות Person ו-Account לפני השורות PersonOwnAccount שמפנות אליהן.
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "PersonOwnAccount",
"priority": "HIGH",
"tag" : "graph_data_load_person_own_account"
}"""
) AS
SELECT
poa.id,
poa.account_id,
poa.create_time
FROM `PROJECT_ID.DATASET_NAME.PersonOwnAccount` poa
JOIN `PROJECT_ID.DATASET_NAME.Person` p ON (poa.id = p.id)
JOIN `PROJECT_ID.DATASET_NAME.Account` a ON (poa.account_id = a.id)
WHERE poa.id = p.id
AND poa.account_id = a.id;
מחיקת רכיבים בתרשים
בצינורות Reverse ETL נעשה שימוש בפעולות upsert. מכיוון שפעולות upsert שוות להצהרות INSERT OR UPDATE, צינור יכול לסנכרן רק שורות שקיימות בנתוני המקור בזמן הריצה. כלומר, הצינור לא כולל שורות שנמחקו. אם מוחקים נתונים מ-BigQuery, צינור reverse ETL לא יכול להסיר ישירות את אותם נתונים מ-Spanner Graph.
אפשר להשתמש באחת מהאפשרויות הבאות כדי לטפל במחיקות מטבלאות מקור ב-BigQuery:
ביצוע מחיקה לוגית או מחיקה עם יכולת שחזור במקור
כדי לסמן שורות למחיקה באופן לוגי, משתמשים בדגל deleted ב-BigQuery. לאחר מכן יוצרים עמודה בטבלת Spanner של היעד שאליה אפשר להעביר את הדגל. כש-ETL הפוך מחיל את העדכונים של צינור הנתונים, הוא מוחק שורות עם הדגל הזה ב-Spanner. אפשר למצוא ולמחוק שורות כאלה באופן מפורש באמצעות partitioned DML. אפשרות אחרת היא למחוק שורות באופן מרומז על ידי הגדרת עמודה של TTL (אורך חיים) עם תאריך שתלוי בעמודת דגל המחיקה. כדי להחריג את השורות שנמחקו לוגית, צריך לכתוב שאילתות Spanner. כך אפשר לוודא ש-Spanner יחריג את השורות האלה מהתוצאות לפני המחיקה המתוזמנת. אחרי שצינור ה-ETL ההפוך פועל עד הסוף, המחיקות הלוגיות משתקפות בשורות ב-Spanner. לאחר מכן תוכלו למחוק שורות מ-BigQuery.
בדוגמה הזו, עמודה is_deleted נוספת לטבלה PersonOwnAccount ב-Spanner. לאחר מכן, היא מוסיפה עמודה expired_ts_generated שתלויה בערך is_deleted. התאריך בעמודה שנוצרה מוקדם יותר מערך הסף DELETION POLICY, ולכן השורות המושפעות מתוזמנות למחיקה בהתאם למדיניות ה-TTL.
ALTER TABLE PersonOwnAccount
ADD COLUMN is_deleted BOOL DEFAULT (FALSE);
ALTER TABLE PersonOwnAccount ADD COLUMN
expired_ts_generated TIMESTAMP AS (IF(is_deleted,
TIMESTAMP("1970-01-01 00:00:00+00"),
TIMESTAMP("9999-01-01 00:00:00+00"))) STORED HIDDEN;
ALTER TABLE PersonOwnAccount
ADD ROW DELETION POLICY (OLDER_THAN(expired_ts_generated, INTERVAL 0 DAY));
שימוש בהיסטוריית השינויים ב-BigQuery לפעולות INSERT, UPDATE ומחיקות לוגיות
אפשר לעקוב אחרי שינויים בטבלה ב-BigQuery באמצעות היסטוריית השינויים שלה. אפשר להשתמש בפונקציה CHANGES של GoogleSQL כדי למצוא שורות שהשתנו במרווח זמן מסוים. לאחר מכן, משתמשים בפרטים של השורה שנמחקה עם צינור עיבוד נתונים הפוך של ETL. אפשר להגדיר את צינור העיבוד כך שיגדיר אינדיקטור, כמו דגל מחיקה או תאריך תפוגה, בטבלת Spanner. האינדיקטור הזה מסמן שורות למחיקה בטבלאות של Spanner.
משתמשים בתוצאות של פונקציית הסדרות העיתיות CHANGES כדי להחליט אילו שורות מטבלת המקור לכלול בטעינה של צינור ה-ETL ההפוך.
הצינור כולל שורות עם _CHANGE_TYPE בתור INSERT או UPDATE בתור upserts אם השורה קיימת בטבלת המקור. השורה הנוכחית מטבלת המקור מספקת את הנתונים העדכניים ביותר.
משתמשים בשורות עם _CHANGE_TYPE בתור DELETE שלא כוללות שורות קיימות בטבלת המקור כדי להגדיר אינדיקטור בטבלת Spanner, כמו דגל של מחיקה או תאריך תפוגה של שורה.
השאילתה לייצוא צריכה להתייחס לסדר של הוספות ומחיקות ב-BigQuery. לדוגמה, נניח ששורה נמחקה בזמן T1 ושורה חדשה נוספה בזמן מאוחר יותר T2. אם שניהם ממופים לאותה שורה בטבלת Spanner, הייצוא צריך לשמור את ההשפעות של האירועים האלה בסדר המקורי שלהם.
אם ההגדרה מופעלת, האינדיקטור delete מסמן שורות למחיקה בטבלאות של Spanner.
לדוגמה, אפשר להוסיף עמודה לטבלת קלט של Spanner כדי לאחסן את תאריך התפוגה של כל שורה. לאחר מכן יוצרים המדיניות בנושא מחיקת נתונים שמשתמשת בתאריכי התפוגה האלה.
בדוגמה הבאה אפשר לראות איך מוסיפים עמודה לאחסון תאריכי התפוגה של השורות בטבלה.
ALTER TABLE PersonOwnAccount ADD COLUMN expired_ts TIMESTAMP;
ALTER TABLE PersonOwnAccount
ADD ROW DELETION POLICY (OLDER_THAN(expired_ts, INTERVAL 1 DAY));
כדי להשתמש בפונקציה CHANGES בטבלה ב-BigQuery, צריך להגדיר את האפשרות enable_change_history של הטבלה לערך TRUE:
ALTER TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`
SET OPTIONS (enable_change_history=TRUE);
בדוגמה הבאה אפשר לראות איך אפשר להשתמש ב-ETL הפוך כדי לעדכן שורות חדשות או שורות ששונו, ולהגדיר את תאריך התפוגה של שורות שמסומנות למחיקה. ביצוע left join עם הטבלה PersonOwnAccount מספק לשאילתה מידע על הסטטוס הנוכחי של כל שורה.
EXPORT DATA OPTIONS (
uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format='CLOUD_SPANNER',
spanner_options="""{
"table": "PersonOwnAccount",
"priority": "HIGH",
"tag" : "graph_data_delete_via_reverse_etl"
}"""
) AS
SELECT
DISTINCT
IF (changes._CHANGE_TYPE = 'DELETE', changes.id, poa.id) AS id,
IF (changes._CHANGE_TYPE = 'DELETE', changes.account_id, poa.account_id) AS account_id,
IF (changes._CHANGE_TYPE = 'DELETE', changes.create_time, poa.create_time) AS create_time,
IF (changes._CHANGE_TYPE = 'DELETE', changes._CHANGE_TIMESTAMP, NULL) AS expired_ts
FROM
CHANGES(TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`,
TIMESTAMP_TRUNC(TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 DAY), DAY),
TIMESTAMP_TRUNC(CURRENT_TIMESTAMP(), DAY)) changes
LEFT JOIN `PROJECT_ID.DATASET_NAME.PersonOwnAccount` poa
ON (poa.id = changes.id
AND poa.account_id = changes.account_id)
WHERE (changes._CHANGE_TYPE = 'DELETE'
AND poa.id IS NULL)
OR (changes._CHANGE_TYPE IN ( 'UPDATE', 'INSERT')
AND poa.id IS NOT NULL );
בשאילתה לדוגמה נעשה שימוש ב-LEFT JOIN עם טבלת המקור כדי לשמור על הסדר.
הצירוף הזה מבטיח שרשומות השינויים של DELETE יתעלמו משורות שנמחקו ואז נוצרו מחדש בתוך מרווח הזמן של היסטוריית השינויים של השאילתה. הצינור שומר את השורה החדשה התקינה.
כשמוחקים שורות, צינור הנתונים מאכלס את העמודה expired_ts בשורה המתאימה ב-Spanner Graph באמצעות חותמת הזמן DELETE מהעמודה _CHANGE_TIMESTAMP. מדיניות מחיקת שורות (מדיניות TTL) ב-Spanner מוחקת כל שורה שבה הערך של expired_ts הוא יותר מיום אחד בעבר.
כדי להבטיח את מהימנות המערכת, צריך לתאם בין לוח הזמנים של צינור הנתונים, חלון הזמן שבו מתבצעת בדיקה לאחור של השינויים ומדיניות ה-TTL של Spanner. לתזמן את צינור עיבוד הנתונים כך שיפעל מדי יום. משך הזמן של מדיניות ה-TTL ב-Spanner צריך להיות ארוך יותר מפרק הזמן הזה של ההפעלה. כך נמנעת האפשרות שצינור העיבוד יעבד מחדש אירוע DELETE קודם בשורה שכבר הוסרה על ידי מדיניות ה-TTL של Spanner.
בדוגמה הזו מוצג המרווח start_timestamp ו-end_timestamp של שאילתות יומיות שמתעדות את כל השינויים בטבלת BigQuery מהיום הקודם לפי שעון UTC. מכיוון שמדובר בשאילתת אצווה ולפונקציה CHANGES יש מגבלות, הערך של end_timestamp צריך להיות לפחות 10 דקות לפני השעה הנוכחית. לכן, מומלץ לתזמן את הרצת השאילתה לפחות 10 דקות אחרי חצות לפי שעון UTC. פרטים נוספים זמינים במאמרי העזרה בנושא CHANGES.
שימוש בעמודות TTL עם חותמת זמן של הפעם האחרונה שהמשתמש נראה
צינור reverse ETL מגדיר את העמודה last_seen_ts לחותמת הזמן הנוכחית עבור כל שורה בטבלת Spanner. כשמוחקים שורות ב-BigQuery, Spanner לא מעדכן את השורות התואמות, והעמודה last_seen_ts לא משתנה.
לאחר מכן, מערכת Spanner מסירה שורות עם last_seen_ts לא עדכני באמצעות מדיניות TTL או DML עם חלוקה למחיצות, על סמך סף מוגדר. לפני המחיקה המתוזמנת, שאילתות Spanner יכולות לסנן שורות עם last_seen_ts שגדול מהסף הזה. הגישה הזו יעילה במקרים שבהם נתוני הגרף מתעדכנים באופן שוטף, ועדכונים חסרים מצביעים על נתונים לא עדכניים שצריך למחוק.
ביצוע רענון מלא
לפני הטעינה מ-BigQuery, אפשר למחוק טבלאות Spanner כדי לשקף מחיקות בטבלאות המקור. כך נמנעת טעינה של שורות שנמחקו מטבלאות המקור ב-BigQuery אל Spanner במהלך ההרצה הבאה של צינור הנתונים. זו אולי האפשרות הכי קלה להטמעה. עם זאת, כדאי לקחת בחשבון את הזמן שנדרש לטעינה מחדש מלאה של נתוני הגרף.
תחזוקה של צינור עיבוד נתונים של ETL הפוך באצווה מתוזמנת
אחרי ההרצה הראשונית של צינור ה-ETL ההפוך, נתונים נטענים מ-BigQuery ל-Spanner Graph בכמות גדולה, ונתונים מהעולם האמיתי ממשיכים להשתנות. מערכי הנתונים משתנים, וצינור הנתונים מוסיף או מסיר רכיבי גרף לאורך זמן. הצינור מגלה צמתים חדשים ומוסיף קשרים חדשים בין קצוות, או שהסקת מסקנות מ-AI יוצרת אותם.
כדי לוודא שמסד הנתונים של Spanner Graph יישאר עדכני, מתזמנים ומסדרים את האורקסטרציה של צינורות BigQuery באמצעות אחת מהאפשרויות הבאות:
BigQuery Pipelines מאפשר לכם לפתח, לבדוק, לנהל גרסאות ולפרוס תהליכי עבודה מורכבים של טרנספורמציה של נתוני SQL ב-BigQuery. הוא מטפל באופן מובנה בתלות בין הזמנות, ומאפשר להגדיר קשרים בין השאילתות בצינור. Dataform בונה עץ תלות ומריץ את השאילתות בסדר הנכון. כך מוודאים שהתלות במעלה הזרם תושלם לפני שהמשימות במורד הזרם יתחילו.
Workflows שמופעלים על ידי Cloud Scheduler מספקים פתרון שימושי וגמיש לניהול רצפים של שירותיGoogle Cloud , כולל שאילתות BigQuery. הגדרת תהליך עבודה כסדרה של שלבים, שכל אחד מהם מריץ משימה ב-BigQuery. אפשר להשתמש ב-Cloud Scheduler כדי להפעיל את תהליכי העבודה האלה לפי לוח זמנים מוגדר. אפשר לנהל תלויות באמצעות הגדרת תהליך העבודה כדי לציין את סדר הביצוע, להטמיע לוגיקה מותנית, לטפל בשגיאות ולהעביר פלטים משאילתה אחת לשאילתה אחרת.
שאילתות מתוזמנות, שנקראות גם משימות העברה ב-BigQuery, מאפשרות להריץ ב-BigQuery הצהרות SQL על בסיס חוזר. שאילתות מתוזמנות לא מציעות טיפול חזק בשגיאות או ניהול דינמי של תלות.
Reverse ETL with BigQuery continuous queries
התכונה BigQuery continuous queries מאפשרת להריץ פעולות ב-BigQuery כמעט בזמן אמת. שילוב של EXPORT
DATA עם שאילתות רציפות מספק שיטה חלופית להפעלת צינורות ETL הפוך, שמונעת שימוש במשימות אצווה מתוזמנות.
שאילתה מתמשכת היא שאילתה שפועלת לאורך זמן ומנטרת טבלה ב-BigQuery כדי לזהות שורות חדשות. כש-BigQuery מזהה שורות חדשות שנוספו לטבלה, הוא מעביר את תוצאות השאילתה ל-EXPORT
DATA.
הגישה הזו מציעה את היתרונות הבאים:
סנכרון נתונים כמעט בזמן אמת: שורות חדשות ב-BigQuery משתקפות ב-Spanner עם עיכוב מינימלי.
תקורה מופחתת של עיבוד ברצף (batch processing): שאילתה מתמשכת מבטלת את הצורך במשימות באצווה תקופתיות, וכך מצמצמת את התקורה החישובית.
עדכונים מבוססי-אירועים: עדכוני נתונים ב-Spanner בתגובה לשינויים בפועל ב-BigQuery.
צינור לעיבוד נתונים של שאילתות מתמשכות דורש הקצאה של הזמנת משבצת עם הערך job_type של CONTINUOUS. אפשר להקצות את התפקיד הזה ברמת הפרויקט או התיקייה או ברמת הארגון.
יצירת שאילתה מתמשכת עם ETL הפוך מ-BigQuery ל-Spanner
מגדירים את הפרמטר start_timestamp של הפונקציה APPENDS כדי להתחיל לעבד את הנתונים מהמקום שבו טעינת האצווה הסתיימה. הפונקציה הזו מתעדת את כל השורות שנוצרו בחלון הזמן הספציפי. בדוגמה הבאה, צינור הנתונים (pipeline) קובע באופן שרירותי את נקודת ההתחלה כ-10 דקות לפני CURRENT_TIME.
חותמת הזמן הזו צריכה להיות בטווח של חלון הנסיעה בזמן ב-BigQuery.
יש כמה שיטות להפעלת צינור של שאילתות מתמשכות, כולל:
ב-BigQuery Studio, בוחרים באפשרות עוד ואז באפשרות שאילתה מתמשכת בקטע בחירת מצב שאילתה.
משתמשים ב-CLI של bq ומספקים את האפשרות
--continuous=true.
EXPORT DATA OPTIONS ( uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
format="CLOUD_SPANNER",
spanner_options="""{
"table": "PersonOwnAccount",
"priority": "HIGH",
"tag": "reverse-etl-continuous",
"change_timestamp_column": "create_time"
}"""
)
AS SELECT id, account_id, _CHANGE_TIMESTAMP as create_time
FROM
APPENDS(TABLE `PROJECT_ID.DATASET_NAME.PersonOwnAccount`,
CURRENT_TIMESTAMP() - INTERVAL 10 MINUTE )
סדר הטעינה לא מובטח
נתוני Spanner Graph מורכבים מכמה טבלאות קלט. כשבטבלאות יש אילוצים שלמות רפרנציאלית, צריך להקפיד על סדר טעינה מחמיר. עם זאת, שאילתות רציפות מקבילות לא יכולות לשלוט בסדר שבו Spanner מוסיף שורות. לכן, טעינת נתוני Spanner Graph באמצעות שאילתות רציפות מתאימה רק לסכימות של גרפים עם אילוצים מקלים של שלמות רפרנציאלית.
אינטגרציה עם צינורות עיבוד נתונים קיימים
שאילתה מתמשכת משלימה משימות קיימות באצווה מתוזמנת. לדוגמה, אפשר להשתמש בשאילתה רציפה כדי לקבל עדכונים כמעט בזמן אמת, ובמשימות מתוזמנות כדי לבצע סנכרון מלא של הנתונים או התאמה שלהם.
שימוש בשאילתה מתמשכת ב-BigQuery כדי ליצור צינורות ETL הפוך שמעדכנים את הנתונים ומגיבים במהירות, לצורך סנכרון נתונים בין BigQuery לבין Spanner Graph.
שיקולים לגבי שאילתות מתמשכות
עלות: שאילתות רציפות כרוכות בעלויות של הרצת שאילתות שוטפת ושל הזרמת נתונים.
טיפול בשגיאות: צינור של שאילתה מתמשכת מבוטל אם הוא נתקל בשגיאות במסד הנתונים, כמו מפתח ראשי כפול או הפרה של שלמות רפרנציאלית. אם צינור העברת הנתונים נכשל, צריך לתקן את הנתונים בטבלת המקור ב-BigQuery באופן ידני לפני שמפעילים מחדש את השאילתה.
מחיקות ועדכונים לא מטופלים: הפונקציה
APPENDSמתעדת רק הוספות. הוא לא מתעד מחיקות או עדכונים.
עבודה בהתאם לשיטות המומלצות לשימוש ב-ETL הפוך
כדי לקבל את התוצאות הטובות ביותר, כדאי לפעול לפי ההנחיות הבאות.
בחירת אסטרטגיה למניעת שגיאות של שלמות רפרנציאלית כשמעלים נתונים של קצה הרשת.
כדאי לתכנן את פייפליין הנתונים הכולל כדי למנוע קצוות לא מקושרים. קצוות חופשיים עלולים לפגוע ביעילות של שאילתות Spanner Graph ובשלמות של מבנה הגרף. מידע נוסף זמין במאמר בנושא מניעת קצוות לא מחוברים.
פועלים לפי ההמלצות לאופטימיזציה של ייצוא ב-Spanner.
אם אתם טוענים כמות גדולה של נתונים, כדאי לחלק את צינור הנתונים לכמה צינורות קטנים יותר כדי לא לחרוג ממכסת הזמן שמוגדרת כברירת מחדל לביצוע שאילתות ב-BigQuery (שש שעות). מידע נוסף זמין במאמר מגבלות על עבודות של שאילתות ב-BigQuery.
אם מעלים כמויות גדולות של נתונים, כדאי להוסיף אינדקסים ואילוצי מפתח זר אחרי שמסיימים את ההעלאה הראשונית של הנתונים בכמות גדולה. השיטה הזו משפרת את הביצועים של טעינת הנתונים, כי אילוצי מפתח זר דורשים קריאות נוספות לצורך אימות, ואינדקסים דורשים כתיבות נוספות. הפעולות האלה מגדילות את מספר המשתתפים בעסקה, מה שעלול להאט את תהליך טעינת הנתונים.
הפעלת התאמה אוטומטית לעומס ב-Spanner כדי לקצר את זמני טעינת הנתונים למופע. לאחר מכן, מגדירים את הפרמטר
priorityב-Spanner בקטעspanner_optionsשל הפקודהEXPORT DATABigQuery לערךHIGH. מידע נוסף מופיע במאמרים סקירה כללית של התאמה אוטומטית לעומס ב-Spanner, הגדרת ייצוא עם האפשרותspanner_optionsוRequestOptions.priority.במקרים של טעינת נתונים בכמות גדולה, כדאי ליצור נקודות פיצול כדי לפצל מראש את מסד הנתונים. הפעולה הזו מכינה את Spanner להגדלת התפוקה.
מגדירים עדיפות לבקשה ב-Spanner לטעינת הנתונים בהגדרת צינור הנתונים.
המאמרים הבאים
- בודקים את הסקירה הכללית של Spanner Graph.
- איך מעבירים נתונים ל-Spanner Graph
- עבודה עם תצוגה חזותית של הגרף ב-Spanner.
- איך משתמשים ב-ETL הפוך כדי לייצא נתונים מ-BigQuery ל-Spanner