Connettore Beam HBase Bigtable

Per aiutarti a utilizzare Bigtable in una Dataflow pipeline, sono disponibili due connettori I/O Beam Bigtable open source.

Se stai eseguendo la migrazione da HBase a Bigtable o se la tua applicazione chiama l'API HBase, utilizza il connettore Beam HBase Bigtable (CloudBigtableIO) descritto in questa pagina.

In tutti gli altri casi, devi utilizzare il connettore Beam Bigtable (BigtableIO) insieme al client Cloud Bigtable per Java, che funziona con le API Cloud Bigtable. Per iniziare a utilizzare questo connettore, consulta Connettore Beam Bigtable.

Per saperne di più sul modello di programmazione Apache Beam, consulta la Beam documentazione.

Inizia a utilizzare HBase

Il connettore Beam HBase Bigtable è scritto in Java e si basa sul client HBase Bigtable per Java. È compatibile con Dataflow SDK 2.x per Java, basato su Apache Beam. Il codice sorgente del connettore si trova su GitHub nel repository googleapis/java-bigtable-hbase.

Questa pagina fornisce una panoramica su come utilizzare le trasformazioni Read e Write.

Configura l'autenticazione

Per utilizzare gli esempi Java in questa pagina in un ambiente di sviluppo locale, installa e inizializza gcloud CLI, quindi configura Credenziali predefinite dell'applicazione con le tue credenziali utente.

  1. Installa Google Cloud CLI.

  2. Configura gcloud CLI per utilizzare la tua identità federata.

    Per ulteriori informazioni, vedi Accedi a gcloud CLI con la tua identità federata.

  3. Crea le credenziali di autenticazione locali per il tuo account utente:

    gcloud auth application-default login

    Se viene restituito un errore di autenticazione e utilizzi un provider di identità (IdP) esterno, verifica di aver acceduto a gcloud CLI con la tua identità federata.

Per saperne di più, consulta Configura l'autenticazione per un ambiente di sviluppo locale.

Per informazioni sulla configurazione dell'autenticazione per un ambiente di produzione, consulta Configura le credenziali predefinite dell'applicazione per il codice in esecuzione su Google Cloud .

Aggiungi il connettore a un progetto Maven

Per aggiungere il connettore Beam HBase Bigtable a un progetto Maven, aggiungi l'artefatto Maven al file pom.xml come dipendenza:

<dependency>
  <groupId>com.google.cloud.bigtable</groupId>
  <artifactId>bigtable-hbase-beam</artifactId>
  <version>2.12.0</version>
</dependency>

Specifica la configurazione di Bigtable

Crea un'interfaccia delle opzioni per consentire gli input per l'esecuzione della pipeline:

public interface BigtableOptions extends DataflowPipelineOptions {

  @Description("The Bigtable project ID, this can be different than your Dataflow project")
  @Default.String("bigtable-project")
  String getBigtableProjectId();

  void setBigtableProjectId(String bigtableProjectId);

  @Description("The Bigtable instance ID")
  @Default.String("bigtable-instance")
  String getBigtableInstanceId();

  void setBigtableInstanceId(String bigtableInstanceId);

  @Description("The Bigtable table ID in the instance.")
  @Default.String("mobile-time-series")
  String getBigtableTableId();

  void setBigtableTableId(String bigtableTableId);
}

Quando leggi o scrivi in Bigtable, devi fornire un oggetto di configurazione CloudBigtableConfiguration. Questo oggetto specifica l'ID progetto e l'ID istanza per la tabella, nonché il nome della tabella stessa:

CloudBigtableTableConfiguration bigtableTableConfig =
    new CloudBigtableTableConfiguration.Builder()
        .withProjectId(options.getBigtableProjectId())
        .withInstanceId(options.getBigtableInstanceId())
        .withTableId(options.getBigtableTableId())
        .build();

Per la lettura, fornisci un oggetto di configurazione CloudBigtableScanConfiguration, che ti consente di specificare un oggetto Scan di Apache HBase che limita e filtra i risultati di una lettura. Per maggiori dettagli, consulta Lettura da Bigtable.

Leggi da Bigtable

Per leggere da una tabella Bigtable, applichi una trasformazione Read al risultato di un'operazione CloudBigtableIO.read. La trasformazione Read restituisce un PCollection di oggetti Result di HBase, in cui ogni elemento della PCollection rappresenta una singola riga della tabella.

p.apply(Read.from(CloudBigtableIO.read(config)))
    .apply(
        ParDo.of(
            new DoFn<Result, Void>() {
              @ProcessElement
              public void processElement(@Element Result row, OutputReceiver<Void> out) {
                System.out.println(Bytes.toString(row.getRow()));
              }
            }));

Per impostazione predefinita, un'operazione CloudBigtableIO.read restituisce tutte le righe della tabella. Puoi utilizzare un oggetto Scan di HBase per limitare la lettura a un intervallo di chiavi riga all'interno della tabella o per applicare filtri ai risultati della lettura. Per utilizzare un oggetto Scan, includilo in CloudBigtableScanConfiguration.

Ad esempio, puoi aggiungere una Scan che restituisce solo la prima coppia chiave-valore di ogni riga della tabella, utile per contare il numero di righe della tabella:

import com.google.cloud.bigtable.beam.CloudBigtableIO;
import com.google.cloud.bigtable.beam.CloudBigtableScanConfiguration;
import org.apache.beam.runners.dataflow.options.DataflowPipelineOptions;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.Read;
import org.apache.beam.sdk.options.Default;
import org.apache.beam.sdk.options.Description;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;
import org.apache.hadoop.hbase.util.Bytes;

public class HelloWorldRead {
  public static void main(String[] args) {
    BigtableOptions options =
        PipelineOptionsFactory.fromArgs(args).withValidation().as(BigtableOptions.class);
    Pipeline p = Pipeline.create(options);

    Scan scan = new Scan();
    scan.setCacheBlocks(false);
    scan.setFilter(new FirstKeyOnlyFilter());

    CloudBigtableScanConfiguration config =
        new CloudBigtableScanConfiguration.Builder()
            .withProjectId(options.getBigtableProjectId())
            .withInstanceId(options.getBigtableInstanceId())
            .withTableId(options.getBigtableTableId())
            .withScan(scan)
            .build();

    p.apply(Read.from(CloudBigtableIO.read(config)))
        .apply(
            ParDo.of(
                new DoFn<Result, Void>() {
                  @ProcessElement
                  public void processElement(@Element Result row, OutputReceiver<Void> out) {
                    System.out.println(Bytes.toString(row.getRow()));
                  }
                }));

    p.run().waitUntilFinish();
  }

  public interface BigtableOptions extends DataflowPipelineOptions {
    @Description("The Bigtable project ID, this can be different than your Dataflow project")
    @Default.String("bigtable-project")
    String getBigtableProjectId();

    void setBigtableProjectId(String bigtableProjectId);

    @Description("The Bigtable instance ID")
    @Default.String("bigtable-instance")
    String getBigtableInstanceId();

    void setBigtableInstanceId(String bigtableInstanceId);

    @Description("The Bigtable table ID in the instance.")
    @Default.String("mobile-time-series")
    String getBigtableTableId();

    void setBigtableTableId(String bigtableTableId);
  }
}

Scrivi in Bigtable

Per scrivere in una tabella Bigtable, apply un'operazione CloudBigtableIO.writeToTable. Dovrai eseguire questa operazione su una PCollection di oggetti Mutation di HBase, che possono includere oggetti Put e Delete.

La tabella Bigtable deve già esistere e deve avere le famiglie di colonne appropriate definite. Il connettore Dataflow non crea tabelle e famiglie di colonne al volo. Puoi utilizzare la cbt CLI per creare una tabella e configurare le famiglie di colonne, oppure puoi farlo a livello di programmazione.

Prima di scrivere in Bigtable, devi creare la pipeline Dataflow in modo che le operazioni di inserimento ed eliminazione possano essere serializzate sulla rete:

BigtableOptions options =
    PipelineOptionsFactory.fromArgs(args).withValidation().as(BigtableOptions.class);
Pipeline p = Pipeline.create(options);

In genere, dovrai eseguire una trasformazione, ad esempio una ParDo, per formattare i dati di output in una raccolta di oggetti Put o Delete di HBase. L'esempio seguente mostra una trasformazione DoFn che accetta il valore corrente e lo utilizza come chiave di riga per un'operazione Put. Puoi quindi scrivere gli oggetti Put in Bigtable.

p.apply(Create.of("phone#4c410523#20190501", "phone#4c410523#20190502"))
    .apply(
        ParDo.of(
            new DoFn<String, Mutation>() {
              @ProcessElement
              public void processElement(@Element String rowkey, OutputReceiver<Mutation> out) {
                long timestamp = System.currentTimeMillis();
                Put row = new Put(Bytes.toBytes(rowkey));

                row.addColumn(
                    Bytes.toBytes("stats_summary"),
                    Bytes.toBytes("os_build"),
                    timestamp,
                    Bytes.toBytes("android"));
                out.output(row);
              }
            }))
    .apply(CloudBigtableIO.writeToTable(bigtableTableConfig));

Per abilitare il controllo del flusso di scrittura batch, imposta BIGTABLE_ENABLE_BULK_MUTATION_FLOW_CONTROL su true. Questa funzionalità limita automaticamente la frequenza del traffico per le richieste di scrittura batch e consente alla scalabilità automatica di Bigtable di aggiungere o rimuovere automaticamente i nodi per gestire il job Dataflow.

CloudBigtableTableConfiguration bigtableTableConfig =
    new CloudBigtableTableConfiguration.Builder()
        .withProjectId(options.getBigtableProjectId())
        .withInstanceId(options.getBigtableInstanceId())
        .withTableId(options.getBigtableTableId())
        .withConfiguration(BigtableOptionsFactory.BIGTABLE_ENABLE_BULK_MUTATION_FLOW_CONTROL,
            "true")
        .build();
return bigtableTableConfig;

Di seguito è riportato l'esempio di scrittura completo, inclusa la variante che abilita il controllo del flusso di scrittura batch.


import com.google.cloud.bigtable.beam.CloudBigtableIO;
import com.google.cloud.bigtable.beam.CloudBigtableTableConfiguration;
import com.google.cloud.bigtable.hbase.BigtableOptionsFactory;
import org.apache.beam.runners.dataflow.options.DataflowPipelineOptions;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.options.Default;
import org.apache.beam.sdk.options.Description;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.Create;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.hadoop.hbase.client.Mutation;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;

public class HelloWorldWrite {

  public static void main(String[] args) {
    BigtableOptions options =
        PipelineOptionsFactory.fromArgs(args).withValidation().as(BigtableOptions.class);
    Pipeline p = Pipeline.create(options);

    CloudBigtableTableConfiguration bigtableTableConfig =
        new CloudBigtableTableConfiguration.Builder()
            .withProjectId(options.getBigtableProjectId())
            .withInstanceId(options.getBigtableInstanceId())
            .withTableId(options.getBigtableTableId())
            .build();

    p.apply(Create.of("phone#4c410523#20190501", "phone#4c410523#20190502"))
        .apply(
            ParDo.of(
                new DoFn<String, Mutation>() {
                  @ProcessElement
                  public void processElement(@Element String rowkey, OutputReceiver<Mutation> out) {
                    long timestamp = System.currentTimeMillis();
                    Put row = new Put(Bytes.toBytes(rowkey));

                    row.addColumn(
                        Bytes.toBytes("stats_summary"),
                        Bytes.toBytes("os_build"),
                        timestamp,
                        Bytes.toBytes("android"));
                    out.output(row);
                  }
                }))
        .apply(CloudBigtableIO.writeToTable(bigtableTableConfig));

    p.run().waitUntilFinish();
  }

  public interface BigtableOptions extends DataflowPipelineOptions {

    @Description("The Bigtable project ID, this can be different than your Dataflow project")
    @Default.String("bigtable-project")
    String getBigtableProjectId();

    void setBigtableProjectId(String bigtableProjectId);

    @Description("The Bigtable instance ID")
    @Default.String("bigtable-instance")
    String getBigtableInstanceId();

    void setBigtableInstanceId(String bigtableInstanceId);

    @Description("The Bigtable table ID in the instance.")
    @Default.String("mobile-time-series")
    String getBigtableTableId();

    void setBigtableTableId(String bigtableTableId);
  }

  public static CloudBigtableTableConfiguration batchWriteFlowControlExample(
      BigtableOptions options) {
    CloudBigtableTableConfiguration bigtableTableConfig =
        new CloudBigtableTableConfiguration.Builder()
            .withProjectId(options.getBigtableProjectId())
            .withInstanceId(options.getBigtableInstanceId())
            .withTableId(options.getBigtableTableId())
            .withConfiguration(BigtableOptionsFactory.BIGTABLE_ENABLE_BULK_MUTATION_FLOW_CONTROL,
                "true")
            .build();
    return bigtableTableConfig;
  }
}