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:
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:
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:
CreateWriteStream
AppendRows
(loop)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:
CreateWriteStream
AppendRows
⇒FlushRows
(loop)FinalizeWriteStream
(opcional)
Selecionar um tipo
Use o seguinte fluxograma para ajudar a decidir que tipo é mais adequado para a sua carga de trabalho:
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. OJsonStreamWriter
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?
- Transmita dados através da API Storage Write
- Carregue dados em lote com a API Storage Write
- Tipos de dados de buffer de protocolo e Arrow suportados
- Práticas recomendadas da API Storage Write