Créer et gérer des schémas protobuf

Ce document explique comment créer des groupes de schémas et effectuer des opérations sur ces groupes.

Dans Bigtable, vous pouvez utiliser des schémas de tampon de protocole (protobuf) pour interroger des champs individuels dans des messages protobuf stockés sous forme d'octets dans vos colonnes. Pour ce faire, importez vos schémas dans un groupe de schémas, une ressource au niveau de la table qui contient un ou plusieurs de vos schémas protobuf.

L'utilisation de groupes de schémas présente les avantages suivants :

  • Gain de temps et d'efforts : avec les tampons de protocole, vous définissez votre structure de données une seule fois dans un fichier proto, puis vous utilisez le code source généré pour écrire et lire vos données.
  • Amélioration de la cohérence des données : en utilisant un fichier proto comme source unique de référence, vous pouvez vous assurer que toutes les applications et tous les services utilisent le même modèle de données.
  • Élimination de la duplication des données : vous pouvez utiliser des tampons de protocole dans plusieurs projets en définissant des types de messages dans des fichiers proto qui résident en dehors de la base de code d'un projet spécifique.

Le processus d'utilisation des schémas dans Bigtable commence par vos fichiers proto. Un fichier proto est un fichier texte dans lequel vous définissez la structure de vos données. Vous utilisez l'outil de compilation protobuf, également appelé protoc, pour générer un ensemble de descripteurs de fichier protobuf, qui est un schéma lisible par machine de votre fichier proto. Vous utilisez ensuite cet ensemble de descripteurs pour créer un groupe de schémas.

Pour obtenir des exemples de fichiers proto et de leurs ensembles de descripteurs correspondants, consultez la section Exemples de données.

Le diagramme suivant illustre le processus d'utilisation des schémas dans Bigtable :

Processus d'utilisation des schémas Protobuf dans Bigtable.
Figure 1. Processus d'utilisation des schémas protobuf dans Bigtable (cliquez pour agrandir).

Vous pouvez créer des groupes de schémas à l'aide de la Google Cloud CLI. Une fois que vous avez importé un groupe de schémas dans Bigtable, vous pouvez interroger vos données à l'aide du générateur de requêtes Bigtable Studio, de GoogleSQL pour Bigtable ou de tables externes Bigtable dans BigQuery.

Avant de commencer

Procédez comme suit si vous prévoyez d'utiliser la gcloud CLI :

  1. Installez Google Cloud CLI.
  2. Initialisez la gcloud CLI :

    gcloud init
    

Rôles requis

Pour obtenir les autorisations nécessaires pour créer et gérer des groupes de schémas, demandez à votre administrateur de vous accorder le rôle Identity and Access Management (IAM) Administrateur Bigtable (roles/bigtable.admin) sur la table.

Ce rôle prédéfini contient les autorisations dont Bigtable a besoin pour utiliser les groupes de schémas. Pour connaître les autorisations exactes requises, développez la section Autorisations requises :

Autorisations requises

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

Vous pouvez également obtenir ces autorisations avec des rôles personnalisés ou d'autres rôles prédéfinis.

Pour en savoir plus sur les rôles et les autorisations Bigtable, consultez la section Contrôle des accès avec IAM.

Générer un ensemble de descripteurs de fichier protobuf

Avant de pouvoir créer un groupe de schémas, vous devez générer un ensemble de descripteurs à partir de vos fichiers proto à l'aide de l'outil de compilation protobuf.

  1. Pour installer le compilateur, téléchargez le package et suivez les instructions du fichier README.
  2. Exécutez le compilateur :

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

    Remplacez les éléments suivants :

    • IMPORT_PATH: répertoire dans lequel le compilateur protoc recherche les fichiers proto.
    • DESCRIPTOR_OUTPUT_LOCATION: répertoire dans lequel le compilateur protoc enregistre l'ensemble de descripteurs généré.
    • PATH_TO_PROTO : chemin d'accès à votre fichier proto.

Par exemple, pour créer un ensemble de descripteurs nommé library.pb pour le fichier library.proto dans le répertoire actuel, vous pouvez utiliser la commande suivante :

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

Créer un groupe de schémas

gcloud

Pour créer un groupe de schémas, utilisez la gcloud bigtable schema-bundles create commande :

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

Remplacez les éléments suivants :

  • SCHEMA_BUNDLE_ID : ID unique du nouveau groupe de schémas qui ne peut pas contenir de point ('.').
  • INSTANCE_ID : ID de l'instance dans laquelle créer le groupe de schémas.
  • TABLE_ID : ID de la table dans laquelle créer le groupe de schémas.
  • PROTO_DESCRIPTORS_FILE : chemin d'accès à l'ensemble de descripteurs généré à l'étape précédente.

Java

Pour créer un groupe de schémas, utilisez la méthode createSchemaBundle :

Pour savoir comment installer et utiliser la bibliothèque cliente pour Bigtable, consultez la section Bibliothèques clientes Bigtable.

Pour vous authentifier auprès de Bigtable, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

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

Afficher des informations sur les groupes de schémas

Avant de pouvoir afficher des informations sur les groupes de schémas, vous devez disposer d'une table Bigtable contenant au moins un groupe de schémas. Vous pouvez obtenir des informations sur les groupes de schémas dans une table en récupérant la définition d'un seul groupe de schémas ou en listant tous les groupes de schémas d'une table.

Obtenir la définition d'un groupe de schémas

gcloud

Pour obtenir des informations sur un groupe de schémas, utilisez la gcloud bigtable schema-bundles describe commande :

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

Remplacez les éléments suivants :

  • SCHEMA_BUNDLE_ID : ID du groupe de schémas.
  • INSTANCE_ID : ID de l'instance.
  • TABLE_ID : ID de la table.

Java

Pour obtenir la définition d'un groupe de schémas, utilisez la méthode getSchemaBundle. Cette méthode renvoie un objet SchemaBundle qui contient la définition du schéma.

L'exemple suivant montre comment obtenir un groupe de schémas et désérialiser l'ensemble de descripteurs pour imprimer le contenu du schéma :

Pour savoir comment installer et utiliser la bibliothèque cliente pour Bigtable, consultez la section Bibliothèques clientes Bigtable.

Pour vous authentifier auprès de Bigtable, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

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

Le résultat ressemble à ce qui suit :

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

Lister les groupes de schémas dans une table

gcloud

Pour afficher la liste des groupes de schémas d'une table, utilisez la gcloud bigtable schema-bundles list commande :

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

Remplacez les éléments suivants :

  • INSTANCE_ID : ID de l'instance.
  • TABLE_ID : ID de la table.

Java

Pour afficher la liste de tous les groupes de schémas d'une table, utilisez la méthode listSchemaBundles. Cette méthode renvoie une liste d'ID de groupes de schémas.

L'exemple suivant montre comment lister les groupes de schémas dans une table :

Pour savoir comment installer et utiliser la bibliothèque cliente pour Bigtable, consultez la section Bibliothèques clientes Bigtable.

Pour vous authentifier auprès de Bigtable, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

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

Le résultat ressemble à ce qui suit :

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

Mettre à jour un groupe de schémas

Lorsque vous mettez à jour un groupe de schémas, Bigtable vérifie si le nouvel ensemble de descripteurs est rétrocompatible avec l'ensemble existant. S'il est incompatible, la mise à jour échoue avec une erreur FailedPrecondition. Nous vous recommandons de réserver les numéros de champ supprimés pour éviter leur réutilisation. Pour en savoir plus, consultez la section Bonnes pratiques proto dans la documentation protobuf.

Si vous êtes sûr que les modifications incompatibles sont sûres et que vous souhaitez forcer une mise à jour, vous pouvez utiliser l'option --ignore-warnings avec la gcloud CLI.

gcloud

Pour mettre à jour un groupe de schémas afin d'utiliser un autre ensemble de descripteurs, utilisez la gcloud bigtable schema-bundles update commande :

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

Remplacez les éléments suivants :

  • SCHEMA_BUNDLE_ID : ID du groupe de schémas à mettre à jour.
  • INSTANCE_ID : ID de l'instance contenant le groupe de schémas.
  • TABLE_ID : ID de la table contenant le groupe de schémas.
  • PROTO_DESCRIPTORS_FILE : chemin d'accès au nouveau fichier d'ensemble de descripteurs.

Facultatif : Pour forcer la mise à jour même en cas de modifications incompatibles, ajoutez l'option --ignore-warnings à la commande. Si une vue matérialisée continue ou une vue logique utilise le groupe de schémas, vous ne devez pas forcer les modifications incompatibles.

Java

Pour savoir comment installer et utiliser la bibliothèque cliente pour Bigtable, consultez la section Bibliothèques clientes Bigtable.

Pour vous authentifier auprès de Bigtable, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

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

Supprimer un groupe de schémas

gcloud

Pour supprimer un groupe de schémas, utilisez la gcloud bigtable schema-bundles delete commande :

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

Remplacez les éléments suivants :

  • SCHEMA_BUNDLE_ID : ID du groupe de schémas à supprimer.
  • INSTANCE_ID : ID de l'instance contenant le groupe de schémas.
  • TABLE_ID : ID de la table contenant le groupe de schémas.

Si une vue matérialisée continue ou une vue logique utilise le groupe de schémas, ne supprimez pas le groupe.

Java

Pour savoir comment installer et utiliser la bibliothèque cliente pour Bigtable, consultez la section Bibliothèques clientes Bigtable.

Pour vous authentifier auprès de Bigtable, configurez les identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

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

Limites

Les groupes de schémas présentent les limites suivantes :

  • Vous ne pouvez pas créer plus de 10 groupes de schémas par table.
  • La taille totale des descripteurs de tampon de protocole sérialisés dans un groupe de schémas ne peut pas dépasser 4 Mo. Il n'existe aucune limite directe quant au nombre de schémas individuels que vous pouvez inclure dans un groupe, tant que la taille totale du groupe ne dépasse pas cette limite.
  • Si une vue matérialisée continue ou une vue logique utilise le groupe de schémas, vous ne devez pas forcer les modifications incompatibles ni supprimer le groupe.

Étape suivante