Introdução à API BigQuery Storage Write

A API Storage Write do BigQuery é uma API de carregamento de dados unificada para o BigQuery. Combina o carregamento de streaming e o carregamento em lote numa única API de alto desempenho. Pode usar a API Storage Write para fazer stream de registos para o BigQuery em tempo real ou para processar em lote um número arbitrariamente grande de registos e confirmá-los numa única operação atómica.

Vantagens da utilização da API Storage Write

Semântica de entrega exatamente uma vez. A API Storage Write suporta a semântica de entrega exatamente uma vez através da utilização de desvios de streams. Ao contrário do método tabledata.insertAll, a API Storage Write nunca escreve duas mensagens com o mesmo desvio numa stream, se o cliente fornecer desvios de stream ao anexar registos.

Transações ao nível do fluxo. Pode escrever dados numa stream e confirmar os dados como uma única transação. Se a operação de confirmação falhar, pode tentar novamente a operação em segurança.

Transações em streams. Vários trabalhadores podem criar os seus próprios streams para processar dados de forma independente. Quando todos os trabalhadores terminarem, pode confirmar todas as streams como uma transação.

Protocolo eficiente. A API Storage Write é mais eficiente do que o método insertAll antigo porque usa streaming gRPC em vez de REST através de HTTP. A API Storage Write também suporta o formato binário protocol buffer e o formato tabular Apache Arrow, que são um formato de transferência mais eficiente do que o JSON. As solicitações de escrita são assíncronas com ordenação garantida.

Deteção de atualizações do esquema. Se o esquema da tabela subjacente for alterado enquanto o cliente está a fazer streaming, a API Storage Write notifica o cliente. O cliente pode decidir se quer restabelecer a ligação através do esquema atualizado ou continuar a escrever na ligação existente.

Custo inferior. A API Storage Write tem um custo significativamente inferior ao da API de streaming insertAll mais antiga. Além disso, pode carregar até 2 TiB por mês gratuitamente.

Autorizações necessárias

Para usar a API Storage Write, tem de ter autorizações bigquery.tables.updateData.

As seguintes funções de gestão de identidade e de acesso (IAM) predefinidas incluem autorizações bigquery.tables.updateData:

  • bigquery.dataEditor
  • bigquery.dataOwner
  • bigquery.admin

Para mais informações acerca das funções e autorizações do IAM no BigQuery, consulte o artigo Funções e autorizações predefinidas.

Âmbitos de autenticação

A utilização da API Storage Write requer um dos seguintes âmbitos do OAuth:

  • https://www.googleapis.com/auth/bigquery
  • https://www.googleapis.com/auth/cloud-platform
  • https://www.googleapis.com/auth/bigquery.insertdata

Para mais informações, consulte a Vista geral da autenticação.

Vista geral da API Storage Write

A abstração principal na API Storage Write é um stream. Um fluxo escreve dados numa tabela do BigQuery. Mais do que um stream pode escrever em simultâneo na mesma tabela.

Stream predefinida

A API Storage Write fornece uma stream predefinida, concebida para cenários de streaming em que tem dados a chegar continuamente. Tem as seguintes características:

  • Os dados escritos na stream predefinida estão imediatamente disponíveis para consulta.
  • A stream predefinida suporta a semântica de, pelo menos, uma vez.
  • Não precisa de criar explicitamente a stream predefinida.

Se estiver a migrar da API tabledata.insertall antiga, considere usar a stream predefinida. Tem uma semântica de escrita semelhante, com maior resiliência dos dados e menos restrições de escalabilidade.

Fluxo da API:

  1. AppendRows (loop)

Para mais informações e um exemplo de código, consulte o artigo Use a stream predefinida para a semântica pelo menos uma vez.

Streams criadas pela aplicação

Pode criar explicitamente uma stream se precisar de um dos seguintes comportamentos:

  • Semântica de escrita exatamente uma vez através da utilização de deslocamentos de streams.
  • Suporte para propriedades ACID adicionais.

Em geral, os streams criados por aplicações dão mais controlo sobre a funcionalidade ao custo de uma complexidade adicional.

Quando cria uma stream, especifica um tipo. O tipo controla quando os dados escritos no fluxo ficam visíveis no BigQuery para leitura.

Tipo pendente

No tipo pendente, os registos são colocados em buffer num estado pendente até confirmar a stream. Quando confirma uma stream, todos os dados pendentes ficam disponíveis para leitura. A confirmação é uma operação atómica. Use este tipo para cargas de trabalho em lote, como alternativa às tarefas de carregamento do BigQuery. Para mais informações, consulte o artigo Carregue dados em lote com a API Storage Write.

Fluxo da API:

  1. CreateWriteStream
  2. AppendRows (loop)
  3. FinalizeWriteStream
  4. BatchCommitWriteStreams

Tipo de compromisso

No tipo comprometido, os registos estão disponíveis para leitura imediatamente à medida que os escreve na stream. Use este tipo para cargas de trabalho de streaming que precisam de uma latência de leitura mínima. A stream predefinida usa um formulário do tipo committed, pelo menos, uma vez. Para mais informações, consulte o artigo Use o tipo committed para semântica exatamente uma vez.

Fluxo da API:

  1. CreateWriteStream
  2. AppendRows (loop)
  3. FinalizeWriteStream (opcional)

Tipo com memória intermédia

O tipo Buffered é um tipo avançado que, geralmente, não deve ser usado, exceto com o conetor Apache Beam BigQuery I/O. Se tiver pequenos lotes que quer garantir que aparecem juntos, use o tipo committed e envie cada lote num pedido. Neste tipo, são fornecidas confirmações ao nível da linha e os registos são armazenados em buffer até que as linhas sejam confirmadas através da atualização da stream.

Fluxo da API:

  1. CreateWriteStream
  2. AppendRowsFlushRows (loop)
  3. FinalizeWriteStream (opcional)

Selecionar um tipo

Use o seguinte fluxograma para ajudar a decidir que tipo é mais adequado para a sua carga de trabalho:

imagem

Detalhes da API

Considere o seguinte quando usar a API Storage Write:

AppendRows

O método AppendRows acrescenta um ou mais registos à stream. A primeira chamada para AppendRows tem de conter um nome da stream juntamente com o esquema de dados, especificado como um DescriptorProto. Em alternativa, pode adicionar um esquema de seta serializado na primeira chamada para AppendRows se estiver a carregar dados no formato Apache Arrow. Como prática recomendada, envie um lote de linhas em cada chamada AppendRows. Não envie uma linha de cada vez.

Processamento de buffers de protocolo

Os buffers de protocolo oferecem um mecanismo extensível, independente do idioma e da plataforma, para serializar dados estruturados de forma compatível com versões futuras e anteriores. São vantajosos porque oferecem armazenamento de dados compacto com análise rápida e eficiente. Para saber mais sobre os buffers de protocolo, consulte o artigo Vista geral dos buffers de protocolo.

Se for usar a API diretamente com uma mensagem de protocolo de buffer predefinida, a mensagem de protocolo de buffer não pode usar um especificador package, e todos os tipos aninhados ou de enumeração têm de ser definidos na mensagem raiz de nível superior. Não são permitidas referências a mensagens externas. Para ver um exemplo, consulte o ficheiro sample_data.proto.

Os clientes Java e Go suportam buffers de protocolo arbitrários, porque a biblioteca cliente normaliza o esquema do buffer de protocolo.

Processamento do Apache Arrow

Para enviar feedback ou pedir apoio técnico para esta funcionalidade, contacte bq-write-api-feedback@google.com. O Apache Arrow é um formato de colunas universal e um conjunto de ferramentas multilíngue para o processamento de dados. O Apache Arrow oferece um formato de memória orientado por colunas independente do idioma para dados simples e hierárquicos, organizado para operações analíticas eficientes em hardware moderno. Para saber mais sobre o Apache Arrow, consulte o artigo Apache Arrow. A API Storage Write suporta o carregamento do Arrow através de dados e esquemas do Arrow serializados na classe AppendRowsRequest. A biblioteca cliente Python inclui suporte incorporado para o carregamento do Apache Arrow. Outros idiomas podem exigir a chamada da API AppendRows não processada para carregar dados no formato Apache Arrow.

FinalizeWriteStream

O método FinalizeWriteStream finaliza a stream para que não possam ser anexados novos dados. Este método é obrigatório no tipo Pending e opcional nos tipos Committed e Buffered. A stream predefinida não suporta este método.

Processamento de erros

Se ocorrer um erro, o google.rpc.Status devolvido pode incluir um StorageError nos detalhes do erro. Reveja o StorageErrorCode para encontrar o tipo de erro específico. Para mais informações sobre o modelo de erros da API Google, consulte o artigo Erros.

Ligações

A API Storage Write é uma API gRPC que usa ligações bidirecionais. O método AppendRows cria uma ligação a uma stream. Pode abrir várias ligações na stream predefinida. Estas anexações são assíncronas, o que lhe permite enviar uma série de escritas em simultâneo. As mensagens de resposta em cada ligação bidirecional chegam pela mesma ordem em que os pedidos foram enviados.

As streams criadas pela aplicação só podem ter uma ligação ativa. Como prática recomendada, limite o número de ligações ativas e use uma ligação para o maior número possível de escritas de dados. Quando usa o fluxo predefinido em Java ou Go, pode usar a multiplexagem da API Storage Write para escrever em várias tabelas de destino com ligações partilhadas.

Geralmente, uma única ligação suporta, pelo menos, 1 MBps de débito. O limite superior depende de vários fatores, como a largura de banda da rede, o esquema dos dados e a carga do servidor. Quando uma ligação atinge o limite de débito, os pedidos recebidos podem ser rejeitados ou colocados em fila até que o número de pedidos em curso diminua. Se precisar de mais débito, crie mais ligações.

O BigQuery fecha a ligação gRPC se esta permanecer inativa durante demasiado tempo. Se isto acontecer, o código de resposta é HTTP 409. A ligação gRPC também pode ser fechada em caso de reinício do servidor ou por outros motivos. Se ocorrer um erro de ligação, crie uma nova ligação. As bibliotecas de cliente Java e Go voltam a estabelecer ligação automaticamente se a ligação for fechada.

Apoio técnico da biblioteca cliente

As bibliotecas cliente para a API Storage Write existem em várias linguagens de programação e expõem as construções da API baseadas em gRPC subjacentes. Esta API tira partido de funcionalidades avançadas, como o streaming bidirecional, que podem exigir trabalho de desenvolvimento adicional para serem suportadas. Para esse efeito, estão disponíveis várias abstrações de nível superior para esta API que simplificam essas interações e reduzem as preocupações dos programadores. Recomendamos que tire partido destas outras abstrações da biblioteca sempre que possível.

Esta secção fornece detalhes adicionais sobre os idiomas e as bibliotecas onde foram disponibilizadas aos programadores capacidades adicionais além da API gerada.

Para ver exemplos de código relacionados com a API Storage Write, consulte Todos os exemplos de código do BigQuery.

Cliente Java

A biblioteca cliente Java oferece dois objetos de gravação:

  • StreamWriter: aceita dados no formato de buffer de protocolo.

  • JsonStreamWriter: Aceita dados no formato JSON e converte-os em buffers de protocolo antes de os enviar através da rede. O JsonStreamWriter também suporta atualizações automáticas do esquema. Se o esquema da tabela for alterado, o escritor volta a ligar-se automaticamente ao novo esquema, o que permite ao cliente enviar dados através do novo esquema.

O modelo de programação é semelhante para ambos os escritores. A principal diferença é a forma como formata a carga útil.

O objeto writer gere uma ligação da API Storage Write. O objeto writer limpa automaticamente os pedidos, adiciona os cabeçalhos de encaminhamento regional aos pedidos e volta a estabelecer ligação após erros de ligação. Se usar a API gRPC diretamente, tem de processar estes detalhes.

Cliente Go

O cliente Go usa uma arquitetura cliente-servidor para codificar mensagens no formato de buffer de protocolo usando o proto2. Consulte a documentação do Go para ver detalhes sobre como usar o cliente Go, com código de exemplo.

Cliente Python

O cliente Python é um cliente de nível inferior que envolve a API gRPC. Para usar este cliente, tem de enviar os dados como buffers de protocolo, seguindo o fluxo da API para o tipo especificado.

Evite usar a geração de mensagens proto dinâmicas em Python, uma vez que o desempenho dessa biblioteca é inferior ao normal.

Para saber como usar buffers do protocolo com Python, leia o tutorial sobre os princípios básicos dos buffers do protocolo em Python.

Também pode usar o formato de carregamento do Apache Arrow como um protocolo alternativo para carregar dados através da API Storage Write. Para mais informações, consulte o artigo Use o formato Apache Arrow para carregar dados.

Cliente NodeJS

A biblioteca de cliente NodeJS aceita entradas JSON e oferece suporte de reconexão automática. Consulte a documentação para ver detalhes sobre como usar o cliente.

Indisponibilidade de identificadores

A repetição com retirada exponencial pode mitigar erros aleatórios e breves períodos de indisponibilidade do serviço, mas para evitar a eliminação de linhas durante uma indisponibilidade prolongada, é necessário ponderar mais. Em particular, se um cliente não conseguir inserir uma linha de forma persistente, o que deve fazer?

A resposta depende dos seus requisitos. Por exemplo, se o BigQuery estiver a ser usado para estatísticas operacionais em que algumas linhas em falta são aceitáveis, o cliente pode desistir após algumas novas tentativas e rejeitar os dados. Se, em alternativa, cada linha for crucial para a empresa, como no caso dos dados financeiros, tem de ter uma estratégia para persistir os dados até que possam ser inseridos mais tarde.

Uma forma comum de lidar com erros persistentes é publicar as linhas num tópico do Pub/Sub para avaliação posterior e possível inserção. Outro método comum é persistir temporariamente os dados no cliente. Ambos os métodos podem manter os clientes desbloqueados e, ao mesmo tempo, garantir que todas as linhas podem ser inseridas assim que a disponibilidade for restaurada.

Transmita para tabelas particionadas

A API Storage Write suporta o streaming de dados para tabelas particionadas.

Quando os dados são transmitidos, são inicialmente colocados na partição __UNPARTITIONED__. Depois de recolher dados não particionados suficientes, o BigQuery reparticiona os dados, colocando-os na partição adequada. No entanto, não existe um contrato de nível de serviço (SLA) que defina quanto tempo pode demorar para que esses dados sejam movidos para fora da partição __UNPARTITIONED__.

Para tabelas particionadas por tempo de carregamento e particionadas por colunas de unidades de tempo, os dados não particionados podem ser excluídos de uma consulta filtrando os valores NULL da partição __UNPARTITIONED__ através de uma das pseudocolunas (_PARTITIONTIME ou _PARTITIONDATE consoante o tipo de dados preferido).

Particionamento por tempo de ingestão

Quando faz streaming para uma tabela particionada por tempo de ingestão, a API Storage Write infere a partição de destino a partir da hora UTC atual do sistema.

Se estiver a transmitir dados para uma tabela particionada diariamente, pode substituir a inferência de data fornecendo um decorador de partição como parte do pedido. Inclua o decorator no parâmetro tableID. Por exemplo, pode fazer stream para a partição correspondente a 2025-06-01 para a tabela table1 usando o decorador de partição table1$20250601.

Quando faz streaming com um decorador de partições, pode fazer streaming para partições de 31 dias no passado a 16 dias no futuro. Para escrever em partições para datas fora destes limites, use um trabalho de carregamento ou de consulta, conforme descrito em Escreva dados numa partição específica.

O streaming com um decorador de partição só é suportado para tabelas particionadas diariamente com streams predefinidas, não para tabelas particionadas por hora, mês ou ano, nem para streams criadas por aplicações.

Partição de colunas de unidades de tempo

Quando faz streaming para uma tabela particionada por colunas de unidades de tempo, o BigQuery coloca automaticamente os dados na partição correta com base nos valores da coluna de partição DATE, DATETIME ou TIMESTAMP predefinida da tabela. Pode transmitir dados para uma tabela particionada por coluna de unidade de tempo se os dados referenciados pela coluna de partição estiverem entre 10 anos no passado e 1 ano no futuro.

Particionamento de intervalo de números inteiros

Quando faz stream para uma tabela particionada por intervalo de números inteiros, o BigQuery coloca automaticamente os dados na partição correta com base nos valores da coluna de particionamento INTEGER predefinida da tabela.

Plug-in de saída da API Storage Write do Fluent Bit

O plug-in de saída da API Storage Write do Fluent Bit automatiza o processo de carregamento de registos JSON no BigQuery, eliminando a necessidade de escrever código. Com este plugin, só tem de configurar um plugin de entrada compatível e configurar um ficheiro de configuração para começar a transmitir dados. O Fluent Bit é um processador e um encaminhador de registos de código aberto e multiplataforma que usa plug-ins de entrada e saída para processar diferentes tipos de origens e destinos de dados.

Este plugin suporta o seguinte:

  • Semântica de, pelo menos, uma vez com o tipo predefinido.
  • Semântica de exatamente uma vez com o tipo committed.
  • Dimensionamento dinâmico para streams predefinidas, quando é indicada contrapressão.

Métricas do projeto da API Storage Write

Para métricas de monitorização da carregamento de dados com a API Storage Write, use a vista INFORMATION_SCHEMA.WRITE_API_TIMELINE ou consulte as Trusted Cloud métricas.

Use a linguagem de manipulação de dados (DML) com dados transmitidos recentemente

Pode usar a linguagem de manipulação de dados (DML), como as declarações UPDATE, DELETE ou MERGE, para modificar linhas que foram escritas recentemente numa tabela do BigQuery pela API BigQuery Storage Write. As gravações recentes são as que ocorreram nos últimos 30 minutos.

Para mais informações sobre a utilização da DML para modificar os dados transmitidos, consulte o artigo Usar a linguagem de manipulação de dados.

Limitações

  • O suporte para a execução de declarações DML de mutação em dados transmitidos recentemente não se aplica aos dados transmitidos através da API de streaming insertAll.
  • A execução de declarações DML de mutação numa transação de várias declarações em dados transmitidos recentemente não é suportada.

Quotas da API Storage Write

Para informações sobre as quotas e os limites da API Storage Write, consulte o artigo Quotas e limites da API Storage Write do BigQuery.

Pode monitorizar as suas ligações simultâneas e a utilização da quota de débito na Trusted Cloud página Quotas da consola.

Calcular a taxa de transferência

Suponhamos que o seu objetivo é recolher registos de 100 milhões de pontos finais,criando 1500 registos por minuto. Em seguida, pode estimar a taxa de transferência como 100 million * 1,500 / 60 seconds = 2.5 GB per second. Tem de garantir antecipadamente que tem quota suficiente para publicar este débito.

Preços da API Storage Write

Para ver os preços, consulte o artigo Preços do carregamento de dados.

Exemplo de utilização

Suponhamos que existe um pipeline que processa dados de eventos a partir de registos de pontos finais. Os eventos são gerados continuamente e têm de estar disponíveis para consulta no BigQuery assim que possível. Uma vez que a atualidade dos dados é fundamental para este exemplo de utilização, a API Storage Write é a melhor escolha para carregar dados para o BigQuery. Uma arquitetura recomendada para manter estes pontos finais simples é enviar eventos para o Pub/Sub, a partir do qual são consumidos por um pipeline de streaming do Dataflow que faz streaming diretamente para o BigQuery.

Uma preocupação de fiabilidade principal para esta arquitetura é como lidar com a falha ao inserir um registo no BigQuery. Se cada registo for importante e não puder ser perdido, os dados têm de ser colocados em buffer antes de tentar inseri-los. Na arquitetura recomendada acima, o Pub/Sub pode desempenhar a função de um buffer com as respetivas capacidades de retenção de mensagens. O pipeline do Dataflow deve ser configurado para repetir inserções por stream do BigQuery com recuo exponencial truncado. Depois de a capacidade do Pub/Sub como buffer se esgotar, por exemplo, no caso de indisponibilidade prolongada do BigQuery ou de uma falha de rede, os dados têm de ser mantidos no cliente, e o cliente precisa de um mecanismo para retomar a inserção de registos mantidos assim que a disponibilidade for restaurada. Para mais informações sobre como lidar com esta situação, consulte a publicação no blogue Guia de fiabilidade do Google Pub/Sub.

Outro caso de falha a processar é o de um registo danificado. Um registo inválido é um registo rejeitado pelo BigQuery porque não é possível inserir o registo com um erro não repetível ou um registo que não foi inserido com êxito após o número máximo de novas tentativas. Ambos os tipos de registos devem ser armazenados numa "fila de mensagens rejeitadas" pelo pipeline do Dataflow para investigação adicional.

Se forem necessárias semânticas exatamente uma vez, crie uma stream de escrita do tipo committed com deslocamentos de registos fornecidos pelo cliente. Isto evita duplicados, uma vez que a operação de escrita só é realizada se o valor de deslocamento corresponder ao deslocamento de anexação seguinte. Se não fornecer um desvio, os registos são anexados ao fim atual da stream, e a repetição de uma anexação com falha pode fazer com que o registo apareça mais do que uma vez na stream.

Se não forem necessárias garantias de exatamente uma vez, a escrita na stream predefinida permite um débito mais elevado e também não conta para o limite de quota na criação de streams de escrita.

Estime a taxa de transferência da sua rede e certifique-se antecipadamente de que tem uma quota adequada para publicar a taxa de transferência.

Se a sua carga de trabalho estiver a gerar ou processar dados a uma taxa muito desigual, experimente suavizar os picos de carga no cliente e transmitir para o BigQuery com um débito constante. Isto pode simplificar o planeamento da capacidade. Se isso não for possível, certifique-se de que está preparado para processar erros 429 (recurso esgotado) se e quando o débito exceder a quota durante picos curtos.

Para ver um exemplo detalhado de como usar a API Storage Write, consulte o artigo Faça stream de dados com a API Storage Write.

O que se segue?