Batchanfragen

Aufgrund der Einstellung globaler HTTP-Batchendpunkte funktionieren HTTP-Batchanfragen, die nur auf BigQuery APIs abzielen, ab dem 1. Juni 2021 nicht mehr. Wenn Ihre Anwendung HTTP-Batchanfragen sendet, ersetzen Sie vor dem 1. Juni 2021 HTTP-Batchanfragen durch einzelne HTTP-Anfragen.

Informationen zur Einstellung finden Sie im folgenden Abschnitt mit den FAQ. Dokumentationen zur Batchverarbeitung von HTTP-Anfragen finden Sie unter Anfragen im Batch verarbeiten.

FAQ zur Einstellung der BigQuery Batch HTTP API

Warum werden BigQuery-HTTP-Batchanfragen eingestellt?

Die Unterstützung für globale HTTP-Batchendpunkte basierte auf einer Architektur, die einen einzelnen gemeinsamen Proxy verwendet, um Anfragen für alle APIs zu erhalten. Da Google zu einer stärker verteilten Hochleistungsarchitektur gewechselt ist, bei der Anfragen direkt an den entsprechenden API-Server gesendet werden, konnten wir die Unterstützung dieser globalen Endpunkte nicht mehr aufrechterhalten.

Das Einstellen von BigQuery-HTTP-Batchanfragen ist der nächste Schritt. Der BigQuery-Dienst ist ebenfalls verteilt. Methoden mit zahlreichen Abfragen pro Sekunde werden von dedizierten Back-Ends verarbeitet. Alle Regionen sind isoliert, aber HTTP-Batchanfragen können zu regionsübergreifendem Anfrage-Fanout führen. Dies macht die Batchverarbeitung ineffizient und kann eine erhöhte Verarbeitungslatenz zur Folge haben, was dem ursprünglichen Ziel der Unterstützung von HTTP-Batchanfragen entgegenwirkt.

Was genau wurde eingestellt?

Die folgenden Methoden von Batchanfragen für die Interaktion mit BigQuery APIs werden nicht mehr funktionieren:

Wie kann ich migrieren?

Die meisten BigQuery-Nutzer verwenden keine HTTP-Batchanfragen. Sollten Sie noch Batchanfragen verwenden, nutzen Sie die folgenden Beispiele, um HTTP-Batchanfragen durch einzelne HTTP-Anfragen zu ersetzen.

REST

Senden Sie einzelne HTTP-Anfragen wie im Abschnitt „Referenz zur BigQuery API“ beschrieben. Kombinieren Sie Ihre Anfragen nicht in Batches mit dem Pfad /batch/v2/bigquery.

JavaScript

Wenn Sie JavaScript verwenden, beginnen Sie mit einem Codeblock, der so aussieht:

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

Ersetzen Sie den vorherigen Codeblock durch einen Codeblock, der in etwa so aussieht:

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

Wenn Sie Python verwenden, beginnen Sie mit einem Codeblock, der so aussieht:

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)

Ersetzen Sie den vorherigen Codeblock durch einen Codeblock, der in etwa so aussieht:

# 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

Andere Sprachen

Ähnlich wie in den vorherigen Beispielen ersetzen Sie BatchRequest-Aufrufe durch einzelne Anfragen.

Support für die Migration

Um Hilfe bei der Migration zu erhalten, können Sie Fragen bei Stack Overflow stellen. Google-Entwickler verfolgen und beantworten Fragen mit dem Tag google-bigquery. Bitte nutzen Sie dieses Tag für Ihre Fragen. Wir bemühen uns, alle Fragen innerhalb einer angemessenen Frist zu beantworten.

Batchanfragen

In diesem Dokument erfahren Sie, wie API-Aufrufe in einem Batch zusammengefasst werden, um die Anzahl von HTTP-Verbindungen für den Client zu reduzieren.

In diesem Dokument wird ausschließlich das Erstellen einer Batchanfrage durch Senden einer HTTP-Anfrage behandelt. Wenn Sie stattdessen eine Google-Clientbibliothek für die Batchanfrage verwenden, lesen Sie die Informationen in der Dokumentation der Clientbibliothek.

Überblick

Jede HTTP-Verbindung, die der Client erstellt, führt zu einem bestimmten Overhead. Die BigQuery-API unterstützt Batchanfragen, damit der Client mehrere API-Aufrufe in einer einzelnen HTTP-Anfrage zusammenfassen kann.

Fallbeispiele für den Einsatz von Batchanfragen:

  • Sie haben gerade mit der Verwendung der API begonnen und müssen viele Daten hochladen.
  • Ein Nutzer hat Änderungen an Daten vorgenommen, während Ihre Anwendung offline (nicht mit dem Internet verbunden) war, sodass Ihre Anwendung die lokalen Daten mit dem Server synchronisieren und dazu viele Aktualisierungs- und Löschvorgänge senden muss.

In jedem Fall können Sie, anstatt jeden Aufruf einzeln zu senden, mehrere Aufrufe in einer einzigen HTTP-Anfrage zusammenfassen. Alle internen Anfragen müssen an dieselbe Google API gesendet werden.

Jede Batchanfrage ist auf maximal 1.000 Aufrufe begrenzt. Bei einer höheren Anzahl an Aufrufen erstellen Sie mehrere Batchanfragen.

Hinweis: Die Batchverarbeitung der BigQuery API verwendet dieselbe Syntax wie die Batchverarbeitung von OData, jedoch mit einer anderen Semantik.

Batchdetails

Eine Batchanfrage besteht aus mehreren, in einer HTTP-Anfrage zusammengefassten API-Aufrufen. Sie kann an den im Discovery-Dokument der API angegebenen batchPath gesendet werden. Der Standardpfad ist /batch/api_name/api_version. In diesem Abschnitt wird die Batchsyntax im Detail beschrieben. Anschließend finden Sie ein Beispiel.

Hinweis: Wenn n Anfragen zu einem Batch zusammengefasst sind, werden auch n Anfragen auf Ihr Nutzungskontingent angerechnet, nicht nur eine einzige Anfrage. Die Batchanfrage wird vor der Verarbeitung in eine Reihe von Anfragen aufgeteilt.

Format einer Batchanfrage

Eine Batchanfrage ist eine einzelne Standard-HTTP-Anfrage, die mehrere Google BigQuery API-Aufrufe enthält. Dabei wird der Inhaltstyp multipart/mixed verwendet. Jeder Teil der HTTP-Hauptanfrage enthält eine verschachtelte HTTP-Anfrage.

Jeder Teil beginnt mit seinem eigenen HTTP-Header Content-Type: application/http. Er kann auch einen optionalen Content-ID-Header haben. Die Header der einzelnen Teile sollen jedoch nur den Anfang des Teils markieren. Sie sind von der verschachtelten Anfrage getrennt. Nachdem der Server die Batchanfrage in separate Anfragen aufgeteilt hat, werden die Header der einzelnen Teile ignoriert.

Der Text jedes Teils ist an sich eine vollständige HTTP-Anfrage mit eigenem Verb, eigener URL, eigenen Headern und eigenem Text. Die HTTP-Anfrage darf nur den Pfadteil der URL enthalten; vollständige URLs sind in Batchanfragen nicht zulässig.

Die HTTP-Header für die äußere Batchanfrage gelten für jede Anfrage in dem Batch, ausgenommen Content--Header wie Content-Type. Wenn Sie einen bestimmten HTTP-Header sowohl in der äußeren Anfrage als auch in einem individuellen Aufruf verwenden, überschreibt der Wert des individuellen Aufrufheaders den Wert des Headers der äußeren Stapelanfrage. Die Header für einen individuellen Aufruf gelten nur für diesen Aufruf.

Beispiel: Wenn Sie einen Autorisierungsheader für einen bestimmten Aufruf angeben, gilt dieser Header nur für diesen Aufruf. Wenn Sie einen Autorisierungsheader für die äußere Anfrage angeben, gilt dieser Header für alle einzelnen Aufrufe, es sei denn, diese überschreiben ihn mit eigenen Autorisierungsheadern.

Wenn der Server die Stapelanfrage empfängt, wendet er (nach Bedarf) die Abfrageparameter und Header der äußeren Anfrage für jeden Teil an, und behandelt jeden Teil dann so, als wäre er eine separate HTTP-Anfrage.

Antwort auf eine Batchanfrage

Die Antwort des Servers ist eine einzelne Standard-HTTP-Antwort mit einem Inhaltstyp multipart/mixed. Jeder Teil ist die Antwort auf eine der Anfragen in der Batchanfrage in derselben Reihenfolge wie die einzelnen Anfragen.

Wie die Teile in der Anfrage enthält jeder Antwortteil eine vollständige HTTP-Antwort, einschließlich Statuscode, Headern und Text. Wie auch bei den Teilen in der Anfrage ist jedem Antwortteil ein Content-Type-Header vorangestellt, der den Beginn des Teils markiert.

Wenn ein bestimmter Teil einer Anfrage einen Content-ID-Header enthielt, enthält der entsprechende Teil der Antwort einen übereinstimmenden Content-ID-Header, wobei dem ursprünglichen Wert der String response- vorangestellt ist, wie im folgenden Beispiel dargestellt.

Hinweis: Der Server kann die Aufrufe in beliebiger Reihenfolge ausführen. Die Aufrufe werden nicht unbedingt in der Reihenfolge ausgeführt, in der Sie sie angegeben haben. Wenn Sie sicherstellen möchten, dass zwei Aufrufe in einer bestimmten Reihenfolge ausgeführt werden, können Sie sie nicht in einer einzelnen Anfrage senden. Senden Sie stattdessen den ersten Aufruf für sich alleine und warten Sie auf die Antwort auf den ersten Aufruf, bevor Sie den zweiten Aufruf senden.

Beispiel

Das folgende Beispiel zeigt die Verwendung der Batchverarbeitung mit einer generischen (fiktiven) Demo-API namens Farm API. Für die BigQuery API gelten die gleichen Konzepte.

Beispiel-Batchanfrage

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

Beispiel für eine Stapelantwort

Dies ist die Antwort auf die Beispielanfrage im vorherigen Abschnitt.

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