建立及管理 protobuf 結構定義

本文說明如何建立及執行結構定義套裝組合作業。

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

使用結構定義組合具有下列優點:

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

在 Bigtable 中使用結構定義的程序,從 proto 檔案開始。proto 檔案是定義資料結構的文字檔。您可以使用 protobuf 編譯器工具 (也稱為 protoc),產生 protobuf 檔案描述元集,這是 proto 檔案的機器可讀取結構定義。接著,您可以使用這組描述元建立結構定義套裝組合。

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

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

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

您可以使用 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) 身分與存取權管理 (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

建立結構定義套裝組合

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:在上一個步驟中產生的描述元集路徑。

Java

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

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

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

try {
  InputStream in = getClass().getClassLoader().getResourceAsStream(PROTO_FILE_PATH);
  CreateSchemaBundleRequest request =
      CreateSchemaBundleRequest.of(tableId, schemaBundleId)
          .setProtoSchema(ByteString.readFrom(in));
  SchemaBundle schemaBundle = adminClient.createSchemaBundle(request);
  System.out.printf("Schema bundle: %s created successfully%n", schemaBundle.getId());
} catch (NotFoundException e) {
  System.err.println(
      "Failed to create a schema bundle from a non-existent table: " + e.getMessage());
} catch (IOException e) {
  throw new RuntimeException(e);
}

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

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

取得結構定義套件定義

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(tableId, schemaBundleId);
  // Deserialize and print the FileDescriptorSet
  DescriptorProtos.FileDescriptorSet fileDescriptorSet =
      DescriptorProtos.FileDescriptorSet.parseFrom(schemaBundle.getProtoSchema());

  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
--------------------------------------------------

以表格列出結構定義套裝組合

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 {
  schemaBundleIds = adminClient.listSchemaBundles(tableId);
  for (String schemaBundleId : schemaBundleIds) {
    System.out.println(schemaBundleId);
  }
} 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 會檢查新的描述元集是否與現有描述元集回溯相容。如果不相容,更新就會失敗,並顯示 FailedPrecondition 錯誤。建議您保留已刪除的欄位編號,避免重複使用。詳情請參閱 protobuf 說明文件中的「Proto 最佳做法」。

如果您確定不相容的變更安全無虞,並想強制更新,可以使用 gcloud CLI 的 --ignore-warnings 旗標。

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 旗標。

Java

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

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

try {
  InputStream in = getClass().getClassLoader().getResourceAsStream(PROTO_FILE_PATH);
  UpdateSchemaBundleRequest request =
      UpdateSchemaBundleRequest.of(tableId, schemaBundleId)
          .setProtoSchema(ByteString.readFrom(in));
  SchemaBundle schemaBundle = adminClient.updateSchemaBundle(request);
  System.out.printf("Schema bundle: %s updated successfully%n", schemaBundle.getId());
} catch (NotFoundException e) {
  System.err.println("Failed to modify a non-existent schema bundle: " + e.getMessage());
} catch (IOException e) {
  throw new RuntimeException(e);
}

刪除結構定義套件

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(tableId, 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 個結構定義套件。
  • 架構套件中序列化通訊協定緩衝區描述元的總大小不得超過 4 MB。只要套件總大小不超過這個限制,您可加入的個別結構定義數量就沒有直接限制。

後續步驟