ייצוא נתונים ל-Spanner (תהליך ETL הפוך)

במאמר הזה מוסבר איך להגדיר תהליך עבודה של חילוץ, טרנספורמציה וטעינה הפוכים (reverse ETL) מ-BigQuery אל Spanner. כדי לעשות את זה, אפשר להשתמש בהצהרת EXPORT DATA לייצוא נתונים ממקורות נתונים של BigQuery, כולל טבלאות Iceberg, לטבלת Spanner.

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

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

התפקידים הנדרשים

כדי לקבל את ההרשאות שדרושות לייצוא נתונים מ-BigQuery אל Spanner, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

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

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

מגבלות

  • התכונה הזו לא נתמכת ב-Assured Workloads.

  • לסוגי הנתונים הבאים ב-BigQuery אין מקבילות ב-Spanner, ולכן הם לא נתמכים:

ניב של מסד נתונים ב-Spanner סוגים שלא נתמכים ב-BigQuery
כל הניבים
  • STRUCT
  • GEOGRAPHY
  • DATETIME
  • RANGE
  • TIME
GoogleSQL
  • BIGNUMERIC: סוג NUMERIC הנתמך לא רחב מספיק. כדאי להוסיף המרות מפורשות לסוג NUMERIC בשאילתה.
  • הגודל המקסימלי של שורה מיוצאת לא יכול לחרוג מ-1 MiB.

  • מערכת Spanner אוכפת את השלמות ההפניה במהלך הייצוא. אם טבלת היעד היא צאצא של טבלה אחרת (INTERLEAVE IN PARENT), או אם לטבלת היעד יש אילוצי מפתח זר, המפתחות הזרים ומפתח ההורה יאומתו במהלך הייצוא. אם שורה שיוצאה נכתבת לטבלה עם INTERLEAVE IN PARENT ושורת ההורה לא קיימת, הייצוא ייכשל עם השגיאה'שורת ההורה חסרה'. השגיאה 'אי אפשר לכתוב את השורה'. אם השורה המיוצאת נכתבת לטבלה עם אילוצי מפתח זר והיא מפנה למפתח שלא קיים, הייצוא ייכשל עם השגיאה Foreign key constraint is violated (הפרה של אילוץ מפתח זר). כשמייצאים לכמה טבלאות, מומלץ להגדיר את הייצוא כך שסדר הפעולות יבטיח שיושלם ייצוא של כל הנתונים. בדרך כלל, המשמעות היא ייצוא של טבלאות אב וטבלאות שמפנות למפתחות זרים לפני טבלאות שמפנות אליהן.

    אם הטבלה שאליה מייצאים נתונים כוללת אילוצים של מפתח זר, או שהיא צאצא של טבלה אחרת (INTERLEAVE IN PARENT), צריך לאכלס את טבלת ההורה לפני ייצוא של טבלת צאצא, והיא צריכה להכיל את כל המפתחות התואמים. ניסיון לייצא טבלת צאצאים בזמן שטבלת אב לא מכילה את כל המפתחות הרלוונטיים ייכשל.

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

  • ייצוא ל-Spanner נתמך רק במהדורות BigQuery Enterprise או Enterprise Plus. אין תמיכה במהדורת BigQuery Standard ובחישוב לפי דרישה.

  • אי אפשר להשתמש בשאילתות רציפות כדי לייצא לטבלאות Spanner עם מפתחות ראשיים שנוצרו אוטומטית.

  • אי אפשר להשתמש בשאילתות רציפות כדי לייצא לטבלאות Spanner במסד נתונים עם ניב PostgreSQL.

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

הגדרת ייצוא באמצעות האפשרות spanner_options

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

EXPORT DATA OPTIONS(
   uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
   spanner_options = """{
      "table": "TABLE_NAME",
      "change_timestamp_column": "CHANGE_TIMESTAMP",
      "priority": "PRIORITY",
      "tag": "TAG",
   }"""
)

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: השם של Google Cloud הפרויקט.
  • INSTANCE_ID: השם של מופע מסד הנתונים.
  • DATABASE_ID: השם של מסד הנתונים.
  • TABLE_NAME: השם של טבלת יעד קיימת.
  • CHANGE_TIMESTAMP: השם של עמודת הסוג TIMESTAMP בטבלת היעד ב-Spanner. האפשרות הזו משמשת במהלך הייצוא כדי לעקוב אחרי חותמת הזמן של עדכון השורה האחרון. כשמציינים את האפשרות הזו, הייצוא קודם קורא את השורה בטבלת Spanner, כדי לוודא שרק העדכון האחרון של השורה נכתב. מומלץ לציין עמודה מסוג TIMESTAMP כשמריצים ייצוא רציף, במקרים שבהם חשוב הסדר של השינויים בשורות עם אותו מפתח ראשי.
  • PRIORITY (אופציונלי): priority של בקשות הכתיבה. הערכים המותרים: LOW, ‏ MEDIUM, ‏ HIGH. ערך ברירת מחדל: MEDIUM.
  • TAG (אופציונלי): תג בקשה כדי לזהות את התנועה של כלי הייצוא בניטור של Spanner. ערך ברירת המחדל: bq_export.

דרישות לייצוא שאילתות

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

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

המרות של סוגים

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

סוג BigQuery סוג Spanner
BIGNUMERIC ‫NUMERIC (ניב PostgreSQL בלבד)
FLOAT64 FLOAT32
BYTES PROTO
INT64 ENUM

ייצוא נתונים

אפשר להשתמש בהצהרה EXPORT DATA כדי לייצא נתונים מטבלה ב-BigQuery לטבלת Spanner.

בדוגמה הבאה מיוצאים שדות נבחרים מטבלה בשם mydataset.table1:

EXPORT DATA OPTIONS (
  uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
  format='CLOUD_SPANNER',
  spanner_options="""{ "table": "TABLE_NAME" }"""
)
AS SELECT * FROM mydataset.table1;

מחליפים את מה שכתוב בשדות הבאים:

  • PROJECT_ID: השם של Google Cloud הפרויקט
  • INSTANCE_ID: השם של מופע מסד הנתונים
  • DATABASE_ID: השם של מסד הנתונים
  • TABLE_NAME: השם של טבלת יעד קיימת

ייצוא של כמה תוצאות עם אותו ערך של rowkey

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

ייצוא רציף

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

אופטימיזציה של ייצוא

כדי לייעל את הייצוא של רשומות מ-BigQuery ל-Spanner, אפשר לנסות את הפעולות הבאות:

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

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

    בדוגמה הבאה מוצגת פקודת ייצוא של Spanner שהוגדרה לעדיפות HIGH:

    EXPORT DATA OPTIONS (
      uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
      format='CLOUD_SPANNER',
      spanner_options="""{ "table": "TABLE_NAME", "priority": "HIGH" }"""
    )
  • לא מומלץ להזמין את תוצאות השאילתה. אם קבוצת התוצאות מכילה את כל העמודות של המפתח הראשי, הכלי לייצוא ממיין באופן אוטומטי את המפתחות הראשיים של טבלת היעד כדי לייעל את פעולות הכתיבה ולצמצם את התחרות על משאבים.

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

    לדוגמה, בסכימת Spanner הבאה, SaleYear ו-SaleMonth הן עמודות שנוצרו ומרכיבות את ההתחלה של המפתח הראשי של Spanner:

    CREATE TABLE Sales (
      SaleId STRING(36) NOT NULL,
      ProductId INT64 NOT NULL,
      SaleTimestamp TIMESTAMP NOT NULL,
      Amount FLOAT64,
      -- Generated columns
      SaleYear INT64 AS (EXTRACT(YEAR FROM SaleTimestamp)) STORED,
      SaleMonth INT64 AS (EXTRACT(MONTH FROM SaleTimestamp)) STORED,
    ) PRIMARY KEY (SaleYear, SaleMonth, SaleId);

    כשמייצאים נתונים מ-BigQuery לטבלת Spanner עם עמודות שנוצרו ומשמשות כמפתח הראשי, מומלץ, אבל לא חובה, לכלול את הביטויים של העמודות שנוצרו בשאילתת EXPORT DATA. כך BigQuery יכול למיין מראש את הנתונים בצורה נכונה, וזה חיוני ליצירת חבילות יעילה ולכתיבה ב-Spanner. הערכים של העמודות שנוצרו בהצהרת EXPORT DATA לא נשמרים ב-Spanner, כי הם נוצרים אוטומטית על ידי Spanner, אבל הם משמשים לאופטימיזציה של הייצוא.

    בדוגמה הבאה מיוצאים נתונים לטבלת Sales ב-Spanner, שבה המפתח הראשי משתמש בעמודות שנוצרו. כדי לייעל את ביצועי הכתיבה, השאילתה כוללת ביטויים של EXTRACT שתואמים לעמודות SaleYear ו-SaleMonth שנוצרו, וכך מאפשרים ל-BigQuery למיין מראש את הנתונים לפני הייצוא:

    EXPORT DATA OPTIONS (
      uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
      format='CLOUD_SPANNER',
      spanner_options="""{ "table": "Sales" }"""
    )
    AS SELECT
      s.SaleId,
      s.ProductId,
      s.SaleTimestamp,
      s.Amount,
      -- Add expressions that match the generated columns in the Spanner PK
      EXTRACT(YEAR FROM s.SaleTimestamp) AS SaleYear,
      EXTRACT(MONTH FROM s.SaleTimestamp) AS SaleMonth
    FROM my_dataset.sales_export AS s;
  • כדי למנוע עבודות ארוכות, מייצאים נתונים לפי מחיצה. מפצלים את הנתונים ב-BigQuery באמצעות מפתח חלוקה, כמו חותמת זמן בשאילתה:

    EXPORT DATA OPTIONS (
      uri="https://spanner.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/databases/DATABASE_ID",
      format='CLOUD_SPANNER',
      spanner_options="""{ "table": "TABLE_NAME", "priority": "MEDIUM" }"""
    )
    AS SELECT *
    FROM 'mydataset.table1' d
    WHERE
    d.timestamp >= TIMESTAMP '2025-08-28T00:00:00Z' AND
    d.timestamp < TIMESTAMP '2025-08-29T00:00:00Z';

    כך השאילתה תוכל להסתיים תוך 6 שעות של זמן ריצה של העבודה. מידע נוסף על המגבלות האלה זמין במאמר בנושא מגבלות על שאילתות.

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

  • מומלץ להתחיל עם צומת Spanner אחד (1,000 יחידות עיבוד) והזמנת יחידת קיבולת מינימלית ב-BigQuery. לדוגמה, 100 משבצות זמן או 0 משבצות זמן בסיסיות עם התאמה אוטומטית לעומס. בדרך כלל, ייצואים של עד 100 GB מסתיימים תוך 6 שעות, שהוא הזמן המקסימלי שמוגדר לעבודות. כדי לייצא נתונים בנפח של יותר מ-100GB, צריך להגדיל את התפוקה על ידי הגדלת מספר הצמתים ב-Spanner והזמנת יחידות קיבולת של BigQuery, לפי הצורך. התפוקה גדלה בערך ב-5MiB/s לכל צומת.

תמחור

כשמייצאים נתונים ל-Spanner באמצעות ההצהרה EXPORT DATA, החיוב מתבצע לפי תמחור של קיבולת מחשוב ב-BigQuery.

כדי לייצא באופן רציף ל-Spanner באמצעות שאילתה מתמשכת, צריך להקצות יחידות קיבולת (slot) ב-BigQuery Enterprise או Enterprise Plus ולהקצות מקום שמור באמצעות סוג העבודה CONTINUOUS.

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

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