protobuf スキーマを作成して管理する

このドキュメントでは、スキーマ バンドルを作成してオペレーションを実行する方法について説明します。

Bigtable では、プロトコル バッファ(protobuf)スキーマを使用して、列にバイトとして保存されている protobuf メッセージ内の個々のフィールドをクエリできます。これを行うには、スキーマをスキーマ バンドル(1 つ以上の protobuf スキーマを含むテーブルレベルのリソース)にアップロードします。

スキーマ バンドルを使用すると、次のメリットがあります。

  • 時間と労力を節約できる: プロトコル バッファを使用すると、proto ファイルでデータ構造を一度定義するだけで、生成されたソースコードを使用してデータの書き込みと読み取りを行うことができます。
  • データの整合性を向上させる: proto ファイルを唯一の信頼できる情報源として使用することで、すべてのアプリケーションとサービスが同じデータモデルを使用していることを確認できます。
  • データの重複を排除する: 特定のプロジェクトのコードベース外にある proto ファイルでメッセージ タイプを定義することで、プロジェクト全体でプロトコル バッファを使用できます。

Bigtable でスキーマを使用するプロセスは、proto ファイルから始まります。proto ファイルは、データの構造を定義するテキスト ファイルです。protoc とも呼ばれる protobuf コンパイラ ツールを使用して、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)Identity and Access Management(IAM)ロールを付与するよう管理者に依頼してください。

この事前定義ロールには、Bigtable がスキーマ バンドルを操作するために必要な権限が含まれています。必要とされる正確な権限については、「必要な権限」セクションを開いてご確認ください。

必要な権限

  • 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);
}

スキーマ バンドルに関する情報を表示する

スキーマ バンドルに関する情報を表示するには、少なくとも 1 つのスキーマ バンドルを含む 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 を超えることはできません。バンドルの合計サイズがこの上限を超えない限り、バンドルに含めることができる個々のスキーマの数に直接的な上限はありません。

次のステップ