Richieste batch

A seguito del ritiro degli endpoint HTTP batch globali, le richieste HTTP batch che hanno come target solo le API BigQuery non funzioneranno più a partire dal 1° giugno 2021. Se la tua applicazione invia richieste HTTP in batch, sostitui le richieste HTTP in batch con singole richieste HTTP prima del 1° giugno 2021.

Per informazioni sul ritiro, consulta la sezione Domande frequenti di seguito. Per la documentazione su come raggruppare le richieste HTTP, consulta Raccogliere le richieste.

Domande frequenti sul ritiro dell'API HTTP batch di BigQuery

Perché le richieste HTTP batch di BigQuery sono state ritirate?

Il supporto degli endpoint batch HTTP globali si basava su un'architettura che utilizzava un singolo proxy condiviso per ricevere le richieste per tutte le API. Con il passaggio di Google a un'architettura più distribuita e ad alte prestazioni in cui le richieste vengono inviate direttamente al server API appropriato, non potremo più supportare questi endpoint globali.

Il passaggio successivo è il ritiro delle richieste HTTP batch di BigQuery. Anche il servizio BigQuery è distribuito. I metodi con un elevato numero di query al secondo vengono gestiti da backend dedicati. Tutte le regioni sono isolate, ma le richieste HTTP batch possono causare la distribuzione delle richieste tra più regioni. Ciò rende il raggruppamento non efficiente e può comportare una maggiore latenza di elaborazione, il contrario dell'obiettivo originale del supporto delle richieste HTTP collettive.

Che cosa viene ritirato nello specifico?

I seguenti metodi di richiesta batch per interagire con le API BigQuery non funzioneranno più:

Come faccio a eseguire la migrazione?

La maggior parte degli utenti di BigQuery non utilizza richieste HTTP batch. Se continui a utilizzare le richieste batch, utilizza i seguenti esempi per sostituire le richieste HTTP batch con singole richieste HTTP.

REST

Invia singole richieste HTTP come descritto nella sezione di riferimento dell'API BigQuery. Non combinare le richieste in batch utilizzando il percorso /batch/v2/bigquery.

JavaScript

Se utilizzi JavaScript, inizia con un blocco di codice simile al seguente:

// 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))

Sostituisci il blocco di codice precedente con un blocco di codice simile al seguente:

// 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 utilizzi Python, inizia con un blocco di codice simile al seguente:

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)

Sostituisci il blocco di codice precedente con un blocco di codice simile al seguente:

# 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

Altre lingue

Come negli esempi precedenti, sostituisci le chiamate BatchRequest con singole richieste.

Ricevi assistenza per la migrazione

Per assistenza con la migrazione, puoi porre domande su Stack Overflow. Gli ingegneri di Google monitorano e rispondono alle domande con il tag google-bigquery. Utilizza questo tag per porre domande. Ci impegniamo a rispondere a tutte le domande in un periodo di tempo ragionevole.

Creazione di batch di richieste

Questo documento mostra come raggruppare le chiamate API per ridurre il numero di connessioni HTTP che il tuo client deve effettuare.

Questo documento riguarda nello specifico l'invio di una richiesta batch inviando una richiesta HTTP. Se invece utilizzi una libreria client Google per inviare una richiesta batch, consulta la documentazione della libreria client.

Panoramica

Ogni connessione HTTP stabilita dal client comporta un determinato overhead. L'API BigQuery supporta il batching per consentire al client di inserire più chiamate API in un'unica richiesta HTTP.

Esempi di situazioni in cui potresti voler utilizzare il raggruppamento:

  • Hai appena iniziato a utilizzare l'API e hai molti dati da caricare.
  • Un utente ha apportato modifiche ai dati mentre la tua applicazione era offline (disconnessa da internet), quindi l'applicazione deve sincronizzare i dati locali con il server inviando molti aggiornamenti ed eliminazioni.

In ogni caso, anziché inviare ogni chiamata separatamente, puoi raggrupparle in un'unica richiesta HTTP. Tutte le richieste interne devono essere indirizzate alla stessa API Google.

Hai un limite di 1000 chiamate in una singola richiesta batch. Se devi effettuare più chiamate, utilizza più richieste collettive.

Nota: il sistema batch per l'API BigQuery utilizza la stessa sintassi del sistema di elaborazione batch OData, ma la semantica è diversa.

Dettagli del batch

Una richiesta batch è composta da più chiamate API combinate in un'unica richiesta HTTP, che può essere inviata all'batchPath specificato nel documento di rilevamento dell'API. Il percorso predefinito è /batch/api_name/api_version. Questa sezione descrive la sintassi batch in dettaglio; di seguito è riportato un esempio.

Nota: un insieme di n richieste raggruppate viene conteggiato ai fini del limite di utilizzo come n richieste, non come una singola richiesta. La richiesta batch viene suddivisa in un insieme di richieste prima dell'elaborazione.

Formato di una richiesta batch

Una richiesta batch è una singola richiesta HTTP standard contenente più chiamate all'API BigQuery che utilizzano il tipo di contenuto multipart/mixed. All'interno di questa richiesta HTTP principale, ciascuna delle parti contiene una richiesta HTTP nidificata.

Ogni parte inizia con la propria intestazione HTTP Content-Type: application/http. Può anche avere un'intestazione Content-ID facoltativa. Tuttavia, le intestazioni della parte servono solo a contrassegnare l'inizio della parte e sono separate dalla richiesta nidificata. Dopo che il server ha scompattato la richiesta batch in richieste separate, le intestazioni delle parti vengono ignorate.

Il corpo di ogni parte è una richiesta HTTP completa, con verbo, URL, intestazioni e corpo. La richiesta HTTP deve contenere solo la parte di percorso dell'URL; gli URL completi non sono consentiti nelle richieste collettive.

Le intestazioni HTTP per la richiesta batch esterna, ad eccezione delle intestazioni Content- come Content-Type, si applicano a ogni richiesta del batch. Se specifichi una determinata intestazione HTTP sia nella richiesta esterna che in una singola chiamata, il valore dell'intestazione della singola chiamata sostituisce il valore dell'intestazione della richiesta batch esterna. Le intestazioni di una singola chiamata si applicano solo a quella chiamata.

Ad esempio, se fornisci un'intestazione Authorization per una chiamata specifica, questa intestazione si applica solo a quella chiamata. Se fornisci un'intestazione Authorization per la richiesta esterna, questa intestazione si applica a tutte le singole chiamate, a meno che non vengano sostituite con intestazioni Authorization proprie.

Quando il server riceve la richiesta raggruppata, applica i parametri di ricerca e le intestazioni della richiesta esterna (se appropriato) a ogni parte e poi tratta ogni parte come se fosse una richiesta HTTP separata.

Risposta a una richiesta batch

La risposta del server è una singola risposta HTTP standard con un tipo di contenuto multipart/mixed; ogni parte è la risposta a una delle richieste nella richiesta raggruppata, nello stesso ordine delle richieste.

Come le parti della richiesta, ogni parte della risposta contiene una risposta HTTP completa, inclusi un codice di stato, le intestazioni e il corpo. Come le parti nella richiesta, ogni parte della risposta è preceduta da un'intestazione Content-Type che ne indica l'inizio.

Se una determinata parte della richiesta aveva un'intestazione Content-ID, la parte corrispondente della risposta ha un'intestazione Content-ID corrispondente, con il valore originale preceduto dalla stringa response-, come mostrato nell'esempio seguente.

Nota: il server potrebbe eseguire le chiamate in qualsiasi ordine. Non aspettarti che vengano eseguiti nell'ordine in cui li hai specificati. Se vuoi assicurarti che due chiamate vengano eseguite in un determinato ordine, non puoi inviarle in una singola richiesta; invia invece la prima da sola, quindi attendi la risposta prima di inviare la seconda.

Esempio

L'esempio seguente mostra l'utilizzo del raggruppamento con un'API demo generica (inventariata) chiamata API Farm. Tuttavia, gli stessi concetti si applicano all'API BigQuery.

Esempio di richiesta batch

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--

Esempio di risposta batch

Questa è la risposta alla richiesta di esempio nella sezione precedente.

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--