Protobuf-Schemas erstellen und verwalten

In diesem Dokument wird beschrieben, wie Sie Schema-Bundles erstellen und Vorgänge damit ausführen.

In Bigtable können Sie Protokollpuffer (Protobuf) Schemas verwenden, um einzelne Felder in Protobuf-Nachrichten abzufragen, die als Byte in Ihren Spalten gespeichert sind. Dazu laden Sie Ihre Schemas in ein Schema-Bundle hoch. Das ist eine Ressource auf Tabellenebene, die ein oder mehrere Ihrer Protobuf-Schemas enthält.

Die Verwendung von Schema-Bundles bietet folgende Vorteile:

  • Zeit und Aufwand sparen: Mit Protokollpuffern definieren Sie Ihre Daten struktur einmal in einer Proto-Datei und verwenden dann den generierten Quellcode, um Ihre Daten zu schreiben und zu lesen.
  • Datenkonsistenz verbessern: Wenn Sie eine Proto-Datei als einzige Quelle der Wahrheit verwenden, können Sie sicherstellen, dass alle Anwendungen und Dienste dasselbe Datenmodell verwenden.
  • Datenduplizierung vermeiden: Sie können Protokollpuffer projektübergreifend verwenden, indem Sie Nachrichtentypen in Proto-Dateien definieren, die sich außerhalb der Codebasis eines bestimmten Projekts befinden.

Der Prozess der Verwendung von Schemas in Bigtable beginnt mit Ihren Proto-Dateien. Eine Proto-Datei ist eine Textdatei, in der Sie die Struktur Ihrer Daten definieren. Mit dem Protobuf-Compiler-Tool, auch protoc genannt, generieren Sie einen Satz von Protobuf-Dateideskriptoren, ein maschinenlesbares Schema Ihrer Proto-Datei. Anschließend verwenden Sie diesen Satz von Deskriptoren, um ein Schema-Bundle zu erstellen.

Beispiele für Proto-Dateien und die entsprechenden Sätze von Deskriptoren finden Sie unter Beispieldaten.

Das folgende Diagramm zeigt den Prozess der Verwendung von Schemas in Bigtable:

Der Prozess der Verwendung von Protobuf-Schemas in Bigtable.
Abbildung 1. Der Prozess der Verwendung von Protobuf-Schemas in Bigtable (zum Vergrößern klicken).

Sie können Schema-Bundles mit der Google Cloud CLI erstellen. Nachdem Sie ein Schema-Bundle in Bigtable hochgeladen haben, können Sie Ihre Daten mit dem Abfrage-Tool von Bigtable Studio, GoogleSQL für Bigtable oder externen Bigtable-Tabellen in BigQuery abfragen.

Hinweis

Führen Sie die folgenden Schritte aus, wenn Sie die gcloud CLI verwenden möchten:

  1. Installieren Sie die Google Cloud CLI.
  2. Initialisieren Sie die gcloud CLI:

    gcloud init
    

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen für die Tabelle die IAM-Rolle Bigtable Admin (roles/bigtable.admin) zuzuweisen, damit Sie die Berechtigungen erhalten, die Sie zum Erstellen und Verwalten von Schema-Bundles benötigen.

Diese vordefinierte Rolle enthält die Berechtigungen, die Bigtable für die Arbeit mit Schema-Bundles benötigt. Maximieren Sie den Abschnitt Erforderliche Berechtigungen, um die genau erforderlichen Berechtigungen aufzurufen:

Erforderliche Berechtigungen

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

Sie können diese Berechtigungen auch mit benutzerdefinierten Rollen oder anderen vordefinierten Rollen erhalten.

Weitere Informationen zu Bigtable-Rollen und ‑Berechtigungen finden Sie unter Zugriffssteuerung mit IAM.

Satz von Protobuf-Dateideskriptoren generieren

Bevor Sie ein Schema-Bundle erstellen können, müssen Sie mit dem Protobuf-Compiler-Tool einen Satz von Deskriptoren aus Ihren Proto-Dateien generieren.

  1. Laden Sie das Paket herunter und folgen Sie der Anleitung in der Datei README, um den Compiler zu installieren.
  2. Führen Sie den Compiler aus:

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

    Ersetzen Sie Folgendes:

    • IMPORT_PATH: das Verzeichnis, in dem der protoc-Compiler nach Proto-Dateien sucht.
    • DESCRIPTOR_OUTPUT_LOCATION: das Verzeichnis, in dem der protoc-Compiler den generierten Satz von Deskriptoren speichert.
    • PATH_TO_PROTO: der Pfad zu Ihrer Proto-Datei.

Wenn Sie beispielsweise einen Satz von Deskriptoren mit dem Namen library.pb für die Datei library.proto im aktuellen Verzeichnis erstellen möchten, können Sie den folgenden Befehl verwenden:

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

Schema-Bundle erstellen

gcloud

Verwenden Sie den gcloud bigtable schema-bundles create Befehl, um ein Schema-Bundle zu erstellen:

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

Ersetzen Sie Folgendes:

  • SCHEMA_BUNDLE_ID: eine eindeutige ID für das neue Schema-Bundle, die keinen Punkt ('.') enthalten darf.
  • INSTANCE_ID: die ID der Instanz, in der das Schema-Bundle erstellt werden soll.
  • TABLE_ID: die ID der Tabelle, in der das Schema-Bundle erstellt werden soll.
  • PROTO_DESCRIPTORS_FILE: der Pfad zum Satz von Deskriptoren, der im vorherigen Schritt generiert wurde.

Java

Verwenden Sie die Methode createSchemaBundle, um ein Schema-Bundle zu erstellen:

Informationen zum Installieren und Verwenden der Clientbibliothek für Bigtable finden Sie unter Bigtable-Clientbibliotheken.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Bigtable zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Informationen zu Schema-Bundles ansehen

Bevor Sie Informationen zu Schema-Bundles ansehen können, benötigen Sie eine Bigtable-Tabelle mit mindestens einem Schema-Bundle. Sie können Informationen zu Schema-Bundles in einer Tabelle abrufen, indem Sie die Definition eines einzelnen Schema-Bundles abrufen oder alle Schema-Bundles in einer Tabelle auflisten.

Definition des Schema-Bundles abrufen

gcloud

Verwenden Sie den gcloud bigtable schema-bundles describe Befehl, um Details zu einem Schema-Bundle abzurufen:

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

Ersetzen Sie Folgendes:

  • SCHEMA_BUNDLE_ID: die ID des Schema-Bundles.
  • INSTANCE_ID: die ID der Instanz.
  • TABLE_ID: die ID der Tabelle.

Java

Verwenden Sie die Methode getSchemaBundle, um die Definition eines Schema-Bundles abzurufen. Diese Methode gibt ein SchemaBundle-Objekt zurück, das die Schemadefinition enthält.

Das folgende Beispiel zeigt, wie Sie ein Schema-Bundle abrufen und den Satz von Deskriptoren deserialisieren, um den Inhalt des Schemas auszugeben:

Informationen zum Installieren und Verwenden der Clientbibliothek für Bigtable finden Sie unter Bigtable-Clientbibliotheken.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Bigtable zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Die Ausgabe sieht etwa so aus:

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

Schema-Bundles in einer Tabelle auflisten

gcloud

Verwenden Sie den gcloud bigtable schema-bundles list Befehl, um eine Liste der Schema-Bundles für eine Tabelle aufzurufen:

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

Ersetzen Sie Folgendes:

  • INSTANCE_ID: die ID der Instanz.
  • TABLE_ID: die ID der Tabelle.

Java

Verwenden Sie die Methode listSchemaBundles, um eine Liste aller Schema-Bundles in einer Tabelle aufzurufen. Diese Methode gibt eine Liste von Schema-Bundle-IDs zurück.

Das folgende Beispiel zeigt, wie Sie die Schema-Bundles in einer Tabelle auflisten:

Informationen zum Installieren und Verwenden der Clientbibliothek für Bigtable finden Sie unter Bigtable-Clientbibliotheken.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Bigtable zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Die Ausgabe sieht etwa so aus:

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

Schema-Bundle aktualisieren

Wenn Sie ein Schema-Bundle aktualisieren, prüft Bigtable, ob der neue Satz von Deskriptoren abwärtskompatibel mit dem vorhandenen ist. Wenn er nicht kompatibel ist, schlägt die Aktualisierung mit einem FailedPrecondition-Fehler fehl. Wir empfehlen, gelöschte Feldnummern zu reservieren, um ihre Wiederverwendung zu verhindern. Weitere Informationen finden Sie in der Protobuf-Dokumentation unter Best Practices für Proto-Dateien.

Wenn Sie sicher sind, dass die inkompatiblen Änderungen sicher sind und eine Aktualisierung erzwingen möchten, können Sie das Flag --ignore-warnings mit der gcloud CLI verwenden.

gcloud

Verwenden Sie den gcloud bigtable schema-bundles update Befehl, um ein Schema-Bundle zu aktualisieren und einen anderen Satz von Deskriptoren zu verwenden:

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

Ersetzen Sie Folgendes:

  • SCHEMA_BUNDLE_ID: die ID des Schema-Bundles, das aktualisiert werden soll.
  • INSTANCE_ID: die ID der Instanz, die das Schema-Bundle enthält.
  • TABLE_ID: die ID der Tabelle, die das Schema-Bundle enthält.
  • PROTO_DESCRIPTORS_FILE: der Pfad zur neuen Datei mit dem Satz von Deskriptoren.

Optional: Wenn Sie die Aktualisierung erzwingen möchten, auch wenn inkompatible Änderungen vorhanden sind, fügen Sie dem Befehl das Flag --ignore-warnings hinzu. Wenn entweder eine kontinuierliche materialisierte Ansicht oder eine logische Ansicht das Schema-Bundle verwendet, dürfen Sie keine inkompatiblen Änderungen erzwingen.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Bigtable finden Sie unter Bigtable-Clientbibliotheken.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Bigtable zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Schema-Bundle löschen

gcloud

Verwenden Sie den gcloud bigtable schema-bundles delete Befehl, um ein Schema-Bundle zu löschen:

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

Ersetzen Sie Folgendes:

  • SCHEMA_BUNDLE_ID: die ID des Schema-Bundles, das gelöscht werden soll.
  • INSTANCE_ID: die ID der Instanz, die das Schema-Bundle enthält.
  • TABLE_ID: die ID der Tabelle, die das Schema-Bundle enthält.

Wenn entweder eine kontinuierliche materialisierte Ansicht oder eine logische Ansicht das Schema-Bundle verwendet, löschen Sie das Bundle nicht.

Java

Informationen zum Installieren und Verwenden der Clientbibliothek für Bigtable finden Sie unter Bigtable-Clientbibliotheken.

Richten Sie die Standardanmeldedaten für Anwendungen ein, um sich bei Bigtable zu authentifizieren. Weitere Informationen finden Sie unter Authentifizierung für eine lokale Entwicklungsumgebung einrichten.

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

Beschränkungen

Für Schema-Bundles gelten die folgenden Einschränkungen:

  • Sie können maximal 10 Schema-Bundles pro Tabelle erstellen.
  • Die Gesamtgröße der serialisierten Protokollzwischenspeicher-Deskriptoren in einem Schema-Bundle darf 4 MB nicht überschreiten. Es gibt keine direkte Beschränkung für die Anzahl der einzelnen Schemas, die Sie in ein Bundle aufnehmen können, solange die Gesamtgröße des Bundles dieses Limit nicht überschreitet.
  • Wenn entweder eine kontinuierliche materialisierte Ansicht oder eine logische Ansicht das Schema-Bundle verwendet, dürfen Sie keine inkompatiblen Änderungen erzwingen oder das Bundle löschen.

Nächste Schritte