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

במאמר הזה מוסבר איך להגדיר ETL הפוך (RETL) מ-BigQuery ל-Bigtable. כדי לעשות את זה, אפשר להשתמש בהצהרה EXPORT DATA כדי לייצא נתונים מטבלה ב-BigQuery לטבלה ב-Bigtable.

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

מאפיינים של טבלאות Bigtable

טבלאות Bigtable שונות מטבלאות BigQuery בכמה דרכים:

  • גם טבלאות Bigtable וגם טבלאות BigQuery מורכבות משורות, אבל שורה ב-Bigtable מורכבת ממפתח שורה וממשפחות של עמודות שיש בהן מספר שרירותי של עמודות ששייכות לאותה משפחה של עמודות.
  • משפחות עמודות של טבלה מסוימת נוצרות בזמן יצירת הטבלה, אבל אפשר גם להוסיף או להסיר אותן מאוחר יותר. כשיוצרים קבוצת עמודות, לא צריך לציין את העמודות ששייכות לה.
  • אין צורך להגדיר מראש את העמודות ב-Bigtable, ואפשר להשתמש בהן כדי לאחסן נתונים בשם שלהן (שנקרא גם מגדיר) במסגרת מגבלות הגודל של הנתונים בטבלאות.
  • העמודות ב-Bigtable יכולות להכיל כל ערך בינארי במסגרת מגבלות גודל הנתונים בטבלאות.
  • לעמודות ב-Bigtable תמיד יש מימד זמני (שנקרא גם גרסה). אפשר לאחסן בכל שורה מספר כלשהו של ערכים באותה עמודה, כל עוד חותמת הזמן לא זהה.
  • חותמת זמן ב-Bigtable נמדדת במיקרו-שניות מאז ראשית זמן יוניקס. לדוגמה, 0 מייצג את התאריך 1970-01-01T00:00:00 UTC. חותמות הזמן צריכות להיות מספר לא שלילי של מיקרו-שניות, עם רמת דיוק של אלפיות השנייה (מקובלות רק כפולות של 1,000 מיקרו-שניות). חותמת הזמן של Bigtable שמוגדרת כברירת מחדל היא 0.
  • הנתונים ב-Bigtable נקראים לפי מפתח שורה, כמה מפתחות שורה, טווח של מפתחות שורה או באמצעות מסנן. בכל סוגי בקשות הקריאה, למעט סריקה מלאה של הטבלה, צריך לציין לפחות מפתח שורה אחד או טווח של מפתחות שורה.

מידע על הכנת תוצאות של BigQuery לייצוא ל-Bigtable זמין במאמר הכנת תוצאות של שאילתות לייצוא.

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

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

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

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

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

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

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

מגבלות

שיקולים בקשר למיקום

  • אם מערך הנתונים ב-BigQuery נמצא במספר אזורים, צריך להגדיר את פרופיל האפליקציה ב-Bigtable כך שהנתונים ינותבו לאשכול Bigtable בתוך אותם אזורים. לדוגמה, אם מערך הנתונים ב-BigQuery נמצא באזור US מרובה אזורים, אפשר למקם את אשכול Bigtable באזור us-west1 (אורגון), שנמצא בארצות הברית.
  • אם מערך הנתונים ב-BigQuery נמצא באזור יחיד, צריך להגדיר את פרופיל האפליקציה ב-Bigtable כך שינתב את הנתונים לאשכול Bigtable באותו אזור. לדוגמה, אם מערך הנתונים ב-BigQuery נמצא באזור asia-northeast1 (טוקיו), גם אשכול Bigtable צריך להיות באזור asia-northeast1 (טוקיו).

מידע נוסף זמין במאמר בנושא מיקומי Bigtable.

סוגים נתמכים ב-BigQuery

סוגי הנתונים הבאים נתמכים כשכותבים אותם ל-Bigtable:

סוג BigQuery ערך שנכתב ב-Bigtable
BYTES הייצוא מתבצע כמו שהוא.
STRING בוצעה המרה ל-BYTES.
INTEGER אם הערך של bigtable_options.column_families.encoding הוא BINARY, הערך נכתב בפורמט big-endian של 8 בייטים (הבייט המשמעותי ביותר ראשון). אם bigtable_options.column_families.encoding מוגדר כ-TEXT, הערך נכתב כמחרוזת שניתנת לקריאה על ידי בני אדם ומייצגת מספר.
FLOAT כותב ערך בפורמט הפלט IEEE 754 8-byte.
BOOLEAN אם הערך של bigtable_options.column_families.encoding הוא BINARY, הערך נכתב כערך של בייט אחד (false = 0x00 או true = 0x01). אם bigtable_options.column_families.encoding מוגדר כ-TEXT, הערך נכתב כטקסט ("true" או "false").
JSON
עמודה מיוצאת מסוג JSON מתפרשת כקבוצה של עמודות ששייכות למשפחת עמודות ספציפית ב-Bigtable. החברים באובייקט ה-JSON מפורשים כעמודות, והערכים שלהם נכתבים ב-Bigtable. אפשר לשנות את השם של העמודה שבה יתבצע הכתיבה באמצעות ההגדרה bigtable_options.

לדוגמה:
    JSON '{"FIELD1": "VALUE1", "FIELD2": "VALUE2"}' as MY_COLUMN_FAMILY
    
הערכים VALUE1 ו-VALUE2 נכתבים ב-Bigtable כעמודות FIELD1 ו-FIELD2 במשפחת העמודות MY_COLUMN_FAMILY.
STRUCT
עמודה מיוצאת מסוג STRUCT מתפרשת כקבוצה של עמודות ששייכות למשפחת עמודות ספציפית ב-Bigtable. האיברים במבנה מפורשים כעמודות והערכים שלהם נכתבים ב-Bigtable. אפשר לשנות את השם של העמודה שבה יתבצע הכתיבה באמצעות ההגדרה bigtable_options.

לדוגמה:
    STRUCT<FIELD1  STRING, FIELD2 INTEGER> as MY_COLUMN_FAMILY
    
הערכים FIELD1 ו-FIELD2 נכתבים ב-Bigtable כעמודות FIELD1 ו-FIELD2 במשפחת העמודות MY_COLUMN_FAMILY.

סוגי הנתונים הנתמכים האלה דומים לקריאה מטבלאות Bigtable חיצוניות ב-BigQuery.

ערכי NULL ב-Bigtable

הערכים של NULL ב-Bigtable כפופים למגבלות הבאות:

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

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

  • כשמייצאים ערך NULL מסוג STRUCT או JSON, כל הערכים בעמודה ששייכים למשפחת העמודות המתאימה בשורה המושפעת נמחקים. כדי שמנוע ה-SQL יקצה ערך מסוג מתאים, צריך להמיר את הערך NULL לסוג STRUCT או JSON. השאילתה הבאה מוחקת את כל הנתונים ממשפחת העמודות column_family1 עם קבוצה של מפתחות שורות נתונים:

    EXPORT DATA OPTIONS (...) AS
    SELECT
      rowkey,
    CAST(NULL as STRUCT<INT64>) AS column_family1 FROM T
  • הייצוא לא כולל שורות עם מפתחות שורות NULL. מספר השורות שדילגו עליהן מוחזר בסטטיסטיקות הייצוא למתקשר.

הגדרת ייצוא באמצעות bigtable_options

אתם יכולים להשתמש בהגדרה bigtable_options במהלך ייצוא כדי לצמצם את ההבדלים בין מודלים של אחסון ב-BigQuery וב-Bigtable. ההגדרה מבוטאת בצורה של מחרוזת JSON, כמו בדוגמה הבאה:

EXPORT DATA OPTIONS(
   uri="https://bigtable.googleapis.com/projects/PROJECT_ID/instances/INSTANCE_ID/appProfiles/APP_PROFILE_ID/tables/TABLE",
   bigtable_options = """{
     "columnFamilies": [{
       "familyId": "COLUMN_FAMILY_NAME",
       "encoding": "ENCODING_VALUE",
       "columns": [
         {
           "qualifierString": "BIGTABLE_COLUMN_QUALIFIER",
           ["qualifierEncoded": "BASE_64_ENCODED_VALUE",]
           "fieldName": "BIGQUERY_RESULT_FIELD_NAME"
         }
       ]
    }]
   }"""
)

בטבלה הבאה מתוארים השדות האפשריים שמשמשים בהגדרה:bigtable_options

שם השדה תיאור
columnFamilies מערך של מתארי קבוצות עמודות.
columnFamilies.familyId מזהה של קבוצת עמודות ב-Bigtable.
columnFamilies.encoding הערך יכול להיות BINARY או TEXT. מידע על האופן שבו סוגים מקודדים זמין במאמר סוגים נתמכים ב-BigQuery.
columnFamilies.columns מערך של מיפויי עמודות ב-Bigtable.
columnFamilies.columns.qualifierString אופציונלי: מגדיר עמודה ב-Bigtable. מציינים את הערך הזה אם מגדיר העמודה לא מכיל קודים שאינם UTF-8. השדות qualifierString ו-qualifierEncoding הם בלעדיים. אם לא מציינים את qualifierString או את qualifierEncoded, המערכת משתמשת ב-fieldName כמגדיר העמודה.
columnFamilies.columns.qualifierEncoded אופציונלי: מגדיר עמודה בקידוד Base64. בדומה ל-qualifierString במקרה שמגדיר העמודה חייב לכלול קודים שאינם UTF-8.
columnFamilies.columns.fieldName חובה: שם השדה של קבוצת התוצאות ב-BigQuery. במקרים מסוימים יכול להיות מחרוזת ריקה. דוגמה לשימוש בערך ריק fieldName בשדות מסוגים פשוטים מופיעה במאמר הכנת תוצאות של שאילתות לייצוא.

הכנת תוצאות השאילתה לייצוא

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

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

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

אם אתם משתמשים בערכים מיוצאים עם ממשקי API של Bigtable, כמו ReadModifyWriteRow, כל הערכים המספריים צריכים להשתמש בקידוד בינארי הנכון.

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

כדי להדגים איך כותבים את סוגי הנתונים האלה, נשתמש בדוגמה הבאה של SQL, כאשר column ו-column2 הן עמודות תוצאה עצמאיות:

SELECT
  x as column1, y as column2
FROM table

בשילתת הדוגמה הזו, הפונקציה SELECT x as column1 כותבת ערכים ל-Bigtable תחת משפחת העמודות column1 ומוגדרת כמסווג העמודות '' (מחרוזת ריקה) כשמטפלים בסוגים שאינם JSON או STRUCT.

אפשר לשנות את האופן שבו הסוגים האלה נכתבים בייצוא באמצעות ההגדרה bigtable_options, כמו בדוגמה הבאה:

EXPORT DATA OPTIONS (
  
  bigtable_options="""{
   "columnFamilies" : [
      {
        "familyId": "ordered_at",
        "columns": [
           {"qualifierString": "order_time", "fieldName": ""}
        ]
      }
   ]
}"""
) AS
SELECT
  order_id as rowkey,
  STRUCT(product, amount) AS sales_info,
  EXTRACT (MILLISECOND FROM order_timestamp AT TIME ZONE "UTC") AS ordered_at
FROM T

בדוגמה הזו, הטבלה T ב-BigQuery מכילה את השורה הבאה:

order_id order_timestamp product amount
101 2023-03-28T10:40:54Z ג'ויסטיק 2

אם משתמשים בהגדרה bigtable_options הקודמת עם הטבלה T, הנתונים הבאים נכתבים ב-Bigtable:

rowkey sales_info (קבוצת עמודות) ordered_at (קבוצת עמודות)
101 מוצר סכום order_time
1970-01-01T00:00:00Z ג'ויסטיק 1970-01-01T00:00:00Z 2 1680000054000

1680000054000 מייצג את 2023-03-28T10:40:54Z באלפיות השנייה מאז ראשית זמן יוניקס (Unix epoch) באזור הזמן UTC.

יצירה אוטומטית של משפחות עמודות חדשות

כדי ליצור באופן אוטומטי משפחות עמודות חדשות בטבלת Bigtable, מגדירים את האפשרות auto_create_column_families בהצהרת EXPORT DATA לערך true. בשביל האפשרות הזו נדרשת ההרשאה bigtable.tables.update, שכלולה בתפקידים כמו אדמין ב-Bigtable (roles/bigtable.admin).

EXPORT DATA OPTIONS (
uri="https://bigtable.googleapis.com/projects/PROJECT-ID/instances/INSTANCE-ID/appProfiles/APP_PROFILE_ID/tables/TABLE",
format="CLOUD_BIGTABLE",
auto_create_column_families = true
) AS
SELECT
  order_id as rowkey,
  STRUCT(product, amount) AS sales_info
FROM T

הגדרת חותמת זמן לכל התאים בשורה באמצעות _CHANGE_TIMESTAMP

אפשר להוסיף לעמודה _CHANGE_TIMESTAMP מסוג TIMESTAMP לתוצאה לייצוא. כל תא שנכתב ב-Bigtable משתמש בערך חותמת הזמן מ-_CHANGE_TIMESTAMP של שורת התוצאה המיוצאת.

‫Bigtable לא תומך בחותמות זמן מוקדמות יותר מראשית זמן יוניקס (1970-01-01T00:00:00Z). אם הערך של _CHANGE_TIMESTAMP הוא NULL, חותמת הזמן שמוגדרת כברירת מחדל היא חותמת הזמן של תקופת הזמן של מערכת UNIX של 0.

השאילתה הבאה כותבת תאים לעמודות product ו-amount עם חותמת הזמן שצוינה בעמודה order_timestamp של הטבלה T.

EXPORT DATA OPTIONS (...) AS
SELECT
  rowkey,
  STRUCT(product, amount) AS sales_info,
  order_timestamp as _CHANGE_TIMESTAMP
FROM T

ייצוא רציף

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

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

כשמייצאים תוצאה שמכילה כמה שורות עם אותו ערך rowkey, הערכים שנכתבים ל-Bigtable נשמרים באותה שורה ב-Bigtable.

אתם יכולים להשתמש בשיטה הזו כדי ליצור כמה גרסאות של ערכי עמודות באותה שורה. בדוגמה הזו, הטבלה orders ב-BigQuery מכילה את הנתונים הבאים:

id customer order_timestamp amount_spent
100 בוב 2023-01-01T10:10:54Z 10.99
101 Alice 2023-01-02T12:10:50Z ‪102.7
102 בוב 2023-01-04T15:17:01Z ‫11.1

לאחר מכן המשתמש מריץ את ההצהרה הבאה EXPORT DATA:

EXPORT DATA OPTIONS (
uri="https://bigtable.googleapis.com/projects/PROJECT-ID/instances/INSTANCE-ID/appProfiles/APP_PROFILE_ID/tables/TABLE",
format="CLOUD_BIGTABLE"
) AS
SELECT customer as rowkey, STRUCT(amount_spent) as orders_column_family, order_timestamp as _CHANGE_TIMESTAMP
FROM orders

שימוש בהצהרה הזו עם הטבלה orders ב-BigQuery מוביל לכתיבת הנתונים הבאים ב-Bigtable:

orders_column_family
מפתח שורה amount_spent
Alice 2023-01-02T12:10:50Z ‪102.7
בוב 2023-01-01T10:10:54Z 10.99
2023-01-04T15:17:01Z ‫11.1

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

ייצוא של כמה עמודות כערכי Protocol Buffer ‏ (Protobuf)

מאגרי פרוטוקולים מספקים מנגנון גמיש ויעיל לסריאליזציה של נתונים מובְנים. ייצוא כ-Protobuf יכול להיות מועיל בהתחשב באופן הטיפול בסוגים שונים בין BigQuery לבין Bigtable. אפשר להשתמש בפונקציות מוגדרות על ידי המשתמש (UDF) ב-BigQuery כדי לייצא נתונים כערכים בינאריים של Protobuf ל-Bigtable. מידע נוסף זמין במאמר ייצוא נתונים כעמודות Protobuf.

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

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

תמחור

כשמייצאים נתונים בשאילתה רגילה, החיוב מתבצע לפי תמחור חילוץ נתונים. כשמייצאים נתונים בשאילתה מתמשכת, החיוב מתבצע לפי תמחור קיבולת החישוב של BigQuery. כדי להריץ שאילתות רציפות, צריך הזמנה שמשתמשת במהדורות Enterprise או Enterprise Plus, והקצאת הזמנה שמשתמשת בסוג המשימה CONTINUOUS.

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