Solicitações em lote
Como resultado da suspensão de uso de endpoints HTTP em lote globais, as solicitações HTTP em lote que segmentam apenas APIs do BigQuery deixarão de funcionar em 1 de junho de 2021. Se o aplicativo estiver enviando solicitações HTTP em lote, substitua as solicitações HTTP em lote por solicitações HTTP individuais antes de 1 de junho de 2021.
Para informações sobre a suspensão de uso, consulte a seção de perguntas frequentes a seguir. Para ver a documentação sobre como fazer solicitações em lote HTTP, consulte Solicitações em lote.
Perguntas frequentes sobre a suspensão de uso da API HTTP em lote do BigQuery
Por que as solicitações HTTP em lote do BigQuery foram descontinuadas?
O suporte para endpoints de lote HTTP globais foi baseado em uma arquitetura que usa um único proxy compartilhado para receber solicitações para todas as APIs. À medida que o Google mudou para uma arquitetura mais distribuída e de alto desempenho, em que as solicitações vão diretamente para o servidor da API apropriada, não seria mais possível oferecer suporte a esses endpoints globais.
A remoção de solicitações HTTP em lote do BigQuery é a próxima etapa. O serviço do BigQuery também é distribuído. Métodos de QPS altos são processados por back-ends dedicados. Todas as regiões são isoladas, mas as solicitações HTTP em lote podem causar fanouts de solicitação entre regiões. Isso torna o agrupamento ineficiente e pode resultar em maior latência de processamento, o que é o contrário da meta original de suporte a solicitações HTTP em lote.
O que especificamente foi descontinuado?
Os seguintes métodos de solicitação em lote da interação com as APIs do BigQuery não funcionarão mais:
- API REST
batchPath
especificada no documento de descoberta de API - Classe
BatchRequest
da biblioteca de cliente do Java - Objeto
Batch
da biblioteca de cliente JavaScript - Objeto
BatchRequest
da biblioteca de cliente em C# - Outras bibliotecas de cliente: classe
BatchRequest
Como faço a migração?
A maioria dos usuários do BigQuery não usa solicitações HTTP em lote. Se você ainda estiver usando solicitações em lote, siga os exemplos a seguir para substituir solicitações HTTP em lote por solicitações HTTP individuais.
REST
Envie solicitações HTTP individuais conforme documentado na seção de referência da API do BigQuery.
Não combine suas solicitações em lotes usando o caminho /batch/v2/bigquery
.
JavaScript
Se estiver usando JavaScript, comece com um bloco de código como este:
// Notice that the outer batch request contains inner API requests // for two different APIs. // Request to urlshortener API request1 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}); // Request to zoo API request2 = gapi.client.zoo.animals.list(); // Request to urlshortener API request3 = gapi.client.urlshortener.url.get({"shortUrl": "https://goo.gl/XYFuPH"}); // Request to zoo API request4 = gapi.client.zoo.animal().get({"name": "giraffe"}); // Creating a batch request object batchRequest = gapi.client.newBatch(); // adding the 4 batch requests batchRequest.add(request1); batchRequest.add(request2); batchRequest.add(request3); batchRequest.add(request4); // print the batch request batchRequest.then(x=>console.log(x))
Substitua o bloco de código anterior por um com a seguinte aparência:
// Request to urlshortener API request1 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}); // Request to zoo API request2 = gapi.client.zoo.animals.list(); // Request to urlshortener API request3 = gapi.client.urlshortener.url.get({"shortUrl": "http://goo.gl/fbsS"}) // Request to zoo API request4 = gapi.client.zoo.animals.list(); // print the 4 individual requests Promise.all([request1, request2, request3, request4]) .then(x=>console.log(x));
Python
Se estiver usando o Python, você começará com um bloco de código como este:
from apiclient.http import BatchHttpRequest def insert_animal(request_id, response, exception): if exception is not None: # Do something with the exception pass else: # Do something with the response pass service = build('farm', 'v2') batch = service.new_batch_http_request(callback=insert_animal) batch.add(service.animals().insert(name="sheep")) batch.add(service.animals().insert(name="pig")) batch.add(service.animals().insert(name="llama")) batch.execute(http=http)
Substitua o bloco de código anterior por um com a seguinte aparência:
# import a new API to create a thread pool from concurrent.futures import ThreadPoolExecutor as PoolExecutor def run_it(request): print(request.execute()) service = build('farm', 'v2') request1 = service.animals().insert(name="sheep") request2 = service.animals().insert(name="pig") request3 = service.animals().insert(name="llama") with PoolExecutor(max_workers=4) as executor: for _ in executor.map(run_it,[request1, request2, request3]): pass
Outros idiomas
Assim como nos exemplos anteriores, substitua as chamadas BatchRequest
por solicitações individuais.
Receber suporte para a migração
Para ajuda com a migração, faça perguntas no Stack Overflow. Os engenheiros do Google monitoram e respondem às perguntas com a tag google-bigquery. Use essa tag ao fazer perguntas. Nosso objetivo é responder a todas as perguntas dentro de um período razoável de tempo.
Solicitações em lote
Este documento mostra como reunir chamadas à API em lote para reduzir o número de conexões HTTP que seu cliente tem que fazer.
Neste documento, falamos especificamente sobre como fazer uma solicitação em lote enviando uma solicitação HTTP. Se, em vez disso, você estiver usando uma biblioteca de cliente do Google para fazer uma solicitação em lote, consulte a documentação da biblioteca de cliente (em inglês).
Visão geral
Cada conexão HTTP feita pelo cliente resulta em certa quantidade de overhead. A API BigQuery é compatível com o agrupamento em lote a fim de permitir que seu cliente faça várias chamadas à API em uma única solicitação HTTP.
Exemplos de situações em que convém usar operações em lote:
- Você acabou de começar a usar a API e tem muitos dados para fazer upload.
- Um usuário fez alterações nos dados enquanto eu aplicativo estava off-line (desconectado da Internet), então seu aplicativo precisa sincronizar os dados locais com o servidor enviando várias atualizações e exclusões.
Em cada caso, em vez de enviar cada chamada separadamente, você pode agrupá-las em uma única solicitação HTTP. Todas as solicitações internas precisam ser encaminhadas para a mesma API do Google.
O limite é de 1.000 chamadas em uma única solicitação em lote. Se precisar fazer mais chamadas, use várias solicitações em lote.
Observação: o sistema em lote da API do Google BigQuery usa a mesma sintaxe do sistema de processamento em lote do OData (em inglês), mas a semântica é diferente.
Detalhes do lote
Uma solicitação em lote consiste em várias chamadas de API combinadas em uma solicitação HTTP, que pode ser enviada ao batchPath
especificado no documento de descoberta de API (em inglês). O caminho padrão é /batch/api_name/api_version
. Nesta seção, você verá a descrição em detalhes da sintaxe do lote e, em seguida, um exemplo.
Observação: um conjunto de n solicitações em lote é contabilizado no seu limite de uso, como n solicitações, e não como uma única solicitação. A solicitação em lote é separada em um conjunto de solicitações antes do processamento.
Formato de uma solicitação em lote
Uma solicitação em lote é uma única solicitação HTTP padrão que contém várias chamadas à API BigQuery usando o tipo de conteúdo multipart/mixed
. Dentro dessa solicitação HTTP principal, cada parte contém uma solicitação HTTP aninhada.
Cada parte começa com seu próprio cabeçalho HTTP Content-Type: application/http
. Também é possível ter um cabeçalho Content-ID
opcional. No entanto, os cabeçalhos das partes estão lá apenas para marcar o início da parte. Eles são separados da solicitação aninhada. Depois que o servidor desencapsular a solicitação em solicitações separadas, os cabeçalhos das partes serão ignorados.
O corpo de cada parte é uma solicitação HTTP completa, com o próprio verbo, URL, cabeçalhos e corpo. A solicitação HTTP precisa conter apenas a parte do caminho do URL. URLs completos não são permitidos em solicitações em lote.
Os cabeçalhos HTTP da solicitação em lote externa, exceto os cabeçalhos Content-
, como Content-Type
, aplicam-se a todas as solicitações no lote. Se você especificar um determinado cabeçalho HTTP na solicitação externa e em uma chamada individual, o valor do cabeçalho da chamada individual substituirá o valor do cabeçalho da solicitação em lote externa. Os cabeçalhos de uma chamada individual aplicam-se somente a ela.
Por exemplo, se você fornecer um cabeçalho de autorização para uma chamada específica, esse cabeçalho só se aplicará a essa chamada. Se você fornecer um cabeçalho de autorização para a solicitação externa, esse cabeçalho se aplicará a todas as chamadas individuais, a menos que ele seja substituído por cabeçalhos de autorização próprios.
Ao receber a solicitação em lote, o servidor aplica os parâmetros e os cabeçalhos de consulta da solicitação externa (conforme apropriado) a cada parte e trata cada parte como se fosse uma solicitação HTTP separada.
Resposta a uma solicitação em lote
A resposta do servidor é uma única resposta HTTP padrão com um tipo de conteúdo multipart/mixed
. Cada parte refere-se à resposta a uma das solicitações na solicitação em lote, na mesma ordem das solicitações.
Assim como as partes na solicitação, cada parte da resposta contém uma resposta HTTP completa, inclusive código de status, cabeçalhos e corpo. E da mesma forma que as partes na solicitação, cada parte da resposta é precedida por um cabeçalho Content-Type
que marca o início da parte.
Se uma determinada parte da solicitação tiver um cabeçalho Content-ID
, a parte correspondente da resposta terá um cabeçalho Content-ID
correspondente, com o valor original precedido pela string response-
, conforme mostrado no exemplo a seguir.
Observação: o servidor pode realizar as chamadas em qualquer ordem. Não conte com a execução delas na ordem especificada. Se quiser garantir que duas chamadas ocorram em uma determinada ordem, não as envie em uma única solicitação. Em vez disso, envie a primeira e aguarde a resposta antes de enviar a segunda.
Exemplo
O exemplo a seguir mostra o uso de lotes com uma API de demonstração genérica (fictícia) chamada API Farm. No entanto, os mesmos conceitos se aplicam à API BigQuery.
Exemplo de solicitação em lote
POST /batch/farm/v1 HTTP/1.1 Authorization: Bearer your_auth_token Host: www.googleapis.com Content-Type: multipart/mixed; boundary=batch_foobarbaz Content-Length: total_content_length --batch_foobarbaz Content-Type: application/http Content-ID: <item1:12930812@barnyard.example.com> GET /farm/v1/animals/pony --batch_foobarbaz Content-Type: application/http Content-ID: <item2:12930812@barnyard.example.com> PUT /farm/v1/animals/sheep Content-Type: application/json Content-Length: part_content_length If-Match: "etag/sheep" { "animalName": "sheep", "animalAge": "5" "peltColor": "green", } --batch_foobarbaz Content-Type: application/http Content-ID: <item3:12930812@barnyard.example.com> GET /farm/v1/animals If-None-Match: "etag/animals" --batch_foobarbaz--
Exemplo de resposta em lote
Esta é a resposta à solicitação de exemplo da seção anterior:
HTTP/1.1 200 Content-Length: response_total_content_length Content-Type: multipart/mixed; boundary=batch_foobarbaz --batch_foobarbaz Content-Type: application/http Content-ID: <response-item1:12930812@barnyard.example.com> HTTP/1.1 200 OK Content-Type application/json Content-Length: response_part_1_content_length ETag: "etag/pony" { "kind": "farm#animal", "etag": "etag/pony", "selfLink": "/farm/v1/animals/pony", "animalName": "pony", "animalAge": 34, "peltColor": "white" } --batch_foobarbaz Content-Type: application/http Content-ID: <response-item2:12930812@barnyard.example.com> HTTP/1.1 200 OK Content-Type: application/json Content-Length: response_part_2_content_length ETag: "etag/sheep" { "kind": "farm#animal", "etag": "etag/sheep", "selfLink": "/farm/v1/animals/sheep", "animalName": "sheep", "animalAge": 5, "peltColor": "green" } --batch_foobarbaz Content-Type: application/http Content-ID: <response-item3:12930812@barnyard.example.com> HTTP/1.1 304 Not Modified ETag: "etag/animals" --batch_foobarbaz--