Det finns olika sätt att komma åt och interagera med Apache HBase. Mest anmärkningsvärt är att Java API ger mest funktionalitet. Men vissa vill använda HBase utan Java.
Dessa personer har två huvudalternativ:Det ena är Thrift-gränssnittet (det lättare och därmed snabbare av de två alternativen), och det andra är REST-gränssnittet (aka Stargate). Ett REST-gränssnitt använder HTTP-verb för att utföra en åtgärd. Genom att använda HTTP erbjuder ett REST-gränssnitt ett mycket bredare utbud av språk och program som kan komma åt gränssnittet. (Om du vill ha mer information om REST-gränssnittet kan du gå till min serie med instruktioner om det.)
I den här serien med instruktioner kommer du att lära dig runt Thrift-gränssnittet och utforska Python-kodexempel för att göra det. Det här första inlägget kommer att täcka HBase Thrift, att arbeta med Thrift, och en del kod för att ansluta till Thrift. Det andra inlägget kommer att visa hur man infogar och får flera rader åt gången. Det tredje inlägget kommer att förklara hur man använder skanningar och några överväganden när man väljer mellan REST och Thrift.
De fullständiga kodexemplen finns på mitt GitHub-konto.
HBase Thrift
Thrift är ett mjukvaruramverk som låter dig skapa bindningar på flera språk. I HBase-sammanhang är Java den enda förstklassiga medborgaren. HBase Thrift-gränssnittet tillåter dock att andra språk får åtkomst till HBase över Thrift genom att ansluta till en Thrift-server som ansluter till Java-klienten.
För att både Thrift och REST ska fungera måste en annan HBase-demon vara igång för att hantera dessa förfrågningar. Dessa demoner kan installeras med paketen hbase-thrift och hbase-rest. Diagrammet nedan visar hur Thrift och REST placeras i klustret.
Observera att Thrift- och REST-klientvärdarna vanligtvis inte kör några andra tjänster (som DataNodes eller RegionServers) för att hålla omkostnaderna låga och lyhördheten hög för REST- eller Thrift-interaktioner.
Se till att installera och starta dessa demoner på noder som har tillgång till både Hadoop-klustret och applikationen som behöver åtkomst till HBase. Thrift-gränssnittet har ingen inbyggd lastbalansering, så all lastbalansering kommer att behöva göras med externa verktyg såsom DNS round-robin, en virtuell IP-adress eller i kod. Cloudera Manager gör det också väldigt enkelt att installera och hantera HBase REST- och Thrift-tjänsterna. Du kan ladda ner och prova det gratis i Cloudera Standard!
Nackdelen med Thrift är att det är svårare att ställa in än REST. Du kommer att behöva kompilera Thrift och generera de språkspecifika bindningarna. Dessa bindningar är trevliga eftersom de ger dig kod för språket du arbetar på - det finns inget behov av att analysera XML eller JSON som i REST; snarare ger Thrift-gränssnittet dig direkt tillgång till raddata. En annan trevlig funktion är att Thrift-protokollet har inbyggd binär transport; du behöver inte base64 koda och avkoda data.
För att börja använda Thrift-gränssnittet måste du ta reda på vilken port det körs på. Standardporten för CDH är port 9090. För det här inlägget ser du värd- och portvariablerna som används, här är värdena vi kommer att använda:
host = "localhost" port = "9090"
Du kan konfigurera Thrift-gränssnittet för att använda Kerberos-uppgifter för bättre säkerhet.
För din kod måste du använda IP-adressen eller det fullständiga domännamnet för noden och porten som kör Thrift-demonen. Jag rekommenderar starkt att du gör den här webbadressen till en variabel eftersom den kan ändras med nätverksändringar.
Språkbindningar
Innan du kan skapa Thrift-bindningar måste du ladda ner och kompilera Thrift. Det finns inga binära paket för Thrift som jag kunde hitta, förutom på Windows. Du måste följa Thrifts instruktioner för installationen på din plattform.
När Thrift är installerat måste du hitta filen Hbase.thrift. För att definiera tjänsterna och datatyperna i Thrift måste du skapa en IDL-fil. Lyckligtvis har HBase-utvecklarna redan skapat en åt oss. Tyvärr distribueras inte filen som en del av CDH binära paket. (Vi kommer att fixa det i en framtida CDH-version.) Du måste ladda ner källkodspaketet för den HBase-version du använder. Se till att använda rätt version av HBase eftersom denna IDL kan ändras. I den komprimerade filen är sökvägen till IDL hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift.
Thrift stöder generering av språkbindningar för mer än 14 språk inklusive Java, C++, Python, PHP, Ruby och C#. För att generera bindningarna för Python, skulle du använda följande kommando:
thrift -gen py /path/to/hbase/source/hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Därefter måste du skaffa Thrift-koden för ditt språk som innehåller alla klasser för anslutning till Thrift och dess protokoll. Den här koden finns på /path/to/thrift/thrift-0.9.0/lib/py/src/.
Här är kommandona jag körde för att skapa ett Python-projekt för att använda HBase Thrift:
$ 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/
Jag gillar att behålla en kopia av filen Hbase.thrift i projektet att hänvisa till. Den har mycket "Javadoc" på de olika anropen, dataobjekten och returobjekten.
$ cp ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Boilerplate Code
Du kommer att upptäcka att alla dina Python Thrift-skript kommer att se väldigt lika ut. Låt oss gå igenom varje del.
from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol from thrift.transport import TTransport from hbase import Hbase
Dessa kommer att importera Thrift- och HBase-modulerna du behöver.
# Connect to HBase Thrift server transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port)) protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
Detta skapar socket-transport- och linjeprotokollet och tillåter Thrift-klienten att ansluta och prata med Thrift-servern.
# Create and open the client connection client = Hbase.Client(protocol) transport.open()
Dessa rader skapar klientobjektet som du kommer att använda för att interagera med HBase. Från detta klientobjekt kommer du att utfärda alla dina Gets och Puts. Öppna sedan uttaget till Thrift-servern.
# Do Something
Därefter kommer du faktiskt att arbeta med HBase-klienten. Allt är konstruerat, initierat och kopplat. Börja först använda klienten.
transport.close()
Stäng slutligen transporten. Detta stänger socket och frigör resurserna på Thrift-servern. Här är koden i sin helhet för enkel kopiering och inklistring:
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()
I HBase Thrifts Python-implementering skickas alla värden runt som strängar. Detta inkluderar binära data som ett heltal. Alla kolumnvärden hålls i TCell-objektet. Här är definitionen i filen Hbase.thrift:
struct TCell{ 1:Bytes value, 2:i64 timestamp }
Lägg märke till ändringen av en sträng när Python-koden genereras:
thrift_spec = ( None, # 0 (1, TType.STRING, 'value', None, None, ), # 1 (2, TType.I64, 'timestamp', None, None, ), # 2 )
Jag skrev en hjälpmetod för att göra det lättare att hantera 32-bitars heltal. För att ändra ett heltal fram och tillbaka mellan en sträng använder du dessa två metoder.
# 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]
Ha denna varning i åtanke när du arbetar med binär data i Thrift. Du måste konvertera binära data till strängar och vice versa.
Fel
Det är inte så lätt som det skulle kunna vara att förstå fel i Thrift-gränssnittet. Till exempel, här är felet som kommer ut från Python när en tabell inte hittas:
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')
Allt är dock inte förlorat eftersom du kan titta på HBase Thrift-loggfilen. På CDH finns den här filen på /var/log/hbase/hbase-hbase-thrift-localhost.localdomain.log. I exemplet med saknad tabell skulle du se ett fel i sparsamhetsloggen som säger att tabellen inte existerar. Det är obekvämt, men du kan felsöka därifrån.
I nästa omgång kommer jag att täcka insättning och hämta rader.
Jesse Anderson är instruktör för Cloudera University.