Exemple : Application "Hello World" utilisant les API HBase pour Java

Cet exemple est une application "Hello World" simple qui utilise la bibliothèque cliente Cloud Bigtable HBase pour Java, et montre comment :

  • se connecter à une instance Cloud Bigtable ;
  • créer une table ;
  • Écrire des données dans une table
  • Relire les données
  • Supprimer la table

Exécuter l'exemple

L'exemple utilise les API HBase pour communiquer avec Cloud Bigtable. Le code de cet exemple se trouve dans le dépôt GitHub GoogleCloudPlatform/cloud-bigtable-examples, dans le répertoire java/hello-world.

Pour exécuter ce programme, suivez les instructions de l'exemple sur GitHub.

Utiliser les API HBase

L'exemple d'application permet de se connecter à Cloud Bigtable et décrit quelques opérations simples.

Installer et importer la bibliothèque cliente

Cet exemple utilise le client Cloud Bigtable HBase pour Java, ainsi que Maven. Consultez les instructions d'utilisation de la bibliothèque cliente.

L'exemple utilise les importations suivantes :

import com.google.cloud.bigtable.hbase.BigtableConfiguration;

import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

Se connecter à Cloud Bigtable

Connectez-vous à Cloud Bigtable en utilisant la classe BigtableConfiguration.

// Create the Bigtable connection, use try-with-resources to make sure it gets closed
try (Connection connection = BigtableConfiguration.connect(projectId, instanceId)) {

  // The admin API lets us create, manage and delete tables
  Admin admin = connection.getAdmin();

Créer une table

Utilisez l'API Admin pour créer une table.

// Create a table with a single column family
HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(TABLE_NAME));
descriptor.addFamily(new HColumnDescriptor(COLUMN_FAMILY_NAME));

print("Create table " + descriptor.getNameAsString());
admin.createTable(descriptor);

Écrire des lignes dans une table

Utilisez la classe Table pour placer des lignes dans la table. Pour améliorer le débit, envisagez d'utiliser la classe BigtableBufferedMutator.

// Retrieve the table we just created so we can do some reads and writes
Table table = connection.getTable(TableName.valueOf(TABLE_NAME));

// Write some rows to the table
print("Write some greetings to the table");
for (int i = 0; i < GREETINGS.length; i++) {
  // Each row has a unique row key.
  //
  // Note: This example uses sequential numeric IDs for simplicity, but
  // this can result in poor performance in a production application.
  // Since rows are stored in sorted order by key, sequential keys can
  // result in poor distribution of operations across nodes.
  //
  // For more information about how to design a Bigtable schema for the
  // best performance, see the documentation:
  //
  //     https://cloud.google.com/bigtable/docs/schema-design
  String rowKey = "greeting" + i;

  // Put a single row into the table. We could also pass a list of Puts to write a batch.
  Put put = new Put(Bytes.toBytes(rowKey));
  put.addColumn(COLUMN_FAMILY_NAME, COLUMN_NAME, Bytes.toBytes(GREETINGS[i]));
  table.put(put);
}

Lire une ligne à l'aide de sa clé

Obtenez une ligne directement en utilisant sa clé.

// Get the first greeting by row key
String rowKey = "greeting0";
Result getResult = table.get(new Get(Bytes.toBytes(rowKey)));
String greeting = Bytes.toString(getResult.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME));
System.out.println("Get a single greeting by row key");
System.out.printf("\t%s = %s\n", rowKey, greeting);

Analyser toutes les lignes de la table

Utilisez la classe Scan pour obtenir une plage de lignes.

// Now scan across all rows.
Scan scan = new Scan();

print("Scan for all greetings:");
ResultScanner scanner = table.getScanner(scan);
for (Result row : scanner) {
  byte[] valueBytes = row.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME);
  System.out.println('\t' + Bytes.toString(valueBytes));
}

Supprimer une table

Supprimez une table à l'aide de l'API Admin.

// Clean up by disabling and then deleting the table
print("Delete the table");
admin.disableTable(table.getName());
admin.deleteTable(table.getName());

Synthèse

Voici l'exemple complet sans commentaires.

package com.example.cloud.bigtable.helloworld;

import com.google.cloud.bigtable.hbase.BigtableConfiguration;

import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;

public class HelloWorld {

  private static final byte[] TABLE_NAME = Bytes.toBytes("Hello-Bigtable");
  private static final byte[] COLUMN_FAMILY_NAME = Bytes.toBytes("cf1");
  private static final byte[] COLUMN_NAME = Bytes.toBytes("greeting");

  private static final String[] GREETINGS = {
    "Hello World!", "Hello Cloud Bigtable!", "Hello HBase!"
  };

  private static void doHelloWorld(String projectId, String instanceId) {

    try (Connection connection = BigtableConfiguration.connect(projectId, instanceId)) {

      Admin admin = connection.getAdmin();

      try {
        HTableDescriptor descriptor = new HTableDescriptor(TableName.valueOf(TABLE_NAME));
        descriptor.addFamily(new HColumnDescriptor(COLUMN_FAMILY_NAME));

        print("Create table " + descriptor.getNameAsString());
        admin.createTable(descriptor);

        Table table = connection.getTable(TableName.valueOf(TABLE_NAME));

        print("Write some greetings to the table");
        for (int i = 0; i < GREETINGS.length; i++) {
          String rowKey = "greeting" + i;

          Put put = new Put(Bytes.toBytes(rowKey));
          put.addColumn(COLUMN_FAMILY_NAME, COLUMN_NAME, Bytes.toBytes(GREETINGS[i]));
          table.put(put);
        }

        String rowKey = "greeting0";
        Result getResult = table.get(new Get(Bytes.toBytes(rowKey)));
        String greeting = Bytes.toString(getResult.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME));
        System.out.println("Get a single greeting by row key");
        System.out.printf("\t%s = %s\n", rowKey, greeting);

        Scan scan = new Scan();

        print("Scan for all greetings:");
        ResultScanner scanner = table.getScanner(scan);
        for (Result row : scanner) {
          byte[] valueBytes = row.getValue(COLUMN_FAMILY_NAME, COLUMN_NAME);
          System.out.println('\t' + Bytes.toString(valueBytes));
        }

        print("Delete the table");
        admin.disableTable(table.getName());
        admin.deleteTable(table.getName());
      } catch (IOException e) {
        if (admin.tableExists(TableName.valueOf(TABLE_NAME))) {
          print("Cleaning up table");
          admin.disableTable(TableName.valueOf(TABLE_NAME));
          admin.deleteTable(TableName.valueOf(TABLE_NAME));
        }
        throw e;
      }
    } catch (IOException e) {
      System.err.println("Exception while running HelloWorld: " + e.getMessage());
      e.printStackTrace();

      System.exit(1);
    }

    System.exit(0);
  }

  private static void print(String msg) {
    System.out.println("HelloWorld: " + msg);
  }

  public static void main(String[] args) {
    String projectId = requiredProperty("bigtable.projectID");
    String instanceId = requiredProperty("bigtable.instanceID");

    doHelloWorld(projectId, instanceId);
  }

  private static String requiredProperty(String prop) {
    String value = System.getProperty(prop);
    if (value == null) {
      throw new IllegalArgumentException("Missing required system property: " + prop);
    }
    return value;
  }
}