Istnieją różne sposoby uzyskiwania dostępu i interakcji z Apache HBase. Java API zapewnia największą funkcjonalność, ale wiele osób chce używać HBase bez Javy.
Istnieją dwa główne podejścia do tego celu:jednym jest interfejs Thrift, który jest szybszy i lżejszy z dwóch opcji. Innym sposobem uzyskania dostępu do HBase jest użycie interfejsu REST, który używa czasowników HTTP do wykonania akcji, dając programistom szeroki wybór języków i programów do użycia.
Ta seria poradników omówi interfejs REST i dostarczy próbki kodu Pythona, aby uzyskać do niego dostęp. Pierwszy post będzie dotyczył HBase REST, niektórych zastrzeżeń Pythona i administrowania tabelami. W drugim poście wyjaśnimy, jak wstawiać wiele wierszy naraz za pomocą XML i JSON. Trzeci post pokaże, jak uzyskać wiele wierszy za pomocą XML i JSON. Pełne próbki kodu można znaleźć na moim koncie GitHub.
Podstawy HBase REST
Aby zarówno Thrift, jak i REST działały, inny demon HBase musi być uruchomiony do obsługi tych żądań. Te demony można zainstalować w pakietach hbase-thrift i hbase-rest. Poniższy diagram ilustruje, gdzie Thrift i REST są umieszczone w klastrze. Zwróć uwagę, że klienci Thrift i REST zwykle nie uruchamiają żadnych innych usług, takich jak DataNode lub RegionServers, aby zmniejszyć obciążenie i wysoką responsywność w przypadku interakcji REST.
Pamiętaj, aby zainstalować i uruchomić te demony w węzłach, które mają dostęp zarówno do klastra Hadoop, jak i do serwera aplikacji sieci Web. Interfejs REST nie ma wbudowanego równoważenia obciążenia; to trzeba będzie zrobić za pomocą sprzętu lub kodu. Cloudera Manager bardzo ułatwia instalację i zarządzanie usługami HBase REST i Thrift. (Możesz pobrać i wypróbować za darmo!) Minusem REST jest to, że jest znacznie cięższy niż Thrift lub Java.
Interfejs REST może używać różnych formatów danych:XML, JSON i protobuf. Określając Accept
i Content-Type
nagłówki, możesz wybrać format, który chcesz przekazać lub odebrać.
Aby zacząć korzystać z interfejsu REST, musisz dowiedzieć się, na którym porcie jest uruchomiony. Domyślnym portem dla CDH jest port 8070. W tym poście zobaczysz baseurl
użyta zmienna, a oto wartość, której użyję:
baseurl = "http://localhost:8070"
Interfejs REST można skonfigurować tak, aby używał poświadczeń Kerberos w celu zwiększenia bezpieczeństwa.
W kodzie musisz użyć adresu IP lub w pełni kwalifikowanej nazwy domeny DNS węzła z uruchomionym demonem REST. Sprawdź również, czy port jest poprawny. Gorąco polecam, aby ten adres URL był zmienną, ponieważ może się zmieniać wraz ze zmianami sieci.
Obejścia błędów Pythona i HBase
Istnieją dwa błędy i obejścia, które należy rozwiązać. Pierwszym błędem jest to, że wbudowane moduły Pythona nie obsługują wszystkich czasowników HTTP. Drugi to błąd HBase REST podczas pracy z JSON.
Wbudowane moduły Pythona do interakcji REST nie obsługują łatwo wszystkich czasowników HTTP potrzebnych do HBase REST. Będziesz musiał zainstalować moduł żądań Pythona. Moduł żądań czyści również kod i znacznie ułatwia wszystkie interakcje.
Interfejs HBase REST ma błąd podczas dodawania danych przez JSON:wymagane jest, aby pola zachowały dokładną kolejność. Wbudowany dict
Pythona typ nie obsługuje tej funkcji, więc aby zachować kolejność, musimy użyć OrderedDict
klasa. (Osoby z Pythonem 2.6 i starszymi będą musiały zainstalować moduł orderdict.) Błąd i obejście omówię również w dalszej części posta.
Trudno było też używać kodowania base64 i dekodowania liczb całkowitych, więc napisałem trochę kodu, aby to zrobić:
# 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]
Aby było jeszcze łatwiej, napisałem metodę potwierdzającą, że odpowiedzi HTTP wracają w latach 200, co wskazuje, że operacja zadziałała. Przykładowy kod używa tej metody, aby sprawdzić powodzenie wywołania przed przejściem dalej. Oto metoda:
# Checks the request object to see if the call was successful def issuccessful(request): if 200
Praca z tabelami
Korzystając z interfejsu REST, możesz tworzyć lub usuwać tabele. Rzućmy okiem na kod, aby utworzyć tabelę.
content = '' content += '' content += ' ' content += '' request = requests.post(baseurl + "/" + tablename + "/schema", data=content, headers={"Content-Type" : "text/xml", "Accept" : "text/xml"})
W tym fragmencie tworzymy mały dokument XML, który definiuje schemat tabeli w zmiennej zawartości. Musimy podać nazwę tabeli i nazwę rodziny kolumn. Jeśli istnieje wiele rodzin kolumn, utwórz więcej ColumnSchema
węzłów.
Następnie używamy modułu requestów do POST
XML do utworzonego przez nas adresu URL. Ten adres URL musi zawierać nazwę nowej tabeli. Pamiętaj też, że ustawiamy nagłówki dla tego POST
połączenie. Pokazujemy, że wysyłamy w formacie XML z Content-Type
ustawiony na „text/xml” i że chcemy odzyskać XML za pomocą Accept
ustaw na „text/xml”.
Korzystanie z request.status_code
, możesz sprawdzić, czy tworzenie tabeli powiodło się. Interfejs REST używa tych samych kodów błędów HTTP do wykrywania, czy wywołanie zakończyło się pomyślnie, czy nie. Kod stanu w latach 200 oznacza, że wszystko działało poprawnie.
Możemy łatwo sprawdzić, czy tabela istnieje, używając następującego kodu:
request = requests.get(baseurl + "/" + tablename + "/schema")
Wywołania używają GET
czasownik, aby poinformować interfejs REST, że chcemy uzyskać informacje o schemacie dotyczące tabeli w adresie URL. Po raz kolejny możemy użyć kodu statusu, aby sprawdzić, czy tabela istnieje. Kod stanu w 200 oznacza, że istnieje, a każda inna liczba oznacza, że nie.
Korzystanie z curl
możemy sprawdzić powodzenie operacji REST bez pisania kodu. Następujące polecenie zwróci 200 pokazujące sukces połączenia, ponieważ messagestable
tabela istnieje w HBase. Oto wywołanie i jego wynik:
[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
To wywołanie REST zakończy się błędem, ponieważ tablenotthere
tabela nie istnieje w HBase. Oto wywołanie i jego wynik:
[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
Możemy usunąć tabelę za pomocą następującego kodu:
request = requests.delete(baseurl + "/" + tablename + "/schema")
To wywołanie używa DELETE
czasownik informujący interfejs REST, że chcemy usunąć tabelę. Usunięcie tabeli za pośrednictwem interfejsu REST nie wymaga uprzedniego jej wyłączenia. Jak zwykle możemy potwierdzić sukces, patrząc na kod statusu.
W następnym poście z tej serii omówimy wstawianie wierszy.
Jesse Anderson jest instruktorem na Uniwersytecie Cloudera.
Jeśli interesuje Cię HBase, zarejestruj się w HBaseCon 2013 (13 czerwca, San Francisco) — wydarzenie społecznościowe dla współtwórców, programistów, administratorów i użytkowników HBase. Rejestracja Early Bird jest otwarta do 23 kwietnia.