Der er forskellige måder at få adgang til og interagere med Apache HBase på. Mest bemærkelsesværdigt er det, at Java API leverer den mest funktionalitet. Men nogle mennesker ønsker at bruge HBase uden Java.
Disse mennesker har to hovedmuligheder:Den ene er Thrift-grænsefladen (den mere lette og dermed hurtigere af de to muligheder), og den anden er REST-grænsefladen (alias Stargate). En REST-grænseflade bruger HTTP-verber til at udføre en handling. Ved at bruge HTTP tilbyder en REST-grænseflade en meget bredere vifte af sprog og programmer, der kan få adgang til grænsefladen. (Hvis du gerne vil have mere information om REST-grænsefladen, kan du gå til min serie af vejledninger om det.)
I denne serie af how-to's lærer du dig rundt i Thrift-grænsefladen og udforsker Python-kodeeksempler til at gøre det. Dette første indlæg vil dække HBase Thrift, arbejde med Thrift, og en del kode for at oprette forbindelse til Thrift. Det andet indlæg viser, hvordan man indsætter og får flere rækker ad gangen. Det tredje indlæg vil forklare, hvordan man bruger scanninger og nogle overvejelser, når man vælger mellem REST og Thrift.
De fulde kodeeksempler kan findes på min GitHub-konto.
HBase Thrift
Thrift er en softwareramme, der giver dig mulighed for at oprette bindinger på tværs af sprog. I forbindelse med HBase er Java den eneste førsteklasses borger. HBase Thrift-grænsefladen tillader dog andre sprog at få adgang til HBase over Thrift ved at oprette forbindelse til en Thrift-server, der har grænseflader med Java-klienten.
For at både Thrift og REST skal fungere, skal en anden HBase-dæmon køre for at håndtere disse anmodninger. Disse dæmoner kan installeres med hbase-thrift og hbase-rest-pakkerne. Diagrammet nedenfor viser, hvordan Thrift og REST er placeret i klyngen.
Bemærk, at Thrift- og REST-klientværterne normalt ikke kører nogen andre tjenester (såsom DataNodes eller RegionServers) for at holde overhead lavt og høj lydhørhed for REST- eller Thrift-interaktioner.
Sørg for at installere og starte disse dæmoner på noder, der har adgang til både Hadoop-klyngen og den applikation, der har brug for adgang til HBase. Thrift-grænsefladen har ikke nogen indbygget belastningsbalancering, så al belastningsbalancering skal udføres med eksterne værktøjer såsom DNS round-robin, en virtuel IP-adresse eller i kode. Cloudera Manager gør det også rigtig nemt at installere og administrere HBase REST- og Thrift-tjenesterne. Du kan downloade og prøve det gratis i Cloudera Standard!
Ulempen ved Thrift er, at det er sværere at sætte op end REST. Du skal kompilere Thrift og generere de sprogspecifikke bindinger. Disse bindinger er gode, fordi de giver dig kode til det sprog, du arbejder i - der er ingen grund til at parse XML eller JSON som i REST; snarere giver Thrift-grænsefladen dig direkte adgang til rækkedataene. En anden god funktion er, at Thrift-protokollen har indbygget binær transport; du behøver ikke base64 indkode og afkode data.
For at begynde at bruge Thrift-grænsefladen skal du finde ud af, hvilken port den kører på. Standardporten for CDH er port 9090. Til dette indlæg kan du se de anvendte værts- og portvariabler, her er de værdier, vi skal bruge:
host = "localhost" port = "9090"
Du kan konfigurere Thrift-grænsefladen til at bruge Kerberos-legitimationsoplysninger for bedre sikkerhed.
Til din kode skal du bruge IP-adressen eller det fuldt kvalificerede domænenavn på noden og porten, der kører Thrift-dæmonen. Jeg anbefaler stærkt at gøre denne URL til en variabel, da den kan ændre sig med netværksændringer.
Sprogbindinger
Før du kan oprette Thrift-bindinger, skal du downloade og kompilere Thrift. Der er ingen binære pakker til Thrift, som jeg kunne finde, undtagen på Windows. Du skal følge Thrifts instruktioner til installationen på din valgte platform.
Når Thrift er installeret, skal du finde filen Hbase.thrift. For at definere tjenester og datatyper i Thrift skal du oprette en IDL-fil. Heldigvis har HBase-udviklerne allerede skabt en til os. Desværre distribueres filen ikke som en del af CDH binære pakker. (Vi vil rette det i en fremtidig CDH-udgivelse.) Du skal downloade kildepakken til den HBase-version, du bruger. Sørg for at bruge den korrekte version af HBase, da denne IDL kan ændre sig. I den komprimerede fil er stien til IDL hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift.
Thrift understøtter generering af sprogbindinger til mere end 14 sprog, herunder Java, C++, Python, PHP, Ruby og C#. For at generere bindingerne til Python skal du bruge følgende kommando:
thrift -gen py /path/to/hbase/source/hbase-VERSION/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Dernæst skal du hente Thrift-koden til dit sprog, der indeholder alle klasserne til forbindelse til Thrift og dets protokoller. Denne kode kan findes på /path/to/thrift/thrift-0.9.0/lib/py/src/.
Her er de kommandoer, jeg kørte for at oprette et Python-projekt for at bruge 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/
Jeg kan godt lide at beholde en kopi af filen Hbase.thrift i projektet for at referere tilbage til. Den har en masse "Javadoc" på de forskellige opkald, dataobjekter og returobjekter.
$ cp ~/Downloads/hbase-0.94.2-cdh4.2.0/src/main/resources/org/apache/hadoop/hbase/thrift/Hbase.thrift
Boilerplate Code
Du vil opdage, at alle dine Python Thrift-scripts vil ligne meget. Lad os gennemgå hver del.
from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol from thrift.transport import TTransport from hbase import Hbase
Disse vil importere de Thrift- og HBase-moduler, du har brug for.
# Connect to HBase Thrift server transport = TTransport.TBufferedTransport(TSocket.TSocket(host, port)) protocol = TBinaryProtocol.TBinaryProtocolAccelerated(transport)
Dette skaber socket-transport- og linjeprotokollen og giver Thrift-klienten mulighed for at oprette forbindelse og tale med Thrift-serveren.
# Create and open the client connection client = Hbase.Client(protocol) transport.open()
Disse linjer skaber det klientobjekt, du vil bruge til at interagere med HBase. Fra dette klientobjekt vil du udstede alle dine Gets og Puts. Åbn derefter socket til Thrift-serveren.
# Do Something
Dernæst skal du faktisk arbejde med HBase-klienten. Alt er konstrueret, initialiseret og forbundet. Begynd først at bruge klienten.
transport.close()
Luk endelig transporten. Dette lukker for socket og frigør ressourcerne på Thrift-serveren. Her er koden i sin helhed til nem kopiering og indsættelse:
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 sendes alle værdier rundt som strenge. Dette inkluderer binære data som et heltal. Alle kolonneværdier holdes i TCell-objektet. Her er definitionen i filen Hbase.thrift:
struct TCell{ 1:Bytes value, 2:i64 timestamp }
Bemærk ændringen til en streng, når Python-koden genereres:
thrift_spec = ( None, # 0 (1, TType.STRING, 'value', None, None, ), # 1 (2, TType.I64, 'timestamp', None, None, ), # 2 )
Jeg skrev en hjælpemetode for at gøre det nemmere at håndtere 32-bit heltal. For at ændre et heltal frem og tilbage mellem en streng, bruger du disse to 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]
Hold denne advarsel i tankerne, når du arbejder med binære data i Thrift. Du bliver nødt til at konvertere binære data til strenge og omvendt.
Fejl ude
Det er ikke så let, som det kunne være, at forstå fejl i Thrift-grænsefladen. For eksempel, her er fejlen, der kommer ud af Python, når en tabel ikke findes:
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')
Alt er dog ikke tabt, fordi du kan se på HBase Thrift-logfilen. På CDH er denne fil placeret på /var/log/hbase/hbase-hbase-thrift-localhost.localdomain.log. I eksemplet med manglende tabel vil du se en fejl i Thrift-loggen, der siger, at tabellen ikke eksisterer. Det er ubelejligt, men du kan fejlsøge derfra.
I den næste rate dækker jeg indsættelse og hentning af rækker.
Jesse Anderson er instruktør for Cloudera University.