Es gibt verschiedene Möglichkeiten, auf Apache HBase zuzugreifen und mit ihm zu interagieren. Vor allem bietet die Java-API die meisten Funktionen. Aber einige Leute möchten HBase ohne Java verwenden.
Diese Leute haben zwei Hauptoptionen:Eine ist die Thrift-Schnittstelle (die leichtere und damit schnellere der beiden Optionen) und die andere ist die REST-Schnittstelle (auch bekannt als Stargate). Eine REST-Schnittstelle verwendet HTTP-Verben, um eine Aktion auszuführen. Durch die Verwendung von HTTP bietet eine REST-Schnittstelle eine viel größere Auswahl an Sprachen und Programmen, die auf die Schnittstelle zugreifen können. (Wenn Sie weitere Informationen über die REST-Schnittstelle wünschen, können Sie zu meiner Reihe von Anleitungen dazu gehen.)
In dieser Reihe von Anleitungen lernen Sie sich in der Thrift-Oberfläche zurecht und erkunden dafür Python-Codebeispiele. Dieser erste Beitrag behandelt HBase Thrift, die Arbeit mit Thrift und einige Standardcodes für die Verbindung mit Thrift. Der zweite Beitrag zeigt, wie Sie mehrere Zeilen gleichzeitig einfügen und abrufen. Der dritte Beitrag erläutert die Verwendung von Scans und einige Überlegungen bei der Wahl zwischen REST und Thrift.
Die vollständigen Codebeispiele finden Sie in meinem GitHub-Konto.
HBase Sparsamkeit
Thrift ist ein Software-Framework, mit dem Sie sprachübergreifende Bindungen erstellen können. Im Kontext von HBase ist Java der einzige Bürger erster Klasse. Die HBase-Thrift-Schnittstelle ermöglicht jedoch anderen Sprachen den Zugriff auf HBase über Thrift, indem eine Verbindung zu einem Thrift-Server hergestellt wird, der mit dem Java-Client kommuniziert.
Damit sowohl Thrift als auch REST funktionieren, muss ein weiterer HBase-Daemon ausgeführt werden, um diese Anforderungen zu verarbeiten. Diese Daemons können mit den Paketen hbase-thrift und hbase-rest installiert werden. Das folgende Diagramm zeigt, wie Thrift und REST im Cluster platziert werden.
Beachten Sie, dass die Thrift- und REST-Client-Hosts normalerweise keine anderen Dienste (wie DataNodes oder RegionServers) ausführen, um den Overhead niedrig und die Reaktionsfähigkeit für REST- oder Thrift-Interaktionen hoch zu halten.
Stellen Sie sicher, dass Sie diese Daemons auf Knoten installieren und starten, die sowohl Zugriff auf den Hadoop-Cluster als auch auf die Anwendung haben, die Zugriff auf HBase benötigt. Die Thrift-Schnittstelle verfügt über keinen integrierten Lastenausgleich, daher muss der gesamte Lastenausgleich mit externen Tools wie einem DNS-Round-Robin, einer virtuellen IP-Adresse oder im Code erfolgen. Cloudera Manager macht es auch wirklich einfach, die HBase REST- und Thrift-Dienste zu installieren und zu verwalten. Sie können es in Cloudera Standard kostenlos herunterladen und ausprobieren!
Der Nachteil von Thrift ist, dass es schwieriger einzurichten ist als REST. Sie müssen Thrift kompilieren und die sprachspezifischen Bindungen generieren. Diese Bindungen sind nett, weil sie Ihnen Code für die Sprache geben, in der Sie arbeiten – es besteht keine Notwendigkeit, XML oder JSON wie in REST zu parsen; Vielmehr bietet Ihnen die Thrift-Schnittstelle direkten Zugriff auf die Zeilendaten. Ein weiteres nettes Feature ist, dass das Thrift-Protokoll einen nativen binären Transport hat; Sie müssen Daten nicht base64-kodieren und dekodieren.
Um mit der Nutzung der Thrift-Schnittstelle zu beginnen, müssen Sie herausfinden, auf welchem Port sie läuft. Der Standardport für CDH ist Port 9090. Für diesen Beitrag sehen Sie die verwendeten Host- und Portvariablen. Hier sind die Werte, die wir verwenden werden:
host = "localhost" port = "9090"
Sie können die Thrift-Benutzeroberfläche so einrichten, dass Kerberos-Anmeldedaten für eine bessere Sicherheit verwendet werden.
Für Ihren Code müssen Sie die IP-Adresse oder den vollständig qualifizierten Domänennamen des Knotens und den Port verwenden, auf dem der Thrift-Daemon ausgeführt wird. Ich empfehle dringend, diese URL zu einer Variablen zu machen, da sie sich bei Netzwerkänderungen ändern kann.
Sprachbindungen
Bevor Sie Thrift-Bindungen erstellen können, müssen Sie Thrift herunterladen und kompilieren. Es gibt keine Binärpakete für Thrift, die ich finden konnte, außer unter Windows. Sie müssen den Anweisungen von Thrift für die Installation auf der Plattform Ihrer Wahl folgen.
Sobald Thrift installiert ist, müssen Sie die Datei Hbase.thrift finden. Um die Dienste und Datentypen in Thrift zu definieren, müssen Sie eine IDL-Datei erstellen. Glücklicherweise haben die HBase-Entwickler bereits eine für uns erstellt. Leider wird die Datei nicht als Teil der CDH-Binärpakete verteilt. (Wir werden dies in einer zukünftigen CDH-Version beheben.) Sie müssen das Quellpaket der von Ihnen verwendeten HBase-Version herunterladen. Stellen Sie sicher, dass Sie die richtige Version von HBase verwenden, da sich diese IDL ändern kann. In der komprimierten Datei lautet der Pfad zur IDL hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift.
Thrift unterstützt das Generieren von Sprachbindungen für mehr als 14 Sprachen, darunter Java, C++, Python, PHP, Ruby und C#. Um die Bindungen für Python zu generieren, würden Sie den folgenden Befehl verwenden:
thrift -gen py /path/to/hbase/source/hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Als nächstes müssen Sie den Thrift-Code für Ihre Sprache abrufen, der alle Klassen für die Verbindung zu Thrift und seinen Protokollen enthält. Dieser Code befindet sich unter /path/to/thrift/thrift-0.9.0/lib/py/src/.
Hier sind die Befehle, die ich ausgeführt habe, um ein Python-Projekt zur Verwendung von HBase Thrift zu erstellen:
$ mkdir HBaseThrift $ cd HBaseThrift/ $ thrift -gen py ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift $ mv gen-py/* . $ rm -rf gen-py/ $ mkdir thrift $ cp -rp ~/Downloads/thrift-0.9.0/lib/py/src/* ./thrift/
Ich behalte gerne eine Kopie der Hbase.thrift-Datei im Projekt, um darauf zurückgreifen zu können. Es enthält viel „Javadoc“ zu den verschiedenen Aufrufen, Datenobjekten und Rückgabeobjekten.
$ cp ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Boilerplate-Code
Sie werden feststellen, dass alle Ihre Python Thrift-Skripte sehr ähnlich aussehen werden. Lassen Sie uns jeden Teil durchgehen.
from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol from thrift.transport import TTransport from hbase import Hbase
Diese importieren die benötigten Thrift- und HBase-Module.
# Connect to HBase Thrift server transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port)) protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
Dies erstellt das Socket-Transport- und Leitungsprotokoll und ermöglicht dem Thrift-Client, sich mit dem Thrift-Server zu verbinden und mit ihm zu kommunizieren.
# Create and open the client connection client = Hbase.Client(protocol) transport.open()
Diese Zeilen erstellen das Client-Objekt, das Sie für die Interaktion mit HBase verwenden werden. Von diesem Client-Objekt aus geben Sie alle Ihre Gets und Puts aus. Als nächstes öffnen Sie den Socket zum Thrift-Server.
# Do Something
Als Nächstes arbeiten Sie tatsächlich mit dem HBase-Client. Alles ist aufgebaut, initialisiert und verbunden. Beginnen Sie zuerst mit der Verwendung des Clients.
transport.close()
Schließen Sie schließlich den Transport. Dadurch wird der Socket geschlossen und die Ressourcen auf dem Thrift-Server freigegeben. Hier ist der vollständige Code zum einfachen Kopieren und Einfügen:
from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol from thrift.transport import TTransport from hbase import Hbase # Connect to HBase Thrift server transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port)) protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport) # Create and open the client connection client = Hbase.Client(protocol) transport.open() # Do Something transport.close()
In der Python-Implementierung von HBase Thrift werden alle Werte als Zeichenfolgen weitergegeben. Dazu gehören binäre Daten wie eine ganze Zahl. Alle Spaltenwerte werden im TCell-Objekt gespeichert. Hier ist die Definition in der Datei Hbase.thrift:
struct TCell{ 1:Bytes value, 2:i64 timestamp }
Beachten Sie die Änderung einer Zeichenfolge, wenn der Python-Code generiert wird:
thrift_spec = ( None, # 0 (1, TType.STRING, 'value', None, None, ), # 1 (2, TType.I64, 'timestamp', None, None, ), # 2 )
Ich habe eine Hilfsmethode geschrieben, um den Umgang mit 32-Bit-Ganzzahlen zu vereinfachen. Um eine ganze Zahl zwischen einem String hin und her zu wechseln, verwenden Sie diese beiden Methoden.
# Method for encoding ints with Thrift's string encoding def encode(n): return struct.pack("i", n) # Method for decoding ints with Thrift's string encoding def decode(s): return struct.unpack('i', s)[0]
Denken Sie an diesen Vorbehalt, wenn Sie mit Binärdaten in Thrift arbeiten. Sie müssen binäre Daten in Strings umwandeln und umgekehrt.
Fehlermeldung
Es ist nicht so einfach, Fehler in der Thrift-Oberfläche zu verstehen. Hier ist zum Beispiel der Fehler, der von Python ausgegeben wird, wenn eine Tabelle nicht gefunden wird:
Traceback (most recent call last): File "./get.py", line 17, in <module> rows = client.getRow(tablename, "shakespeare-comedies-000001") File "/mnt/hgfs/jesse/repos/DevHivePigHBaseVM/training_materials/hbase/exercises/python_bleets_thrift/hbase/Hbase.py", line 1038, in getRow return self.recv_getRow() File "/mnt/hgfs/jesse/repos/DevHivePigHBaseVM/training_materials/hbase/exercises/python_bleets_thrift/hbase/Hbase.py", line 1062, in recv_getRow raise result.io hbase.ttypes.IOError: IOError(_message='doesnotexist')
Es ist jedoch nicht alles verloren, da Sie sich die HBase Thrift-Protokolldatei ansehen können. Auf CDH befindet sich diese Datei unter /var/log/hbase/hbase-hbase-thrift-localhost.localdomain.log. Im Beispiel für fehlende Tabellen würde im Thrift-Protokoll ein Fehler angezeigt, der besagt, dass die Tabelle nicht existiert. Es ist unpraktisch, aber Sie können von dort aus debuggen.
In der nächsten Ausgabe werde ich das Einfügen und Abrufen von Zeilen behandeln.
Jesse Anderson ist Dozent an der Cloudera University.