esegui una query sui dati Bigtable

Questo documento descrive come utilizzare BigQuery per eseguire query sui dati archiviati in una tabella esterna Bigtable. Per informazioni su come eseguire query sui dati direttamente da Bigtable, consulta la panoramica di GoogleSQL per Bigtable.

Bigtable è il database NoSQL scarsamente popolato di Google che può scalare fino a miliardi di righe, migliaia di colonne e petabyte di dati. Per informazioni sul modello dei dati Bigtable, consulta Modello di archiviazione.

Esegui query sulle tabelle esterne permanenti

Prima di iniziare, tu o un altro utente della tua organizzazione dovete creare una tabella esterna da utilizzare. Per i dettagli e le autorizzazioni richieste, consulta Creare una tabella esterna BigQuery.

Ruoli obbligatori

Per eseguire query sulle tabelle esterne permanenti di Bigtable, assicurati di disporre dei seguenti ruoli:

  • Visualizzatore dati BigQuery (roles/bigquery.dataViewer)
  • Utente BigQuery (roles/bigquery.user)
  • Lettore Bigtable (roles/bigtable.reader)

A seconda delle tue autorizzazioni, puoi assegnare questi ruoli a te stesso o chiedere all'amministratore di assegnarteli. Per ulteriori informazioni sulla concessione dei ruoli, consulta Visualizzazione dei ruoli assegnabili sulle risorse.

Per visualizzare le autorizzazioni BigQuery esatte necessarie per eseguire query sulle tabelle esterne, espandi la sezione Autorizzazioni richieste:

Autorizzazioni obbligatorie

Potresti anche ottenere queste autorizzazioni con ruoli personalizzati o altri ruoli predefiniti.

esegui una query sulla tabella

Puoi eseguire una query su una tabella Bigtable esterna definitiva esattamente come se fosse una tabella BigQuery standard, tenendo conto delle limitazioni relative alle origini dati esterne. Per ulteriori informazioni, consulta Eseguire query interattive e in batch.

Esegui query sulle tabelle esterne temporanee

L'esecuzione di query su un'origine dati esterna utilizzando una tabella temporanea è utile per query una tantum e ad hoc su dati esterni o per processi ETL (estrazione, trasformazione e caricamento).

Per eseguire query su un'origine dati esterna senza creare una tabella permanente, fornisci una definizione della tabella per la tabella temporanea e poi utilizzala in un comando o in una chiamata per eseguire query sulla tabella temporanea. Puoi fornire la definizione della tabella in uno dei seguenti modi:

Il file di definizione della tabella o lo schema fornito viene utilizzato per creare la tabella esterna temporanea e la query viene eseguita su questa tabella.

Quando utilizzi una tabella esterna temporanea, non crei una tabella in uno dei tuoi set di dati BigQuery. Poiché la tabella non viene archiviata in modo permanente in un set di dati, non può essere condivisa con altri.

L'utilizzo di una tabella esterna temporanea anziché di una tabella esterna permanente presenta alcune limitazioni, tra cui le seguenti:

  • Devi disporre del ruolo Amministratore Bigtable (roles/bigtable.admin).
  • Questo approccio non ti consente di utilizzare la console Google Cloud per dedurre lo schema della tabella Bigtable e creare automaticamente la definizione della tabella. Devi creare la definizione della tabella.

Ruoli obbligatori

Per eseguire query sulle tabelle esterne temporanee di Bigtable, assicurati di disporre dei seguenti ruoli:

  • Visualizzatore dati BigQuery (roles/bigquery.dataViewer)
  • Utente BigQuery (roles/bigquery.user)
  • Bigtable Admin (roles/bigtable.admin)

A seconda delle tue autorizzazioni, puoi assegnare questi ruoli a te stesso o chiedere all'amministratore di assegnarteli. Per ulteriori informazioni sulla concessione dei ruoli, consulta Visualizzazione dei ruoli assegnabili sulle risorse.

Per visualizzare le autorizzazioni BigQuery esatte necessarie per eseguire query sulle tabelle esterne, espandi la sezione Autorizzazioni richieste:

Autorizzazioni obbligatorie

Potresti anche ottenere queste autorizzazioni con ruoli personalizzati o altri ruoli predefiniti.

Crea e esegui query sulla tabella

Per eseguire query sui dati di Bigtable utilizzando una tabella esterna temporanea:

La creazione e l'esecuzione di query su una tabella esterna temporanea sono supportate dall'API e dallo strumento a riga di comando bq.

bq

Per eseguire una query su una tabella temporanea utilizzando un file di definizione della tabella, inserisci il comando bq query con il flag --external_table_definition.

(Facoltativo) Fornisci il flag --location e imposta il valore sulla tua posizione.

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

Sostituisci quanto segue:

  • LOCATION: il nome della tua posizione. Il flag --location è facoltativo.
  • TABLE: il nome della tabella temporanea che stai creando.
  • DEFINITION_FILE: il percorso del file di definizione della tabella sulla tua macchina locale.
  • QUERY: la query che stai inviando alla tabella temporanea.

Ad esempio, il comando seguente crea e esegue query su una tabella temporanea denominata follows utilizzando un file di definizione della tabella denominato follows_def.

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

API

  • Crea una query. Per informazioni sulla creazione di un job di query, consulta Eseguire query sui dati.

  • (Facoltativo) Specifica la tua posizione nella proprietà location nella sezione jobReference della risorsa job.

  • Specifica le proprietà dell'origine dati esterna impostando ExternalDataConfiguration per la risorsa tabella.

Java

Prima di provare questo esempio, segui le istruzioni di configurazione Java riportate nella guida rapida all'utilizzo di BigQuery con le librerie client. Per ulteriori informazioni, consulta la documentazione di riferimento dell'API BigQuery Java.

Per autenticarti in BigQuery, configura le Credenziali predefinite dell'applicazione. Per saperne di più, consulta Configurare l'autenticazione per le librerie client.

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());
    }
  }
}

Considerazioni sulle prestazioni

Le prestazioni delle query sulle origini dati esterne di Bigtable dipendono da tre fattori:

  • Il numero di righe
  • La quantità di dati letti
  • L'entità della parallellizzazione

BigQuery tenta di leggere il minor numero di dati possibile leggendo solo le famiglie di colonne a cui viene fatto riferimento nella query. L'entità della parallellizzazione dipende dal numero di nodi nel cluster Bigtable e dal numero di suddivisioni della tabella.

Tieni presente che Bigtable unisce automaticamente le suddivisioni in base al carico. Se la tabella non viene letta di frequente, nel tempo ci saranno meno suddivisioni e un degrado graduale del rendimento delle query. Per ulteriori informazioni su come suddividere una tabella in base alla chiave di riga, consulta Gestire le tabelle.

L'esecuzione di query su Bigtable da BigQuery consuma ciclo di CPU di Bigtable. Il consumo di CPU da parte di BigQuery potrebbe influire sulla latenza e sul throughput di altre richieste concorrenti, come la pubblicazione del traffico degli utenti in tempo reale. Ad esempio, un utilizzo elevato della CPU su Bigtable influisce sulle query long-tail e aumenta la latenza al 99° percentile.

Devi monitorare l'utilizzo della CPU di Bigtable per verificare di rientrare nei limiti consigliati indicati nella dashboard di monitoraggio di Bigtable nella console Google Cloud. Aumentare il numero di nodi per l'istanza ti consente di gestire sia il traffico di BigQuery sia quello di altre richieste simultanee.

Filtri delle query

Le query con un filtro di uguaglianza di riga leggono solo quella riga specifica. Ad esempio, nella sintassi GoogleSQL:

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

Sono supportati anche i filtri di intervallo come rowkey > '1' e rowkey < '8', ma solo quando la chiave riga viene letta come stringa con l'opzione readRowkeyAsString.