HBase avec Java

1. Vue d’ensemble

Dans cet article, nous examinerons la bibliothèque de clients Java de base de données HBase . HBase est une base de données distribuée qui utilise le système de fichiers Hadoop pour stocker des données.

Nous allons créer un exemple de client Java et une table à laquelle nous ajouterons quelques enregistrements simples.

2. Structure de données HBase

Dans HBase, les données sont regroupées en familles de colonnes. Tous les membres de colonne d’une famille de colonnes ont le même préfixe.

Par exemple, les colonnes family1: qualifier1 et family1: qualifier2 sont deux membres de la famille de colonnes family1 . Tous les membres de la famille de colonnes sont stockés ensemble sur le système de fichiers.

Dans la famille de colonnes, nous pouvons placer une ligne ayant un qualificatif spécifié. Nous pouvons considérer un qualificatif comme une sorte de nom de colonne.

Voyons un exemple d’enregistrement de Hbase:

Family1:{
   'Qualifier1':'row1:cell__data',
   'Qualifier2':'row2:cell__data',
   'Qualifier3':'row3:cell__data'
}
Family2:{
   'Qualifier1':'row1:cell__data',
   'Qualifier2':'row2:cell__data',
   'Qualifier3':'row3:cell__data'
}

Nous avons deux familles de colonnes, chacune d’elles ayant trois qualificatifs contenant des données de cellule. Chaque ligne a une clé de ligne - c’est un identifiant de ligne unique.

Nous utiliserons la clé de ligne pour insérer, récupérer et supprimer les données.

3. Dépendance Maven du client HBase

Avant de nous connecter à HBase, nous devons ajouter https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.apache.hbase%22%20AND%20a%3A%22hbase- client% 22[ hbase-client ]et hbase dépendances:

<dependency>
    <groupId>org.apache.hbase</groupId>
    <artifactId>hbase-client</artifactId>
    <version>${hbase.version}</version>
</dependency>
<dependency>
     <groupId>org.apache.hbase</groupId>
     <artifactId>hbase</artifactId>
     <version>${hbase.version}</version>
</dependency>

4. Configuration HBase

Nous devons configurer HBase pour pouvoir nous connecter à partir d’une bibliothèque client Java. L’installation n’entre pas dans le cadre de cet article, mais vous pouvez consulter certaines des installations de HBase à l’adresse guides online .

Ensuite, nous devons démarrer un maître HBase localement en exécutant:

hbase master start

5. Connexion à HBase à partir de Java

Pour vous connecter par programme de Java à HBase, vous devez définir un fichier de configuration XML. Nous avons démarré notre instance HBase sur localhost, nous devons donc la saisir dans un fichier de configuration:

<configuration>
    <property>
        <name>hbase.zookeeper.quorum</name>
        <value>localhost</value>
    </property>
    <property>
        <name>hbase.zookeeper.property.clientPort</name>
        <value>2181</value>
    </property>
</configuration>

Nous devons maintenant diriger un client HBase vers ce fichier de configuration:

Configuration config = HBaseConfiguration.create();

String path = this.getClass()
  .getClassLoader()
  .getResource("hbase-site.xml")
  .getPath();
config.addResource(new Path(path));

Ensuite, nous vérifions si une connexion à HBase a réussi. Dans le cas d’une défaillance, l’exception MasterNotRunningException sera levée:

HBaseAdmin.checkHBaseAvailable(config);

6. Création d’une structure de base de données

Avant de commencer à ajouter des données à HBase, nous devons créer la structure de données pour insérer des lignes. Nous allons créer une table avec deux familles de colonnes:

private TableName table1 = TableName.valueOf("Table1");
private String family1 = "Family1";
private String family2 = "Family2";

Tout d’abord, nous devons créer une connexion à la base de données et obtenir l’objet admin , que nous utiliserons pour manipuler une structure de base de données:

Connection connection = ConnectionFactory.createConnection(config)
Admin admin = connection.getAdmin();

Ensuite, nous pouvons créer une table en transmettant une instance de la classe HTableDescriptor à une méthode createTable () sur l’objet admin :

HTableDescriptor desc = new HTableDescriptor(table1);
desc.addFamily(new HColumnDescriptor(family1));
desc.addFamily(new HColumnDescriptor(family2));
admin.createTable(desc);

7. Ajout et récupération d’éléments

Avec la table créée, nous pouvons y ajouter de nouvelles données en créant un objet Put et en appelant une méthode put () sur l’objet Table :

byte[]row1 = Bytes.toBytes("row1")
Put p = new Put(row1);
p.addImmutable(family1.getBytes(), qualifier1, Bytes.toBytes("cell__data"));
table1.put(p);

La récupération de la ligne créée précédemment peut être réalisée à l’aide d’une classe Get :

Get g = new Get(row1);
Result r = table1.get(g);
byte[]value = r.getValue(family1.getBytes(), qualifier1);

Row1 est un identifiant de ligne - nous pouvons l’utiliser pour récupérer une ligne spécifique de la base de données. Lorsque vous appelez:

Bytes.bytesToString(value)

le résultat retourné sera précédemment le cell data.__ inséré

8. Numérisation et filtrage

Nous pouvons analyser la table et récupérer tous les éléments d’un qualificatif donné à l’aide d’un objet Scan (notez que ResultScanner étend Closable , assurez-vous d’appeler close () lorsque vous avez terminé):

Scan scan = new Scan();
scan.addColumn(family1.getBytes(), qualifier1);

ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
    System.out.println("Found row: " + result);
}

Cette opération imprimera toutes les lignes à l’intérieur d’un qualifier1 avec des informations supplémentaires telles que l’horodatage:

Found row: keyvalues={Row1/Family1:Qualifier1/1488202127489/Put/vlen=9/seqid=0}

Nous pouvons récupérer des enregistrements spécifiques en utilisant des filtres.

Tout d’abord, nous créons deux filtres. Filter1 spécifie que la requête d’analyse extraira les éléments supérieurs à row1, et filter2 spécifie que nous ne sommes intéressés que par les lignes ayant un qualificatif égal à qualifier1 :

Filter filter1 = new PrefixFilter(row1);
Filter filter2 = new QualifierFilter(
  CompareOp.GREATER__OR__EQUAL,
  new BinaryComparator(qualifier1));
List<Filter> filters = Arrays.asList(filter1, filter2);

Ensuite, nous pouvons obtenir un ensemble de résultats à partir d’une requête Scan :

Scan scan = new Scan();
scan.setFilter(new FilterList(Operator.MUST__PASS__ALL, filters));

try (ResultScanner scanner = table.getScanner(scan)) {
    for (Result result : scanner) {
        System.out.println("Found row: " + result);
    }
}

Lors de la création d’un FilterList , nous avons passé un Operator.MUST PASS ALL - cela signifie que tous les filtres doivent être satisfaits. Nous pouvons choisir une Operation.MUST PASS ONE si un seul filtre doit être satisfait. Dans l’ensemble résultant, nous n’aurons que des lignes correspondant aux filtres spécifiés.

9. Suppression de lignes

Enfin, pour supprimer une ligne, nous pouvons utiliser une classe Delete :

Delete delete = new Delete(row1);
delete.addColumn(family1.getBytes(), qualifier1);
table.delete(delete);

Nous supprimons un row1 qui réside dans une family1.

10. Conclusion

Dans ce rapide tutoriel, nous nous sommes concentrés sur la communication avec une base de données HBase. Nous avons vu comment se connecter à HBase à partir de la bibliothèque client Java et comment exécuter diverses opérations de base.

Vous trouverez la mise en œuvre de tous ces exemples et extraits de code dans le projet GitHub ; C’est un projet Maven, il devrait donc être facile à importer et à exécuter tel quel.