Има различни начини за достъп и взаимодействие с Apache HBase. API на Java осигурява най-много функционалност, но много хора искат да използват HBase без Java.
Има два основни подхода за това: единият е интерфейсът Thrift, който е по-бързият и по-лек от двете опции. Другият начин за достъп до HBase е използването на REST интерфейса, който използва HTTP глаголи за извършване на действие, което дава на разработчиците широк избор от езици и програми за използване.
Тази серия от инструкции ще обсъди REST интерфейса и ще предостави примерни кодове на Python за достъп до него. Първата публикация ще обхване HBase REST, някои предупреждения за Python и администриране на таблици. Втората публикация ще обясни как да вмъкнете няколко реда наведнъж с помощта на XML и JSON. Третата публикация ще покаже как да получите множество редове с помощта на XML и JSON. Пълните примерни кодове могат да бъдат намерени в моя акаунт в GitHub.
Основи на HBase REST
За да работят както Thrift, така и REST, трябва да работи друг демон HBase, който да обработва тези заявки. Тези демони могат да бъдат инсталирани в пакетите hbase-thrift и hbase-rest. Диаграмата по-долу илюстрира къде Thrift и REST са поставени в клъстера. Имайте предвид, че клиентите Thrift и REST обикновено не изпълняват други услуги като DataNode или RegionServers, за да поддържат ниско натоварването и висока отзивчивост за REST взаимодействия.
Не забравяйте да инсталирате и стартирате тези демони на възли, които имат достъп както до клъстера Hadoop, така и до сървъра на уеб приложения. Интерфейсът REST няма вградено балансиране на натоварването; това ще трябва да се направи с хардуер или в код. Cloudera Manager го прави наистина лесен за инсталиране и управление на услугите HBase REST и Thrift. (Можете да го изтеглите и изпробвате безплатно!) Недостатъкът на REST е, че е много по-тежък от Thrift или Java.
Интерфейсът REST може да използва различни формати на данни:XML, JSON и protobuf. Като посочите Accept
и Content-Type
заглавки, можете да изберете формата, който искате да изпратите или да получите обратно.
За да започнете да използвате REST интерфейса, трябва да разберете на кой порт работи. Портът по подразбиране за CDH е порт 8070. За тази публикация ще видите baseurl
използвана променлива и ето стойността, която ще използвам::
baseurl = "http://localhost:8070"
REST интерфейсът може да бъде настроен да използва идентификационни данни на Kerberos за повишаване на сигурността.
За вашия код ще трябва да използвате IP адреса или DNS с пълно квалифицирано име на домейн на възела, изпълняващ демона REST. Също така проверете дали портът е правилен. Силно препоръчвам да направите този URL променлива, тъй като може да се промени с промени в мрежата.
Заобикалящи грешки в Python и HBase
Има две грешки и заобиколни решения, които трябва да бъдат отстранени. Първата грешка е, че вградените модули на Python не поддържат всички HTTP глаголи. Втората е грешка в HBase REST при работа с JSON.
Вградените модули на Python за REST взаимодействие не поддържат лесно всички HTTP глаголи, необходими за HBase REST. Ще трябва да инсталирате модула за заявки на Python. Модулът за заявки също изчиства кода и прави всички взаимодействия много по-лесни.
HBase REST интерфейсът има грешка при добавяне на данни чрез JSON:изисква се полетата да поддържат точния си ред. Вграденият dict
на Python типът не поддържа тази функция, така че за да поддържаме поръчката, ще трябва да използваме OrderedDict
клас. (Тези с Python 2.6 и по-стари ще трябва да инсталират модула ordereddict.) Ще разгледам и грешката и заобикалянето по-късно в публикацията.
Също така беше трудно да използвам base64 кодиране и декодиране на цели числа, така че написах някакъв код за това:
# 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]
За да направя нещата още по-лесни, написах метод за потвърждение, че HTTP отговорите се връщат през 200-те, което показва, че операцията работи. Примерният код използва този метод, за да провери успеха на повикване, преди да продължи. Ето метода:
# Checks the request object to see if the call was successful def issuccessful(request): if 200
Работа с таблици
С помощта на REST интерфейса можете да създавате или изтривате таблици. Нека да разгледаме кода, за да създадем таблица.
content = '' content += '' content += ' ' content += '' request = requests.post(baseurl + "/" + tablename + "/schema", data=content, headers={"Content-Type" : "text/xml", "Accept" : "text/xml"})
В този фрагмент създаваме малък XML документ, който дефинира схемата на таблицата в променливата на съдържанието. Трябва да предоставим името на таблицата и фамилията на колоната. Ако има няколко семейства колони, създавате още ColumnSchema
възли.
След това използваме модула за заявки за POST
XML към URL адреса, който създаваме. Този URL трябва да включва името на новата таблица. Също така имайте предвид, че задаваме заглавките за този POST
обадете се. Показваме, че изпращаме в XML с Content-Type
зададен на “text/xml” и че искаме XML обратно с Accept
зададен на “text/xml”.
Използване на request.status_code
, можете да проверите дали създаването на таблицата е било успешно. Интерфейсът REST използва същите HTTP кодове за грешки, за да открие дали обаждането е било успешно или с грешка. Код на състоянието през 200-те означава, че нещата са работили правилно.
Можем лесно да проверим дали съществува таблица, като използваме следния код:
request = requests.get(baseurl + "/" + tablename + "/schema")
Обажданията използват GET
глагол да каже на интерфейса REST, че искаме да получим информацията за схемата за таблицата в URL адреса. Още веднъж можем да използваме кода на състоянието, за да видим дали таблицата съществува. Код на състоянието в 200-те означава, че съществува, а всяко друго число означава, че не съществува.
Използване на curl
команда, можем да проверим успеха на REST операция, без да пишем код. Следната команда ще върне 200, показваща успеха на повикването, тъй като messagestable
таблицата съществува в HBase. Ето обаждането и неговия изход:
[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
Това извикване на REST ще възникне грешка, защото tablenotthere
таблицата не съществува в HBase. Ето обаждането и неговия изход:
[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
Можем да изтрием таблица с помощта на следния код:
request = requests.delete(baseurl + "/" + tablename + "/schema")
Това извикване използва DELETE
глагол да каже на REST интерфейса, че искаме да изтрием таблицата. Изтриването на таблица през REST интерфейса не изисква първо да я деактивирате. Както обикновено, можем да потвърдим успеха, като погледнем кода на състоянието.
В следващата публикация от тази серия ще разгледаме вмъкването на редове.
Джеси Андерсън е инструктор в университета Cloudera.
Ако се интересувате от HBase, не забравяйте да се регистрирате за HBaseCon 2013 (13 юни, Сан Франциско) – събитието на общността за сътрудници на HBase, разработчици, администратори и потребители. Early Bird регистрацията е отворена до 23 априла