HBase mit Java

1. Übersicht

In diesem Artikel befassen wir uns mit der Java-Client-Bibliothek der HBase- Datenbank. HBase ist eine verteilte Datenbank, die das Hadoop-Dateisystem zum Speichern von Daten verwendet.

Wir erstellen einen Java-Beispielclient und eine Tabelle, zu der wir einige einfache Datensätze hinzufügen.

2. HBase-Datenstruktur

In HBase werden Daten in Spaltenfamilien gruppiert. Alle Spaltenmitglieder einer Spaltenfamilie haben dasselbe Präfix.

Beispielsweise sind die Spalten family1: qualifier1 und family1 : qualifier2 beide Mitglieder der Spaltenfamilie family1 . Alle Mitglieder der Spaltenfamilie werden zusammen im Dateisystem gespeichert.

Innerhalb der Spaltenfamilie können wir eine Zeile mit einem bestimmten Qualifikationsmerkmal einfügen. Wir können uns ein Qualifikationsmerkmal als eine Art Spaltennamen vorstellen.

Sehen wir uns einen Beispieldatensatz von Hbase an:

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' }

Wir haben zwei Spaltenfamilien, von denen jede drei Qualifikationsmerkmale mit einigen Zellendaten enthält. Jede Zeile hat einen Zeilenschlüssel - es ist eine eindeutige Zeilenkennung. Wir werden den Zeilenschlüssel verwenden, um die Daten einzufügen, abzurufen und zu löschen.

3. HBase Client Maven-Abhängigkeit

Bevor wir eine Verbindung zur HBase herstellen, müssen wir hbase-client- und hbase- Abhängigkeiten hinzufügen :

 org.apache.hbase hbase-client ${hbase.version}   org.apache.hbase hbase ${hbase.version} 

4. HBase-Setup

Wir müssen HBase einrichten, um eine Verbindung von einer Java-Clientbibliothek zu HBase herstellen zu können. Die Installation fällt nicht in den Geltungsbereich dieses Artikels. Sie können jedoch einige der HBase-Installationshandbücher online lesen.

Als nächstes müssen wir einen HBase-Master lokal starten, indem wir Folgendes ausführen:

hbase master start

5. Herstellen einer Verbindung zu HBase von Java aus

Um eine programmgesteuerte Verbindung von Java zu HBase herzustellen, müssen Sie eine XML-Konfigurationsdatei definieren. Wir haben unsere HBase-Instanz auf localhost gestartet, daher müssen wir diese in eine Konfigurationsdatei eingeben:

  hbase.zookeeper.quorum localhost   hbase.zookeeper.property.clientPort 2181   

Jetzt müssen wir einen HBase-Client auf diese Konfigurationsdatei verweisen:

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

Als nächstes prüfen wir, ob eine Verbindung zu HBase erfolgreich war. Im Falle eines Fehlers wird die MasterNotRunningException ausgelöst:

HBaseAdmin.checkHBaseAvailable(config);

6. Erstellen einer Datenbankstruktur

Bevor wir anfangen, Daten zu HBase hinzuzufügen, müssen wir die Datenstruktur zum Einfügen von Zeilen erstellen. Wir werden eine Tabelle mit zwei Spaltenfamilien erstellen:

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

Zunächst müssen wir eine Verbindung zur Datenbank herstellen und ein Admin- Objekt abrufen , das wir zum Bearbeiten einer Datenbankstruktur verwenden:

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

Anschließend können wir eine Tabelle erstellen, indem wir eine Instanz der HTableDescriptor- Klasse an eine createTable () -Methode für das admin- Objekt übergeben:

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

7. Hinzufügen und Abrufen von Elementen

Mit der erstellten Tabelle können wir neue Daten hinzufügen, indem wir ein Put- Objekt erstellen und eine put () -Methode für das Table- Objekt aufrufen :

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

Das Abrufen zuvor erstellter Zeilen kann mithilfe einer Get- Klasse erreicht werden:

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

Die Zeile1 ist eine Zeilenkennung - wir können sie verwenden, um eine bestimmte Zeile aus der Datenbank abzurufen. Beim Anruf:

Bytes.bytesToString(value)

Das zurückgegebene Ergebnis sind zuvor die eingefügten cell_data.

8. Scannen und Filtern

Wir können die Tabelle scannen und alle Elemente innerhalb eines bestimmten Qualifikationsmerkmals mithilfe eines Scan- Objekts abrufen (beachten Sie, dass ResultScanner Closable erweitert. Rufen Sie daher unbedingt close () auf, wenn Sie fertig sind):

Scan scan = new Scan(); scan.addColumn(family1.getBytes(), qualifier1); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { System.out.println("Found row: " + result); } 

Diese Operation druckt alle Zeilen innerhalb eines Qualifizierers1 mit einigen zusätzlichen Informationen wie dem Zeitstempel:

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

Wir können bestimmte Datensätze mithilfe von Filtern abrufen.

Zunächst erstellen wir zwei Filter. Der Filter1 gibt an, dass bei der Scanabfrage Elemente abgerufen werden, die größer als Zeile1 sind, und der Filter2 gibt an, dass wir nur an Zeilen interessiert sind, deren Qualifizierer dem Qualifizierer1 entspricht :

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

Then we can get a result set from a Scan query:

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

When creating a FilterList we passed an Operator.MUST_PASS_ALL – it means that all filters must be satisfied. We can choose an Operation.MUST_PASS_ONE if only one filter needs to be satisfied. In the resulting set, we will have only rows that matched specified filters.

9. Deleting Rows

Finally, to delete a row, we can use a Delete class:

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

We're deleting a row1 that resides inside of a family1.

10. Conclusion

In this quick tutorial, we focused on communicated with a HBase database. We saw how to connect to HBase from the Java client library and how to run various basic operations.

Die Implementierung all dieser Beispiele und Codefragmente finden Sie im GitHub-Projekt. Da es sich um ein Maven-Projekt handelt, sollte es einfach zu importieren und auszuführen sein.