建立及管理 protobuf 結構定義

本文說明如何建立結構定義套件,以及對套件執行作業。

在 Bigtable 中,您可以使用通訊協定緩衝區 (protobuf) 結構定義,查詢以位元組形式儲存在資料欄中的 protobuf 訊息內個別欄位。方法是將結構定義上傳至結構定義套件,這是一種資料表層級資源,包含一或多個 protobuf 結構定義。

使用結構定義套件有以下好處:

  • 節省時間和心力:使用通訊協定緩衝區時,您只需在 proto 檔案中定義資料結構一次,然後使用產生的原始碼寫入及讀取資料。
  • 提升資料一致性:將 proto 檔案做為單一事實來源,確保所有應用程式和服務都使用相同的資料模型。
  • 消除資料重複:您可以在特定專案程式碼集以外的 proto 檔案中定義訊息類型,藉此跨專案使用通訊協定緩衝區。

在 Bigtable 中使用結構定義時,首先要建立 proto 檔案。proto 檔案是定義資料結構的文字檔案。您可以使用 protobuf 編譯器工具 (也稱為 protoc) 產生 protobuf 檔案描述元集,這是 proto 檔案的機器可讀結構定義。接著,您可以使用這個描述元集建立結構定義套件。

如需 proto 檔案和對應描述元集的範例,請參閱「範例資料」。

下圖顯示在 Bigtable 中使用結構定義的程序:

在 Bigtable 中使用 protobuf 結構定義的程序。
圖 1. 在 Bigtable 中使用 protobuf 結構定義的程序 (按一下即可放大)。

您可以使用 Google Cloud 控制台或 Google Cloud CLI 建立結構定義套件。將結構定義套件上傳至 Bigtable 後,您可以使用 Bigtable Studio 查詢建立工具、Bigtable 專用 GoogleSQL,或 BigQuery 中的 Bigtable 外部資料表查詢資料。

事前準備

如要使用 gcloud CLI,請按照下列步驟操作:

  1. 安裝 Google Cloud CLI。
  2. 初始化 gcloud CLI:

    gcloud init
    

必要的角色

如要取得建立及管理結構定義套件所需的權限,請要求管理員授予您資料表的 Bigtable 管理員 (roles/bigtable.admin) Identity and Access Management (IAM) 角色。

這個預先定義的角色具備 Bigtable 使用結構定義套件所需的權限。如要查看確切的必要權限,請展開「Required permissions」(必要權限) 部分:

所需權限

  • bigtable.schemaBundles.create
  • bigtable.schemaBundles.update
  • bigtable.schemaBundles.delete
  • bigtable.schemaBundles.get
  • bigtable.schemaBundles.list

您或許還可透過自訂角色或其他預先定義的角色取得這些權限。

如要進一步瞭解 Bigtable 角色和權限,請參閱「使用 IAM 控管存取權」。

產生 protobuf 檔案描述元集

您必須先使用 protobuf 編譯器工具,從 proto 檔案產生描述元組合,才能建立結構定義套件。

  1. 如要安裝編譯器,請下載套件,並按照 README 檔案中的指示操作。
  2. 執行編譯器:

    protoc --proto_path=IMPORT_PATH --include_imports \
       --descriptor_set_out=DESCRIPTOR_OUTPUT_LOCATION PATH_TO_PROTO
    

    更改下列內容:

    • IMPORT_PATH:protoc 編譯器搜尋 proto 檔案的目錄。
    • DESCRIPTOR_OUTPUT_LOCATION:protoc 編譯器儲存所產生描述元集的目錄。
    • PATH_TO_PROTO:proto 檔案的路徑。

舉例來說,如要為目前目錄中的 library.proto 檔案建立名為 library.pb 的描述元組合,可以使用下列指令:

protoc --include_imports --descriptor_set_out=library.pb
library.proto

建立結構定義組合

控制台

  1. 在 Google Cloud 控制台中,開啟 Bigtable 執行個體清單。

    開啟執行個體清單

  2. 從清單中選取執行個體。

  3. 在導覽窗格中,點選「Bigtable Studio」。

  4. 在「Explorer」窗格中,找到要建立結構定義套件的資料表,然後依序點選旁邊的「more_vert」more_vert動作選單和「Create schema bundle」(建立結構定義套件)。

  5. 在「Create schema bundle」(建立結構定義套件) 對話方塊的「Schema Bundle ID」(結構定義套件 ID) 欄位中,輸入結構定義套件的專屬 ID。

    ID 長度必須介於 1 到 50 個字元之間,只能包含英文字母、數字、底線和連字號,開頭不得為連字號,且不得包含半形句號 (.)。

  6. 在「File Descriptor Set (.pb file)」(檔案描述元集 (.pb 檔案)) 欄位中,按一下「Browse」(瀏覽),選取您在本文件「產生 protobuf 檔案描述元集」一節中建立的 protobuf 檔案描述元集。檔案大小不得超過 4 MB。

  7. 點選「建立」。

    結構定義套件會在新分頁中開啟。

gcloud

如要建立結構定義套件,請使用 gcloud bigtable schema-bundles create 指令:

gcloud bigtable schema-bundles create SCHEMA_BUNDLE_ID \
    --instance=INSTANCE_ID \
    --table=TABLE_ID \
    --proto-descriptors-file=PROTO_DESCRIPTORS_FILE

更改下列內容:

  • SCHEMA_BUNDLE_ID:新結構定義套件的專屬 ID,不得包含任何句號 (「.」) 字元。
  • INSTANCE_ID:建立結構定義套件的執行個體 ID。
  • TABLE_ID:您建立結構定義套件的資料表 ID。
  • PROTO_DESCRIPTORS_FILE:您在本文件「產生 protobuf 檔案描述元集」一節中建立的描述元集路徑。

Java

如要建立結構定義組合,請使用 createSchemaBundle 方法:

如要瞭解如何安裝及使用 Bigtable 的用戶端程式庫,請參閱「Bigtable 用戶端程式庫」。

如要向 Bigtable 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

try (InputStream in = getClass().getClassLoader().getResourceAsStream(PROTO_FILE_PATH)) {
  if (in == null) {
    throw new FileNotFoundException("Resource not found: " + PROTO_FILE_PATH);
  }
  SchemaBundle schemaBundleObj =
      SchemaBundle.newBuilder()
          .setProtoSchema(
              ProtoSchema.newBuilder().setProtoDescriptors(ByteString.readFrom(in)).build())
          .build();
  CreateSchemaBundleRequest request =
      CreateSchemaBundleRequest.newBuilder()
          .setParent(
              "projects/" + projectId + "/instances/" + instanceId + "/tables/" + tableId)
          .setSchemaBundleId(schemaBundleId)
          .setSchemaBundle(schemaBundleObj)
          .build();
  SchemaBundle schemaBundle = adminClient.createSchemaBundleAsync(request).get();
  System.out.printf("Schema bundle: %s created successfully%n", schemaBundle.getName());
} catch (Exception e) {
  System.err.println("Failed to create a schema bundle: " + e.getMessage());
}

查看結構定義套裝組合的相關資訊

您必須擁有至少一個結構定義套件的 Bigtable 資料表,才能查看結構定義套件的相關資訊。如要取得資料表中的結構定義組合資訊,可以擷取單一結構定義組合的定義,或列出資料表中的所有結構定義組合。

取得結構定義組合定義

控制台

  1. 在 Google Cloud 控制台中,開啟 Bigtable 執行個體清單。

    開啟執行個體清單

  2. 從清單中選取執行個體。

  3. 在導覽窗格中,點選「Bigtable Studio」。

  4. 在「Explorer」窗格中,依序展開含有結構定義套件的資料表和「Schema Bundles」(結構定義套件)。

  5. 按一下要查看的結構定義套件,或按一下結構定義套件旁的「more_vert」more_vert動作選單,然後點選「View details」(查看詳細資料)。

    系統會開啟一個分頁,顯示結構定義套件定義。

  6. 選用:如要開啟 SQL 查詢編輯器分頁,並使用結構定義套件的範例查詢,請按一下結構定義套件旁的「more_vert」more_vert動作選單,然後點選「Sample query」(範例查詢)。

gcloud

如要取得結構定義套件的詳細資料,請使用 gcloud bigtable schema-bundles describe 指令:

gcloud bigtable schema-bundles describe SCHEMA_BUNDLE_ID \
    --instance=INSTANCE_ID \
    --table=TABLE_ID

更改下列內容:

  • SCHEMA_BUNDLE_ID:結構定義組合的 ID。
  • INSTANCE_ID:執行個體的 ID。
  • TABLE_ID:資料表的 ID。

Java

如要取得結構定義套件的定義,請使用 getSchemaBundle 方法。這個方法會傳回包含結構定義定義的 SchemaBundle 物件。

以下範例說明如何取得結構定義套件,並將描述元集反序列化,以輸出結構定義的內容:

如要瞭解如何安裝及使用 Bigtable 的用戶端程式庫,請參閱「Bigtable 用戶端程式庫」。

如要向 Bigtable 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

SchemaBundle schemaBundle = null;
try {
  schemaBundle =
      adminClient.getSchemaBundle(
          "projects/"
              + projectId
              + "/instances/"
              + instanceId
              + "/tables/"
              + tableId
              + "/schemaBundles/"
              + schemaBundleId);
  // Deserialize and print the FileDescriptorSet
  DescriptorProtos.FileDescriptorSet fileDescriptorSet =
      DescriptorProtos.FileDescriptorSet.parseFrom(
          schemaBundle.getProtoSchema().getProtoDescriptors());

  System.out.println("--------- Deserialized FileDescriptorSet ---------");
  for (DescriptorProtos.FileDescriptorProto fileDescriptorProto :
      fileDescriptorSet.getFileList()) {
    System.out.println("File: " + fileDescriptorProto.getName());
    System.out.println("  Package: " + fileDescriptorProto.getPackage());
    for (DescriptorProtos.DescriptorProto messageType :
        fileDescriptorProto.getMessageTypeList()) {
      System.out.println("  Message: " + messageType.getName());
    }
  }
  System.out.println("--------------------------------------------------");
} catch (InvalidProtocolBufferException e) {
  System.err.println("Failed to parse FileDescriptorSet: " + e.getMessage());
} catch (NotFoundException e) {
  System.err.println(
      "Failed to retrieve metadata from a non-existent schema bundle: " + e.getMessage());
}

輸出結果會與下列內容相似:

--------- Deserialized FileDescriptorSet ---------
File: my_schema.proto
Package: my_package
Message: MyMessage
--------------------------------------------------

以表格列出結構定義套件

控制台

  1. 在 Google Cloud 控制台中,開啟 Bigtable 執行個體清單。

    開啟執行個體清單

  2. 從清單中選取執行個體。

  3. 在導覽窗格中,點選「Bigtable Studio」。

  4. 在「Explorer」窗格中,展開要查看的結構定義套件所屬的資料表。

  5. 展開「Schema Bundles」(結構定義套件)。

    表格中會顯示結構定義套裝組合清單。如果資料表沒有任何結構定義套件,系統就不會顯示「Schema Bundles」(結構定義套件) 清單。

gcloud

如要查看資料表的結構定義套件清單,請使用 gcloud bigtable schema-bundles list 指令:

gcloud bigtable schema-bundles list \
    --instance=INSTANCE_ID \
    --table=TABLE_ID

更改下列內容:

  • INSTANCE_ID:執行個體的 ID。
  • TABLE_ID:資料表的 ID。

Java

如要查看資料表中所有結構定義套件的清單,請使用 listSchemaBundles 方法。這個方法會傳回結構定義軟體包 ID 清單。

以下範例說明如何列出資料表中的結構定義套件:

如要瞭解如何安裝及使用 Bigtable 的用戶端程式庫,請參閱「Bigtable 用戶端程式庫」。

如要向 Bigtable 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

List<String> schemaBundleIds = new ArrayList<>();
try {
  ListSchemaBundlesRequest request =
      ListSchemaBundlesRequest.newBuilder()
          .setParent(
              "projects/" + projectId + "/instances/" + instanceId + "/tables/" + tableId)
          .build();
  for (SchemaBundle bundle : adminClient.listSchemaBundles(request).iterateAll()) {
    String id = SchemaBundleName.parse(bundle.getName()).getSchemaBundle();
    System.out.println(id);
    schemaBundleIds.add(id);
  }
} catch (NotFoundException e) {
  System.err.println(
      "Failed to list schema bundles from a non-existent table: " + e.getMessage());
}

輸出結果會與下列內容相似:

my-schema-bundle-1
my-schema-bundle-2

更新結構定義組合

更新結構定義套件時,Bigtable 會檢查新的描述元組合是否與現有組合回溯相容。如果 Bigtable 偵測到不相容,更新就會失敗,並顯示 FailedPrecondition 錯誤。建議您保留已刪除的欄位編號,以免重複使用。詳情請參閱 protobuf 說明文件中的「Proto 最佳做法」。

如果您確定不相容的變更安全無虞,且想強制更新,可以使用 gcloud CLI 的 --ignore-warnings 旗標。不過,如果結構定義套件正由連續 materialized view 或邏輯檢視表使用,則無法強制執行不相容的變更。檢視表會依據結構定義組合的訊息定義剖析及查詢資料,因此不相容的變更會破壞對邏輯檢視表的查詢,並導致連續 materialized view 在資料處理期間失敗。如要對檢視表參照的結構定義套件進行回溯不相容的變更,您必須先更新或刪除參照檢視表。

控制台

  1. 在 Google Cloud 控制台中,開啟 Bigtable 執行個體清單。

    開啟執行個體清單

  2. 從清單中選取執行個體。

  3. 在導覽窗格中,點選「Bigtable Studio」。

  4. 在「Explorer」窗格中,依序展開含有結構定義套件的資料表和「Schema Bundles」(結構定義套件)。

  5. 找出要更新的結構定義套件,按一下旁邊的 more_vert 動作選單,然後點選「Update」(更新)。

  6. 在「Update schema bundle」(更新結構定義套件) 對話方塊的「File Descriptor Set (.pb file)」(檔案描述元集 (.pb 檔案)) 欄位中,選取新的 protobuf 檔案描述元集。檔案大小不得超過 4 MB。

  7. 按一下 [儲存]。

gcloud

如要更新結構定義套件,改用其他描述元集,請使用 gcloud bigtable schema-bundles update 指令:

gcloud bigtable schema-bundles update SCHEMA_BUNDLE_ID \
    --instance=INSTANCE_ID \
    --table=TABLE_ID \
    --proto-descriptors-file=PROTO_DESCRIPTORS_FILE

更改下列內容:

  • SCHEMA_BUNDLE_ID:要更新的結構定義組合 ID。
  • INSTANCE_ID:包含結構定義套件的執行個體 ID。
  • TABLE_ID:包含結構定義套件的資料表 ID。
  • PROTO_DESCRIPTORS_FILE:新描述元集檔案的路徑。

選用:如要強制更新,即使有不相容的變更,請在指令中附加 --ignore-warnings 旗標。如果結構定義套件正由連續 materialized view 或邏輯檢視表使用,則無法強制執行不相容的變更。

Java

如要瞭解如何安裝及使用 Bigtable 的用戶端程式庫,請參閱「Bigtable 用戶端程式庫」。

如要向 Bigtable 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

try (InputStream in = getClass().getClassLoader().getResourceAsStream(PROTO_FILE_PATH)) {
  if (in == null) {
    throw new FileNotFoundException("Resource not found: " + PROTO_FILE_PATH);
  }
  SchemaBundle schemaBundleObj =
      SchemaBundle.newBuilder()
          .setName(
              "projects/"
                  + projectId
                  + "/instances/"
                  + instanceId
                  + "/tables/"
                  + tableId
                  + "/schemaBundles/"
                  + schemaBundleId)
          .setProtoSchema(
              ProtoSchema.newBuilder().setProtoDescriptors(ByteString.readFrom(in)).build())
          .build();
  UpdateSchemaBundleRequest request =
      UpdateSchemaBundleRequest.newBuilder()
          .setSchemaBundle(schemaBundleObj)
          .setUpdateMask(FieldMask.newBuilder().addPaths("proto_schema").build())
          .build();
  SchemaBundle schemaBundle = adminClient.updateSchemaBundleAsync(request).get();
  System.out.printf("Schema bundle: %s updated successfully%n", schemaBundle.getName());
} catch (Exception e) {
  System.err.println("Failed to modify schema bundle: " + e.getMessage());
}

刪除結構定義組合

如果結構定義組合正由連續 materialized view 或邏輯檢視表使用,則無法刪除。如果刪除套件,對邏輯檢視表的查詢就會失敗,且持續性 materialized view 也無法處理傳入的資料。如要刪除結構定義套件,請先刪除參照該套件的所有檢視表,或更新檢視表以移除參照。

控制台

  1. 在 Google Cloud 控制台中,開啟 Bigtable 執行個體清單。

    開啟執行個體清單

  2. 從清單中選取執行個體。

  3. 在導覽窗格中,點選「Bigtable Studio」。

  4. 在「Explorer」窗格中,依序展開含有結構定義套件的資料表和「Schema Bundles」(結構定義套件)。

  5. 找到要刪除的結構定義套件,按一下旁邊的 more_vert 動作選單,然後點選「Delete」(刪除)。

  6. 在確認對話方塊中點按「刪除」。

gcloud

如要刪除結構定義組合,請使用 gcloud bigtable schema-bundles delete 指令:

gcloud bigtable schema-bundles delete SCHEMA_BUNDLE_ID \
    --instance=INSTANCE_ID \
    --table=TABLE_ID

更改下列內容:

  • SCHEMA_BUNDLE_ID:要刪除的結構定義套件 ID。
  • INSTANCE_ID:包含結構定義套件的執行個體 ID。
  • TABLE_ID:包含結構定義套件的資料表 ID。

Java

如要瞭解如何安裝及使用 Bigtable 的用戶端程式庫,請參閱「Bigtable 用戶端程式庫」。

如要向 Bigtable 進行驗證,請設定應用程式預設憑證。詳情請參閱「為本機開發環境設定驗證機制」。

try {
  adminClient.deleteSchemaBundle(
      "projects/"
          + projectId
          + "/instances/"
          + instanceId
          + "/tables/"
          + tableId
          + "/schemaBundles/"
          + schemaBundleId);
  System.out.printf("SchemaBundle: %s deleted successfully%n", schemaBundleId);
} catch (NotFoundException e) {
  System.err.println("Failed to delete a non-existent schema bundle: " + e.getMessage());
}

限制

結構定義套件有下列限制:

  • 每個資料表最多可建立 10 個結構定義組合。這項限制適用於 protobuf 和 Avro 結構定義套件。
  • 結構定義套件中,序列化通訊協定緩衝區描述元的總大小不得超過 4 MB。只要套件總大小不超過此限制,套件中可包含的個別結構定義數量就沒有直接限制。

後續步驟