Práticas recomendadas da API BigQuery Storage Write
Este documento apresenta práticas recomendadas para usar a API BigQuery Storage Write. Antes de ler este documento, leia o artigo Vista geral da API Storage Write do BigQuery.
Limite a taxa de criação de streams
Antes de criar uma stream, pondere se pode usar a stream predefinida. Para cenários de streaming, a stream predefinida tem menos limitações de quota e pode ser dimensionada melhor do que usar streams criadas pela aplicação. Se usar uma stream criada pela aplicação, certifique-se de que usa o débito máximo em cada stream antes de criar streams adicionais. Por exemplo, use escritas assíncronas.
Para streams criadas por aplicações, evite chamar CreateWriteStream
com uma frequência elevada. Geralmente, se exceder as 40 a 50 chamadas por segundo, a latência das chamadas da API aumenta substancialmente (>25 s). Certifique-se de que a sua aplicação pode aceitar um início a frio e aumentar gradualmente o número de streams, bem como limitar a taxa de chamadas CreateWriteStream
. Também pode definir um prazo mais longo para aguardar a conclusão da chamada, para que não falhe com um erro DeadlineExceeded
. Também existe uma quota a longo prazo sobre a taxa máxima de chamadas CreateWriteStream
. A criação de streams é um processo que requer muitos recursos, pelo que reduzir a taxa de criação de streams e usar totalmente as streams existentes é a melhor forma de não exceder este limite.
Gestão do conjunto de ligações
O método AppendRows
cria uma ligação bidirecional a uma stream. Pode abrir várias ligações na stream predefinida, mas apenas uma ligação ativa nas streams criadas pela aplicação.
Quando usa a stream predefinida, pode usar a multiplexagem da API Storage Write para escrever em várias tabelas de destino com ligações partilhadas. A multiplexagem agrupa as ligações para um melhor débito e utilização dos recursos. Se o seu fluxo de trabalho tiver mais de 20 ligações simultâneas, recomendamos que use a multiplexagem. A multiplexagem está disponível em Java e Go. Para ver detalhes da implementação em Java, consulte o artigo Use a multiplexagem. Para ver detalhes de implementação do Go, consulte o artigo Partilha de ligações (multiplexagem). Se usar o conetor Beam com semântica de, pelo menos, uma vez, pode ativar a multiplexagem através de UseStorageApiConnectionPool. O conetor do Dataproc Spark tem a multiplexagem ativada por predefinição.
Para um melhor desempenho, use uma ligação para o maior número possível de escritas de dados. Não use uma ligação apenas para uma única gravação nem abra e feche streams para muitas gravações pequenas.
Existe uma quota para o número de ligações simultâneas que podem ser abertas ao mesmo tempo por projeto. Acima do limite, as chamadas para AppendRows
falham.
No entanto, a quota de ligações simultâneas pode ser aumentada e, normalmente, não deve ser um fator limitativo para o dimensionamento.
Cada chamada para AppendRows
cria um novo objeto de gravação de dados. Assim, quando usa uma stream criada pela aplicação, o número de associações corresponde ao número de streams que foram criadas. 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, mas pode exceder 10 MBps.
Também existe uma quota no débito total por projeto. Isto representa os bytes por segundo em todas as ligações que fluem através do serviço da API Storage Write. Se o seu projeto exceder esta quota, pode pedir um ajuste da quota. Normalmente, isto envolve aumentar as quotas associadas, como a quota de ligações concorrentes, numa proporção igual.
Faça a gestão dos desvios de streams para alcançar uma semântica exatamente uma vez
A API Storage Write só permite escritas no final atual da stream, que se move à medida que os dados são anexados. A posição atual na stream é especificada como um desvio a partir do início da stream.
Quando escreve numa stream criada pela aplicação, pode especificar o deslocamento da stream para alcançar uma semântica de escrita exatamente uma vez.
Quando especifica um desvio, a operação de escrita é idempotente, o que torna seguro repetir devido a erros de rede ou falta de resposta do servidor. Resolva os seguintes erros relacionados com desvios:
ALREADY_EXISTS
(StorageErrorCode.OFFSET_ALREADY_EXISTS
): a linha já foi escrita. Pode ignorar este erro com segurança.OUT_OF_RANGE
(StorageErrorCode.OFFSET_OUT_OF_RANGE
): falhou uma operação de escrita anterior. Tente novamente a partir da última gravação bem-sucedida.
Tenha em atenção que estes erros também podem ocorrer se definir o valor de desvio errado, pelo que tem de gerir os desvios cuidadosamente.
Antes de usar os desvios de stream, pondere se precisa de uma semântica exatamente uma vez. Por exemplo, se o seu pipeline de dados a montante apenas garantir escritas, pelo menos, uma vez, ou se puder detetar facilmente duplicados após a ingestão de dados, pode não precisar de escritas exatamente uma vez. Nesse caso, recomendamos a utilização da stream predefinida, que não requer o controlo dos desvios de linhas.
Não bloquear chamadas com o número AppendRows
O método AppendRows
é assíncrono. Pode enviar uma série de escritas sem bloquear uma resposta para cada escrita individualmente. As mensagens de resposta na ligação bidirecional chegam pela mesma ordem em que os pedidos foram colocados em fila.
Para o débito mais elevado, chame AppendRows
sem bloquear para aguardar a resposta.
Faça a gestão das atualizações do esquema
Para cenários de streaming de dados, os esquemas de tabelas são normalmente geridos fora da pipeline de streaming. É comum o esquema evoluir ao longo do tempo, por exemplo, adicionando novos campos anuláveis. Um pipeline robusto tem de processar atualizações de esquemas fora da banda.
A API Storage Write suporta esquemas de tabelas da seguinte forma:
- O primeiro pedido de gravação inclui o esquema.
- Envia cada linha de dados como um protocolo de buffer binário. O BigQuery mapeia os dados para o esquema.
- Pode omitir campos anuláveis, mas não pode incluir campos que não estejam presentes no esquema atual. Se enviar linhas com campos adicionais, a API Storage Write devolve um
StorageError
comStorageErrorCode.SCHEMA_MISMATCH_EXTRA_FIELD
.
Se quiser enviar novos campos no payload, deve primeiro atualizar o esquema da tabela no BigQuery. A API Storage Write deteta alterações ao esquema após um curto período, da ordem dos minutos. Quando a API Storage Write deteta a alteração do esquema, a mensagem de resposta AppendRowsResponse
contém um objeto TableSchema
que descreve o novo esquema.
Para enviar dados através do esquema atualizado, tem de fechar as ligações existentes e abrir novas ligações com o novo esquema.
Cliente Java. A biblioteca cliente Java oferece algumas funcionalidades adicionais para atualizações de esquemas através da classe JsonStreamWriter
. Após uma atualização do esquema, o JsonStreamWriter
volta a estabelecer ligação automaticamente com o esquema atualizado. Não precisa de fechar e voltar a abrir explicitamente a ligação.
Para verificar as alterações ao esquema de forma programática, chame AppendRowsResponse.hasUpdatedSchema
após a conclusão do método append
.
Também pode configurar o JsonStreamWriter
para ignorar campos desconhecidos nos dados de entrada. Para definir este comportamento, chame setIgnoreUnknownFields
. Este comportamento é semelhante à opção ignoreUnknownValues
quando usa a API tabledata.insertAll
antiga. No entanto, pode levar à perda de dados não intencional, porque os campos desconhecidos são
ignorados silenciosamente.