Criar e gerenciar esquemas protobuf

Este documento descreve como criar e realizar operações em pacotes de esquemas.

No Bigtable, é possível usar esquemas de buffer de protocolo (protobuf) para consultar campos individuais em mensagens protobuf armazenadas como bytes nas colunas. Para fazer isso, envie os esquemas em um pacote de esquemas, um recurso no nível da tabela que contém um ou mais esquemas protobuf.

O uso de pacotes de esquemas oferece os seguintes benefícios:

  • Economiza tempo e esforço: com buffers de protocolo, você define a estrutura de dados uma vez em um arquivo proto e usa o código-fonte gerado para gravar e ler os dados.
  • Melhora a consistência dos dados: ao usar um arquivo proto como uma única fonte confiável, você garante que todos os aplicativos e serviços estejam usando o mesmo modelo de dados.
  • Elimina a duplicação de dados: é possível usar buffers de protocolo em projetos definindo tipos de mensagens em arquivos proto que residem fora da base de código de um projeto específico.

O processo de uso de esquemas no Bigtable começa com os arquivos proto. Um arquivo proto é um arquivo de texto em que você define a estrutura dos dados. Use a ferramenta do compilador protobuf, também conhecida como protoc, para gerar um conjunto de descritores do arquivo protobuf, que é um esquema legível por máquina do arquivo proto. Em seguida, use esse conjunto de descritores para criar um pacote de esquemas.

Para exemplos de arquivos proto e os conjuntos de descritores correspondentes, consulte Dados de exemplo.

O diagrama a seguir mostra o processo de uso de esquemas no Bigtable:

O processo de uso de esquemas protobuf no Bigtable.
Figura 1. O processo de uso de esquemas protobuf no Bigtable (clique para ampliar).

É possível criar pacotes de esquemas usando a Google Cloud CLI. Depois de fazer o upload de um pacote de esquemas para o Bigtable, você pode consultar os dados usando o criador de consultas do Bigtable Studio, o GoogleSQL para Bigtable ou tabelas externas do Bigtable no BigQuery.

Antes de começar

Siga estas etapas se você planeja usar a CLI gcloud:

  1. Instale a Google Cloud CLI.
  2. Inicialize a CLI gcloud.

    gcloud init
    

Funções exigidas

Para receber as permissões necessárias para criar e gerenciar pacotes de esquemas, peça ao administrador para conceder a você o papel do IAM de Administrador do Bigtable (roles/bigtable.admin) na tabela.

Esse papel predefinido contém as permissões necessárias para que o Bigtable funcione com pacotes de esquemas. Para conferir as permissões exatas necessárias, expanda a seção Permissões necessárias:

Permissões necessárias

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

Essas permissões também podem ser concedidas com papéis personalizados ou outros papéis predefinidos.

Para mais informações sobre papéis e permissões do Bigtable, consulte Controle de acesso com o IAM.

Gerar um conjunto de descritores de arquivos protobuf

Antes de criar um pacote de esquemas, é necessário gerar um conjunto de descritores dos arquivos proto com a ferramenta do compilador protobuf.

  1. Para instalar o compilador, faça o download do pacote e siga as instruções no arquivo README.
  2. Execute o compilador:

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

    Substitua:

    • IMPORT_PATH: o diretório em que o compilador protoc pesquisa arquivos proto.
    • DESCRIPTOR_OUTPUT_LOCATION: o diretório em que o compilador protoc salva o conjunto de descritores gerado.
    • PATH_TO_PROTO: o caminho para o arquivo proto.

Por exemplo, para criar um conjunto de descritores chamado library.pb para o arquivo library.proto no diretório atual, use o seguinte comando:

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

Criar um pacote de esquemas

gcloud

Para criar um pacote de esquemas, use o gcloud bigtable schema-bundles create comando:

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

Substitua:

  • SCHEMA_BUNDLE_ID: um ID exclusivo para o novo pacote de esquemas que não pode conter nenhum caractere de ponto ('.').
  • INSTANCE_ID: o ID da instância em que o pacote de esquemas será criado.
  • TABLE_ID: o ID da tabela em que o pacote de esquemas será criado.
  • PROTO_DESCRIPTORS_FILE: o caminho para o conjunto de descritores gerado na etapa anterior.

Java

Para criar um pacote de esquemas, use o método createSchemaBundle:

Para saber como instalar e usar a biblioteca de cliente do Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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());
}

Acessar informações sobre pacotes de esquemas

Antes de acessar informações sobre pacotes de esquemas, é necessário ter uma tabela do Bigtable com pelo menos um pacote de esquemas. É possível acessar informações sobre pacotes de esquemas em uma tabela recuperando a definição de um único pacote de esquemas ou listando todos os pacotes de esquemas em uma tabela.

Receber a definição do pacote de esquemas

gcloud

Para receber detalhes sobre um pacote de esquemas, use o gcloud bigtable schema-bundles describe comando:

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

Substitua:

  • SCHEMA_BUNDLE_ID: o ID do pacote de esquemas.
  • INSTANCE_ID: o ID da instância.
  • TABLE_ID: o ID da tabela.

Java

Para receber a definição de um pacote de esquemas, use o método getSchemaBundle. Esse método retorna um objeto SchemaBundle que contém a definição do esquema.

O exemplo a seguir mostra como receber um pacote de esquemas e desserializar o conjunto de descritores para imprimir o conteúdo do esquema:

Para saber como instalar e usar a biblioteca de cliente do Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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());
}

O resultado será assim:

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

Listar pacotes de esquemas em uma tabela

gcloud

Para conferir uma lista de pacotes de esquemas de uma tabela, use o gcloud bigtable schema-bundles list comando:

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

Substitua:

  • INSTANCE_ID: o ID da instância.
  • TABLE_ID: o ID da tabela.

Java

Para conferir uma lista de todos os pacotes de esquemas em uma tabela, use o método listSchemaBundles. Esse método retorna uma lista de IDs de pacotes de esquemas.

O exemplo a seguir mostra como listar os pacotes de esquemas em uma tabela:

Para saber como instalar e usar a biblioteca de cliente do Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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());
}

O resultado será assim:

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

Atualizar um pacote de esquemas

Ao atualizar um pacote de esquemas, o Bigtable verifica se o novo conjunto de descritores é compatível com o conjunto atual. Se for incompatível, a atualização falhará com um erro FailedPrecondition. Recomendamos reservar números de campos excluídos para evitar a reutilização deles. Para mais informações, consulte Práticas recomendadas do Proto na documentação do protobuf.

Se você tiver certeza de que as mudanças incompatíveis são seguras e quiser forçar uma atualização, use a flag --ignore-warnings com a CLI gcloud.

gcloud

Para atualizar um pacote de esquemas para usar um conjunto de descritores diferente, use o gcloud bigtable schema-bundles update comando:

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

Substitua:

  • SCHEMA_BUNDLE_ID: o ID do pacote de esquemas a ser atualizado.
  • INSTANCE_ID: o ID da instância que contém o pacote de esquemas.
  • TABLE_ID: o ID da tabela que contém o pacote de esquemas.
  • PROTO_DESCRIPTORS_FILE: o caminho para o novo arquivo de conjunto de descritores.

Opcional: para forçar a atualização mesmo que haja mudanças incompatíveis, anexe o comando com a flag --ignore-warnings. Se uma visualização materializada contínua ou uma visualização lógica usar o pacote de esquemas, não force mudanças incompatíveis.

Java

Para saber como instalar e usar a biblioteca de cliente do Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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());
}

Excluir um pacote de esquemas

gcloud

Para excluir um pacote de esquemas, use o gcloud bigtable schema-bundles delete comando:

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

Substitua:

  • SCHEMA_BUNDLE_ID: o ID do pacote de esquemas a ser excluído.
  • INSTANCE_ID: o ID da instância que contém o pacote de esquemas.
  • TABLE_ID: o ID da tabela que contém o pacote de esquemas.

Se uma visualização materializada contínua ou uma visualização lógica usar o pacote de esquemas, não exclua o pacote.

Java

Para saber como instalar e usar a biblioteca de cliente do Bigtable, consulte Bibliotecas de cliente do Bigtable.

Para autenticar no Bigtable, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento 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());
}

Limitações

Os pacotes de esquemas têm as seguintes limitações:

  • É possível criar no máximo 10 pacotes de esquemas por tabela.
  • O tamanho total dos descritores de buffer de protocolo serializados em um pacote de esquemas não pode exceder 4 MB. Não há um limite direto para o número de esquemas individuais que podem ser incluídos em um pacote, desde que o tamanho total do pacote não exceda esse limite.
  • Se uma visualização materializada contínua ou uma visualização lógica usar o pacote de esquemas, não force mudanças incompatíveis nem exclua o pacote.

A seguir