Bigtable-Daten abfragen

In diesem Dokument wird beschrieben, wie Sie mit BigQuery Daten abfragen, die in einer externen Bigtable-Tabelle gespeichert sind. Informationen zum Abfragen von Daten direkt aus Bigtable finden Sie unter GoogleSQL für Bigtable – Übersicht.

Bigtable ist die dünnbesetzte NoSQL-Datenbank von Google, die auf Milliarden von Zeilen, Tausenden von Spalten und Petabyte an Daten skaliert werden kann. Weitere Informationen zum Datenmodell von Bigtable finden Sie unter Speicherungsmodell.

Dauerhafte externe Tabellen abfragen

Bevor Sie beginnen, müssen Sie oder eine Person in Ihrer Organisation eine externe Tabelle erstellen, die Sie verwenden können. Weitere Informationen und erforderliche Berechtigungen finden Sie unter Externe BigQuery-Tabelle erstellen.

Erforderliche Rollen

Zum Abfragen permanenter externer Tabellen von Bigtable benötigen Sie die folgenden Rollen:

  • BigQuery Datenbetrachter (roles/bigquery.dataViewer)
  • BigQuery-Nutzer (roles/bigquery.user)
  • Bigtable-Leser (roles/bigtable.reader)

Abhängig von Ihren Berechtigungen können Sie diese Rollen selbst zuweisen oder Ihren Administrator bitten, sie Ihnen zu gewähren. Weitere Informationen zum Gewähren von Rollen finden Sie unter Zuweisbare Rollen für Ressourcen aufrufen.

Wenn Sie die genauen BigQuery-Berechtigungen sehen möchten, die zum Abfragen externer Tabellen erforderlich sind, maximieren Sie den Abschnitt Erforderliche Berechtigungen:

Erforderliche Berechtigungen

Sie können diese Berechtigungen auch mit benutzerdefinierten Rollen oder anderen vordefinierten Rollen erhalten.

Tabelle abfragen

Sie können eine permanente externe Bigtable-Tabelle genau wie eine BigQuery-Standardtabelle abfragen. Dabei gelten die Einschränkungen für externe Datenquellen. Weitere Informationen finden Sie unter Interaktive Abfragen und Batchabfragen ausführen.

Temporäre externe Tabellen abfragen

Das Abfragen einer externen Datenquelle mithilfe einer temporären Tabelle eignet sich für einmalige Ad-hoc-Abfragen von externen Daten sowie für ETL-Vorgänge (Extraktion, Transformation, Laden).

Wenn Sie eine externe Datenquelle abfragen möchten, ohne eine permanente Tabelle zu erstellen, geben Sie eine Tabellendefinition für die temporäre Tabelle an und verwenden Sie diese Tabellendefinition dann in einem Befehl oder Aufruf, um die temporäre Tabelle abzufragen. Sie können die Tabellendefinition auf eine der folgenden Arten angeben:

Die temporäre externe Tabelle wird mit der Tabellendefinition bzw. dem bereitgestellten Schema erstellt. Anschließend erfolgt die Abfrage der temporären externen Tabelle.

Wenn Sie eine temporäre externe Tabelle verwenden, erstellen Sie keine Tabelle in einem Ihrer BigQuery-Datasets. Da die Tabelle nicht permanent in einem Dataset gespeichert wird, kann sie nicht für andere Nutzer freigegeben werden.

Die Verwendung einer temporären externen Tabelle anstelle einer permanenten externen Tabelle unterliegt einigen Einschränkungen, darunter:

  • Sie benötigen die Rolle "Bigtable-Administrator" (roles/bigtable.admin).
  • Bei diesem Ansatz können Sie nicht die Google Cloud Console verwenden, um das Schema der Bigtable-Tabelle abzuleiten und die Tabellendefinition automatisch zu erstellen. Sie müssen die Tabellendefinition selbst erstellen.

Erforderliche Rollen

Zum Abfragen temporärer externer Bigtable-Tabellen benötigen Sie die folgenden Rollen:

  • BigQuery Datenbetrachter (roles/bigquery.dataViewer)
  • BigQuery-Nutzer (roles/bigquery.user)
  • Bigtable-Admin (roles/bigtable.admin)

Abhängig von Ihren Berechtigungen können Sie diese Rollen selbst zuweisen oder Ihren Administrator bitten, sie Ihnen zu gewähren. Weitere Informationen zum Gewähren von Rollen finden Sie unter Zuweisbare Rollen für Ressourcen aufrufen.

Wenn Sie die genauen BigQuery-Berechtigungen sehen möchten, die zum Abfragen externer Tabellen erforderlich sind, maximieren Sie den Abschnitt Erforderliche Berechtigungen:

Erforderliche Berechtigungen

Sie können diese Berechtigungen auch mit benutzerdefinierten Rollen oder anderen vordefinierten Rollen erhalten.

Tabelle erstellen und abfragen

So fragen Sie Bigtable-Daten mithilfe einer temporären externen Tabelle ab:

Das Erstellen und Abfragen einer temporären externen Tabelle wird vom bq-Befehlszeilentool und der API unterstützt.

bq

Zum Abfragen einer temporären Tabelle mithilfe einer Tabellendefinitionsdatei geben Sie den Befehl bq query mit dem Flag --external_table_definition ein.

Optional: Geben Sie das Flag --location an und legen Sie als Wert Ihren Standort fest.

bq --location=LOCATION query \
--use_legacy_sql=false \
--external_table_definition=TABLE::DEFINITION_FILE \
'QUERY'

Ersetzen Sie dabei Folgendes:

  • LOCATION: Name Ihres Standorts. Das Flag --location ist optional.
  • TABLE: der Name der vorläufigen Tabelle, die Sie erstellen.
  • DEFINITION_FILE: der Pfad zur Tabellendefinitionsdatei auf Ihrem lokalen Rechner.
  • QUERY: die Abfrage, die Sie an die temporäre Tabelle stellen.

Mit dem folgenden Befehl wird beispielsweise die temporäre Tabelle follows mithilfe der Tabellendefinitionsdatei follows_def erstellt und abgefragt:

bq query \
--use_legacy_sql=false \
--external_table_definition=follows::/tmp/follows_def \
'SELECT
  COUNT(rowkey)
 FROM
   follows'

API

  • Erstellen Sie eine Abfrage. Unter Daten abfragen finden Sie Informationen zum Erstellen eines Abfragejobs.

  • Optional: Geben Sie Ihren Standort im Attribut location im Abschnitt jobReference der Jobressource an.

  • Legen Sie die Attribute der externen Datenquelle mit ExternalDataConfiguration für die Tabellenressource fest.

Java

Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Java in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Java API.

Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.BigtableColumn;
import com.google.cloud.bigquery.BigtableColumnFamily;
import com.google.cloud.bigquery.BigtableOptions;
import com.google.cloud.bigquery.ExternalTableDefinition;
import com.google.cloud.bigquery.QueryJobConfiguration;
import com.google.cloud.bigquery.TableResult;
import com.google.common.collect.ImmutableList;
import org.apache.commons.codec.binary.Base64;

// Sample to queries an external bigtable data source using a temporary table
public class QueryExternalBigtableTemp {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String bigtableInstanceId = "MY_INSTANCE_ID";
    String bigtableTableName = "MY_BIGTABLE_NAME";
    String bigqueryTableName = "MY_TABLE_NAME";
    String sourceUri =
        String.format(
            "https://googleapis.com/bigtable/projects/%s/instances/%s/tables/%s",
            projectId, bigtableInstanceId, bigtableTableName);
    String query = String.format("SELECT * FROM %s ", bigqueryTableName);
    queryExternalBigtableTemp(bigqueryTableName, sourceUri, query);
  }

  public static void queryExternalBigtableTemp(String tableName, String sourceUri, String query) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      BigtableColumnFamily.Builder statsSummary = BigtableColumnFamily.newBuilder();

      // Configuring Columns
      BigtableColumn connectedCell =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_cell".getBytes()))
              .setFieldName("connected_cell")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn connectedWifi =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("connected_wifi".getBytes()))
              .setFieldName("connected_wifi")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();
      BigtableColumn osBuild =
          BigtableColumn.newBuilder()
              .setQualifierEncoded(Base64.encodeBase64String("os_build".getBytes()))
              .setFieldName("os_build")
              .setType("STRING")
              .setEncoding("TEXT")
              .build();

      // Configuring column family and columns
      statsSummary
          .setColumns(ImmutableList.of(connectedCell, connectedWifi, osBuild))
          .setFamilyID("stats_summary")
          .setOnlyReadLatest(true)
          .setEncoding("TEXT")
          .setType("STRING")
          .build();

      // Configuring BigtableOptions is optional.
      BigtableOptions options =
          BigtableOptions.newBuilder()
              .setIgnoreUnspecifiedColumnFamilies(true)
              .setReadRowkeyAsString(true)
              .setColumnFamilies(ImmutableList.of(statsSummary.build()))
              .build();

      // Configure the external data source and query job.
      ExternalTableDefinition externalTable =
          ExternalTableDefinition.newBuilder(sourceUri, options).build();
      QueryJobConfiguration queryConfig =
          QueryJobConfiguration.newBuilder(query)
              .addTableDefinition(tableName, externalTable)
              .build();

      // Example query
      TableResult results = bigquery.query(queryConfig);

      results
          .iterateAll()
          .forEach(row -> row.forEach(val -> System.out.printf("%s,", val.toString())));

      System.out.println("Query on external temporary table performed successfully.");
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Query not performed \n" + e.toString());
    }
  }
}

Hinweise zur Leistung

Die Leistung beim Abfragen externer Bigtable-Datenquellen hängt von drei Faktoren ab:

  • Der Anzahl der Zeilen
  • Der Menge der gelesenen Daten
  • Dem Grad der Parallelisierung

BigQuery versucht, so wenig Daten wie möglich zu lesen, indem nur die in der Abfrage angegebenen Spaltenfamilien gelesen werden. Der Grad der Parallelisierung hängt davon ab, wie viele Knoten der Bigtable-Cluster enthält und wie viele Teilungen es in Ihrer Tabelle gibt.

Bigtable entfernt Teilungen basierend auf der Last automatisch. Wenn die Tabelle nicht oft gelesen wird, sinkt die Anzahl der Teilungen im Laufe der Zeit und die Abfrageleistung geht allmählich zurück. Weitere Informationen zum Teilen einer Tabelle anhand des Zeilenschlüssels finden Sie unter Tabellen verwalten.

Beim Abfragen von Bigtable über BigQuery werden Bigtable-CPU-Zyklen verbraucht. Die CPU-Nutzung durch BigQuery kann die Latenz und den Durchsatz für andere, gleichzeitige Abfragen beeinträchtigen, z. B. für die Bereitstellung von Livenutzer-Traffic. Eine hohe CPU-Nutzung durch Bigtable beeinträchtigt z. B. lange Abfragen und erhöht die Latenz für das 99. Perzentil.

Achten Sie bei der CPU-Nutzung von Bigtable darauf, dass die im Monitoring-Dashboard der Google Cloud Console empfohlenen Grenzen für Bigtable nicht überschritten werden. Wenn Sie die Anzahl der Knoten für Ihre Instanz erhöhen, können Sie sowohl BigQuery-Traffic als auch Traffic von anderen, gleichzeitigen Anfragen besser verarbeiten.

Abfragefilter

Bei Abfragen mit einem Zeilengleichheitsfilter wird nur die konkrete Zeile gelesen. Hier ein Beispiel in der GoogleSQL-Syntax:

SELECT
  COUNT(follows.column.name)
FROM
  `dataset.table`
WHERE
  rowkey = "alice";

Bereichsfilter wie rowkey > '1' und rowkey < '8' werden ebenfalls unterstützt, aber nur, wenn "rowkey" als String mit der Option readRowkeyAsString gelesen wird.