Det finns olika sätt att komma åt och interagera med Apache HBase. Java API ger mest funktionalitet, men många vill använda HBase utan Java.
Det finns två huvudsakliga metoder för att göra det: Det ena är Thrift-gränssnittet, som är det snabbare och lättare av de två alternativen. Det andra sättet att komma åt HBase är att använda REST-gränssnittet, som använder HTTP-verb för att utföra en åtgärd, vilket ger utvecklare ett brett urval av språk och program att använda.
Denna serie av instruktioner kommer att diskutera REST-gränssnittet och tillhandahålla Python-kodexempel för åtkomst till det. Det första inlägget kommer att täcka HBase REST, några Python-förbehåll och bordsadministration. Det andra inlägget kommer att förklara hur man infogar flera rader åt gången med XML och JSON. Det tredje inlägget kommer att visa hur man får flera rader med XML och JSON. De fullständiga kodexemplen finns på mitt GitHub-konto.
HBase REST Grunderna
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 i paketen hbase-thrift och hbase-rest. Diagrammet nedan illustrerar var Thrift och REST är placerade i klustret. Observera att Thrift- och REST-klienterna vanligtvis inte kör några andra tjänster som DataNode eller RegionServers för att hålla nere belastningen och lyhördheten hög, för REST-interaktioner.
Se till att installera och starta dessa demoner på noder som har tillgång till både Hadoop-klustret och webbapplikationsservern. REST-gränssnittet har ingen inbyggd lastbalansering; som kommer att behöva göras med hårdvara eller i kod. Cloudera Manager gör det väldigt enkelt att installera och hantera HBase REST- och Thrift-tjänsterna. (Du kan ladda ner och prova det gratis!) Nackdelen med REST är att den är mycket tyngre än Thrift eller Java.
Ett REST-gränssnitt kan använda olika dataformat:XML, JSON och protobuf. Genom att ange Accept
och Content-Type
rubriker kan du välja vilket format du vill skicka in eller få tillbaka.
För att börja använda REST-gränssnittet måste du ta reda på vilken port det körs på. Standardporten för CDH är port 8070. För det här inlägget ser du baseurl
variabel används, och här är värdet jag kommer att använda::
baseurl = "http://localhost:8070"
REST-gränssnittet kan ställas in för att använda Kerberos-uppgifter för att öka säkerheten.
För din kod måste du använda IP-adressen eller det fullständigt kvalificerade domännamnet DNS för noden som kör REST-demonen. Kontrollera också att porten är korrekt. Jag rekommenderar starkt att du gör den här webbadressen till en variabel, eftersom den kan ändras med nätverksändringar.
Python och HBase bugglösningar
Det finns två buggar och lösningar som måste åtgärdas. Det första felet är att de inbyggda Python-modulerna inte stöder alla HTTP-verb. Den andra är en HBase REST-bugg när man arbetar med JSON.
De inbyggda Python-modulerna för REST-interaktion stöder inte lätt alla HTTP-verb som behövs för HBase REST. Du måste installera Python-begäran-modulen. Begäran modulen rensar också upp koden och gör alla interaktioner mycket enklare.
HBase REST-gränssnittet har en bugg när man lägger till data via JSON:det krävs att fälten bibehåller sin exakta ordning. Den inbyggda Python dict
typ stöder inte den här funktionen, så för att behålla ordningen måste vi använda OrderedDict
klass. (De med Python 2.6 och äldre kommer att behöva installera ordereddict-modulen.) Jag kommer också att ta upp buggen och lösningen senare i inlägget.
Det var också svårt att använda base64-koda och avkoda heltal, så jag skrev lite kod för att göra det:
# Method for encoding ints with base64 encoding def encode(n): data = struct.pack("i", n) s = base64.b64encode(data) return s # Method for decoding ints with base64 encoding def decode(s): data = base64.b64decode(s) n = struct.unpack("i", data) return n[0]
För att göra saker ännu enklare skrev jag en metod för att bekräfta att HTTP-svar kommer tillbaka på 200-talet, vilket tyder på att operationen fungerade. Exempelkoden använder den här metoden för att kontrollera framgången för ett samtal innan du går vidare. Här är metoden:
# Checks the request object to see if the call was successful def issuccessful(request): if 200
Arbeta med tabeller
Med REST-gränssnittet kan du skapa eller ta bort tabeller. Låt oss ta en titt på koden för att skapa en tabell.
content = '' content += '' content += ' ' content += '' request = requests.post(baseurl + "/" + tablename + "/schema", data=content, headers={"Content-Type" : "text/xml", "Accept" : "text/xml"})
I det här utdraget skapar vi ett litet XML-dokument som definierar tabellschemat i innehållsvariabeln. Vi måste ange namnet på tabellen och kolumnen efternamn. Om det finns flera kolumnfamiljer skapar du några fler ColumnSchema
noder.
Därefter använder vi modulen förfrågningar för att POST
XML till webbadressen vi skapar. Den här webbadressen måste innehålla namnet på den nya tabellen. Observera också att vi ställer in rubrikerna för denna POST
ringa upp. Vi visar att vi skickar in XML med Content-Type
satt till "text/xml" och att vi vill ha tillbaka XML med Accept
inställd på "text/xml".
Använda request.status_code
, kan du kontrollera att tabellskapandet lyckades. REST-gränssnittet använder samma HTTP-felkoder för att upptäcka om ett anrop lyckades eller misslyckades. En statuskod på 200-talet betyder att saker och ting fungerade korrekt.
Vi kan enkelt kontrollera om en tabell finns med följande kod:
request = requests.get(baseurl + "/" + tablename + "/schema")
Samtalen använder GET
verb för att berätta för REST-gränssnittet vi vill få schemainformationen om tabellen i URL:en. Återigen kan vi använda statuskoden för att se om tabellen finns. En statuskod på 200-talet betyder att den existerar och alla andra nummer betyder att den inte gör det.
Använda curl
kommando, kan vi kontrollera framgången för en REST-operation utan att skriva kod. Följande kommando returnerar en 200 som visar framgången för samtalet eftersom messagestable
tabell finns i HBase. Här är anropet och dess utdata:
[user@localhost]$ curl -I -H "Accept: text/xml" http://localhost:8070/messagestable/schema HTTP/1.1 200 OK Content-Length: 0 Cache-Control: no-cache Content-Type: text/xml
Detta REST-anrop kommer att felas eftersom tablenotthere
tabellen finns inte i HBase. Här är anropet och dess utdata:
[user@localhost]$ curl -I -H "Accept: text/xml" http://localhost:8070/tablenotthere/schema HTTP/1.1 500 org.apache.hadoop.hbase.TableNotFoundException: tablenotthere Content-Type: text/html; charset=iso-8859-1 Cache-Control: must-revalidate,no-cache,no-store Content-Length: 10767
Vi kan ta bort en tabell med följande kod:
request = requests.delete(baseurl + "/" + tablename + "/schema")
Det här anropet använder DELETE
verb för att tala om för REST-gränssnittet att vi vill ta bort tabellen. Att ta bort en tabell via REST-gränssnittet kräver inte att du inaktiverar den först. Som vanligt kan vi bekräfta framgång genom att titta på statuskoden.
I nästa inlägg i den här serien tar vi upp infogning av rader.
Jesse Anderson är instruktör vid Cloudera University.
Om du är intresserad av HBase, se till att registrera dig för HBaseCon 2013 (13 juni, San Francisco) – gemenskapsevenemanget för HBase-bidragsgivare, utvecklare, administratörer och användare. Early Bird-registreringen är öppen fram till den 23 april.