יצירת טבלה חיצונית ב-Bigtable

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

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

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

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

כדי ליצור טבלה חיצונית שאפשר להשתמש בה לשליחת שאילתות לנתוני Bigtable, אתם צריכים להיות ישות בתפקיד אדמין של Bigtable‏ (roles/bigtable.admin) במופע שמכיל את טבלת המקור.

צריך גם את ההרשאה bigquery.tables.create לניהול זהויות והרשאות גישה (IAM) ב-BigQuery.

כל אחד מהתפקידים המוגדרים מראש הבאים של ניהול זהויות והרשאות גישה (IAM) כולל את ההרשאה הזו:

  • עריכה של נתוני BigQuery‏ (roles/bigquery.dataEditor)
  • בעלים של נתונים ב-BigQuery‏ (roles/bigquery.dataOwner)
  • אדמין של BigQuery‏ (roles/bigquery.admin)

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

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

יצירה או זיהוי של מערך נתונים

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

תכנון השימוש במחשוב

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

Data Boost

כדי למנוע השפעה על התנועה של האפליקציה, אפשר להשתמש במחשוב ללא שרתים של Data Boost כשמשתמשים בטבלה חיצונית של BigQuery כדי לקרוא את נתוני Bigtable. כדי להשתמש ב-Data Boost, צריך להשתמש בפרופיל אפליקציה של Data Boost ולכלול את מזהה פרופיל האפליקציה כשיוצרים את ה-URI של Bigtable. מידע נוסף על Data Boost זמין במאמר סקירה כללית על Data Boost ב-Bigtable.

צמתים שהוקצו

אם לא משתמשים ב-Data Boost, הצמתים של האשכול משמשים לחישובים.

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

זיהוי או יצירה של פרופיל אפליקציה

לפני שיוצרים טבלה חיצונית, צריך להחליט באיזה פרופיל אפליקציה של Bigtable‏ BigQuery צריך להשתמש כדי לקרוא את הנתונים. מומלץ להשתמש בפרופיל אפליקציה שייעודי לשימוש עם BigQuery בלבד. פרופיל האפליקציה יכול להיות פרופיל אפליקציה רגיל או פרופיל אפליקציה של Data Boost, בהתאם לסוג החישוב שרוצים להשתמש בו כדי לשלוח שאילתות לנתונים.

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

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

אחזור ה-URI של Bigtable

כדי ליצור טבלה חיצונית למקור נתונים של Bigtable, צריך לספק את ה-URI של Bigtable. כדי לאחזר את ה-URI של Bigtable:

  1. פותחים את הדף Bigtable במסוף.

    מעבר אל Bigtable

  2. צריך לאחזר את הפרטים הבאים על מקור הנתונים של Bigtable:

    • מזהה הפרויקט.
    • מזהה מכונת Bigtable.
    • המזהה של פרופיל האפליקציה ב-Bigtable שבו אתם מתכננים להשתמש. זה יכול להיות פרופיל אפליקציה רגיל או פרופיל אפליקציה של Data Boost, בהתאם לסוג המחשוב שבו רוצים להשתמש. אם לא מציינים מזהה של פרופיל אפליקציה, נעשה שימוש בפרופיל האפליקציה שמוגדר כברירת מחדל.
    • השם של הטבלה ב-Bigtable.
  3. יוצרים את ה-URI של Bigtable באמצעות הפורמט הבא, כאשר:

    • PROJECT_ID הוא הפרויקט שמכיל את מופע Bigtable
    • INSTANCE_ID הוא מזהה המכונה של Bigtable
    • APP_PROFILE (אופציונלי) הוא המזהה של פרופיל האפליקציה שבו רוצים להשתמש
    • TABLE_NAME הוא שם הטבלה שאתם שולחים לגביה שאילתה

    https://googleapis.com/bigtable/projects/PROJECT_ID/instances/INSTANCE_ID[/appProfiles/APP_PROFILE]/tables/TABLE_NAME

יצירת טבלאות חיצוניות קבועות

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

  • אם אתם משתמשים ב-API או בכלי שורת הפקודה של BigQuery, אתם יוצרים קובץ הגדרת טבלה שמגדיר את הסכימה והמטא-נתונים של הטבלה החיצונית.
  • אם אתם משתמשים ב-SQL, אתם צריכים להשתמש באפשרות uri של הצהרת CREATE EXTERNAL TABLE כדי לציין את טבלת Bigtable שממנה אתם רוצים למשוך נתונים, ובאפשרות bigtable_options כדי לציין את סכימת הטבלה.

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

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

SQL

כדי ליצור טבלה חיצונית קבועה, מריצים את הצהרת ה-DDL‏ CREATE EXTERNAL TABLE. צריך לציין באופן מפורש את סכימת הטבלה כחלק מאפשרויות ההצהרה.

  1. במסוף Google Cloud , עוברים לדף BigQuery.

    כניסה ל-BigQuery

  2. מזינים את ההצהרה הבאה בעורך השאילתות:

    CREATE EXTERNAL TABLE DATASET.NEW_TABLE
    OPTIONS (
      format = 'CLOUD_BIGTABLE',
      uris = ['URI'],
      bigtable_options = BIGTABLE_OPTIONS );

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

    • DATASET: מערך הנתונים שבו ייצור הטבלה החיצונית של Bigtable.
    • NEW_TABLE: השם של הטבלה החיצונית ב-Bigtable.
    • URI: ה-URI של טבלת Bigtable שרוצים להשתמש בה כמקור נתונים. ה-URI הזה צריך להיות בפורמט שמתואר במאמר אחזור ה-URI של Bigtable.
    • BIGTABLE_OPTIONS: הסכימה של טבלת Bigtable בפורמט JSON. רשימה של אפשרויות להגדרת טבלאות ב-Bigtable מופיעה במאמר בנושא BigtableOptionsבמאמרי העזרה של API בארכיטקטורת REST.

  3. לוחצים על הפעלה.

מידע נוסף על הרצת שאילתות זמין במאמר הרצת שאילתה אינטראקטיבית.

הצהרה ליצירת טבלת Bigtable חיצונית עשויה להיראות כך:

CREATE EXTERNAL TABLE mydataset.BigtableTable
OPTIONS (
  format = 'CLOUD_BIGTABLE',
  uris = ['https://googleapis.com/bigtable/projects/myproject/instances/myBigtableInstance/appProfiles/myAppProfile/tables/table1'],
  bigtable_options =
    """
    {
      columnFamilies: [
        {
          "familyId": "familyId1",
          "type": "INTEGER",
          "encoding": "BINARY"
        }
      ],
      readRowkeyAsString: true
    }
    """
);

BQ

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

  1. משתמשים בפקודה bq mk כדי ליצור טבלה קבועה.

    bq mk \
    --external_table_definition=DEFINITION_FILE \
    DATASET.TABLE

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

    • DEFINITION_FILE: הנתיב אל קובץ הגדרת הטבלה במחשב המקומי.
    • DATASET: השם של מערך הנתונים שמכיל את הטבלה.
    • TABLE: השם של הטבלה שיוצרים.

API

משתמשים ב-API method‏ tables.insert ויוצרים ExternalDataConfiguration במשאב Table שמעבירים.

במאפיין sourceUris במשאב Table, מציינים רק URI אחד של Bigtable. היא חייבת להיות כתובת URL תקינה מסוג HTTPS.

במאפיין sourceFormat, מציינים את הערך "BIGTABLE".

Java

לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Javaהוראות ההגדרה שבמדריך למתחילים של BigQuery באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של BigQuery Java API.

כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.BigtableColumn;
import com.google.cloud.bigquery.BigtableColumnFamily;
import com.google.cloud.bigquery.BigtableOptions;
import com.google.cloud.bigquery.ExternalTableDefinition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableId;
import com.google.cloud.bigquery.TableInfo;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;
import org.apache.commons.codec.binary.Base64;

// Sample to queries an external bigtable data source using a permanent table
public class QueryExternalBigtablePerm {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String bigtableInstanceId = "MY_INSTANCE_ID";
    String bigtableTableName = "MY_BIGTABLE_NAME";
    String bigqueryDatasetName = "MY_DATASET_NAME";
    String bigqueryTableName = "MY_TABLE_NAME";
    String sourceUri =
        String.format(
            "https://googleapis.com/bigtable/projects/%s/instances/%s/tables/%s",
            projectId, bigtableInstanceId, bigtableTableName);
    String query = String.format("SELECT * FROM %s ", bigqueryTableName);
    queryExternalBigtablePerm(bigqueryDatasetName, bigqueryTableName, sourceUri, query);
  }

  public static void queryExternalBigtablePerm(
      String datasetName, String tableName, String sourceUri, String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      BigtableColumnFamily.Builder statsSummary = BigtableColumnFamily.newBuilder();

      // Configuring Columns
      BigtableColumn connectedCell =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_cell".getBytes()))
              .setFieldName("connected_cell")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn connectedWifi =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_wifi".getBytes()))
              .setFieldName("connected_wifi")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn osBuild =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("os_build".getBytes()))
              .setFieldName("os_build")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();

      // Configuring column family and columns
      statsSummary
          .setColumns(ImmutableList.of(connectedCell, connectedWifi, osBuild))
          .setFamilyID("stats_summary")
          .setOnlyReadLatest(true)
          .setEncoding("TEXT")
          .setType("STRING")
          .build();

      // Configuring BigtableOptions is optional.
      BigtableOptions options =
          BigtableOptions.newBuilder()
              .setIgnoreUnspecifiedColumnFamilies(true)
              .setReadRowkeyAsString(true)
              .setColumnFamilies(ImmutableList.of(statsSummary.build()))
              .build();

      TableId tableId = TableId.of(datasetName, tableName);
      // Create a permanent table linked to the Bigtable table
      ExternalTableDefinition externalTable =
          ExternalTableDefinition.newBuilder(sourceUri, options).build();
      bigquery.create(TableInfo.of(tableId, externalTable));

      // Example query
      TableResult results = bigquery.query(QueryJobConfiguration.of(query));

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));

      System.out.println("Query on external permanent table performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

שאילתות על טבלאות חיצוניות

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

סכימה שנוצרה

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

דוגמה

אתם שומרים פרופילים של משתמשים ברשת חברתית בדיונית. מודל נתונים אחד יכול להיות profile קבוצת עמודות עם עמודות נפרדות ל-gender, ל-age ול-email:

rowkey | profile:gender| profile:age| profile:email
-------| --------------| -----------| -------------
alice  | female        | 30         | alice@gmail.com

אם משתמשים בסכימת ברירת המחדל, שאילתת GoogleSQL לספירת מספר המשתמשים הגברים מעל גיל 30 היא:

SELECT
  COUNT(1)
FROM
  `dataset.table`
OMIT
  RECORD IF NOT SOME(profile.column.name = "gender"
    AND profile.column.cell.value = "male")
  OR NOT SOME(profile.column.name = "age"
    AND INTEGER(profile.column.cell.value) > 30)

אם gender ו-age מוצגים כשדות משנה, קל יותר לבצע שאילתות על הנתונים. כדי לחשוף אותם כשדות משנה, צריך לרשום את gender ו-age כעמודות עם שם במשפחת העמודות profile כשמגדירים את הטבלה. אפשר גם להנחות את BigQuery לחשוף את הערכים האחרונים מקבוצת העמודות הזו, כי בדרך כלל רק הערך האחרון (ואולי הערך היחיד) מעניין.

אחרי שהופכים את העמודות לשדות משנה, שאילתת GoogleSQL לספירת מספר המשתמשים הגברים מעל גיל 30 היא:

SELECT
  COUNT(1)
FROM
  `dataset.table`
WHERE
  profile.gender.cell.value="male"
  AND profile.age.cell.value > 30

שימו לב לאופן שבו gender ו-age מופיעים ישירות כשדות. הגדרת ה-JSON למערך הזה היא:

  "bigtableOptions": {
    "readRowkeyAsString": "true",
    "columnFamilies": [
      {
          "familyId": "profile",
          "onlyReadLatest": "true",
          "columns": [
              {
                  "qualifierString": "gender",
                  "type": "STRING"
              },
              {
                  "qualifierString": "age",
                  "type": "INTEGER"
              }
          ]
      }
    ]
  }

קידוד ערכים

ב-Bigtable, הנתונים מאוחסנים כבייטים גולמיים, ללא קשר לקידוד הנתונים. עם זאת, לערכי בייטים יש שימוש מוגבל בניתוח של שאילתות SQL. ב-Bigtable יש שני סוגים בסיסיים של פענוח סקלרי: text ו-HBase-binary.

בפורמט הטקסט, כל הערכים מאוחסנים כמחרוזות טקסט אלפאנומריות. לדוגמה, המספר השלם 768 יישמר כמחרוזת '768'. הקידוד הבינארי מניח שהשתמשו במחלקה של שיטות Bytes.toBytes של HBase כדי לקודד את הנתונים, ומחיל שיטת פענוח מתאימה.

אזורים ותחומים נתמכים

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

מגבלות

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

היקפים למכונות Compute Engine

כשיוצרים מכונה של Compute Engine, אפשר לציין רשימה של היקפי גישה למכונה. ההיקפים שולטים בגישה של המופע למוצרים, כולל Bigtable. Google Cloudאפליקציות שפועלות במכונה הווירטואלית משתמשות בחשבון השירות כדי לקרוא לממשקי Google Cloud API.

אם הגדרתם מכונה של Compute Engine לפעול כחשבון שירות, וחשבון השירות הזה ניגש לטבלה חיצונית שמקושרת למקור נתונים של Bigtable, אתם צריכים להוסיף למכונה את היקף הגישה לנתונים לקריאה בלבד של Bigtable ‏(https://www.googleapis.com/auth/bigtable.data.readonly). מידע נוסף זמין במאמר בנושא יצירת מכונה של Compute Engine ל-Bigtable.

למידע על החלת היקפי הרשאות על מכונה של Compute Engine, ראו שינוי חשבון השירות והיקפי הגישה של מכונה. מידע נוסף על חשבונות שירות ב-Compute Engine זמין במאמר חשבונות שירות.

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