Примечание редактора: Обязательно ознакомьтесь с частью 1 и частью 2 .
Это четвертая из вводной серии блогов по Apache HBase . В третьей части мы увидели высокоуровневое представление архитектуры HBase. В этой части мы будем использовать Java API HBase для создания таблиц, вставки новых данных и извлечения данных по ключу строки. Мы также увидим, как настроить базовое сканирование таблицы, которое ограничивает извлекаемые столбцы, а также использует фильтр для просмотра результатов.
Только что ознакомившись с высокоуровневой архитектурой HBase, теперь давайте рассмотрим клиентский API Java, поскольку именно так ваши приложения взаимодействуют с HBase. Как упоминалось ранее, вы также можете взаимодействовать с HBase с помощью нескольких разновидностей технологий RPC, таких как Apache Thrift и шлюз REST, но мы собираемся сосредоточиться на нативном Java API. Клиентские API предоставляют семантику DDL (язык определения данных) и DML (язык манипулирования данными), очень похожую на то, что вы найдете в SQL для реляционных баз данных. Предположим, мы собираемся хранить информацию о людях в HBase, и мы хотим начать с создания новой таблицы. В следующем листинге показано, как создать новую таблицу с помощью HBaseAdmin
класса.
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
HTableDescriptor tableDescriptor = new HTableDescriptor(TableName.valueOf("people"));
tableDescriptor.addFamily(new HColumnDescriptor("personal"));
tableDescriptor.addFamily(new HColumnDescriptor("contactinfo"));
tableDescriptor.addFamily(new HColumnDescriptor("creditcard"));
admin.createTable(tableDescriptor);
people
Таблица определена в предыдущем список содержит три семейства столбцов: personal
, contactinfo
и creditcard
. Чтобы создать таблицу, вы создаете HTableDescriptor
и добавляете одно или несколько семейств столбцов путем добавления HColumnDescriptor
объектов. Затем вы звоните, createTable
чтобы создать таблицу. Теперь у нас есть таблица, поэтому давайте добавим некоторые данные. В следующем листинге показано, как использовать Put
класс для вставки данных о Джоне Доу, в частности, его имени и адреса электронной почты (для краткости опущена правильная обработка ошибок).
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "people");
Put put = new Put(Bytes.toBytes("doe-john-m-12345"));
put.add(Bytes.toBytes("personal"), Bytes.toBytes("givenName"), Bytes.toBytes("John"));
put.add(Bytes.toBytes("personal"), Bytes.toBytes("mi"), Bytes.toBytes("M"));
put.add(Bytes.toBytes("personal"), Bytes.toBytes("surame"), Bytes.toBytes("Doe"));
put.add(Bytes.toBytes("contactinfo"), Bytes.toBytes("email"), Bytes.toBytes("[email protected]"));
table.put(put);
table.flushCommits();
table.close();
В приведенном выше листинге мы создаем Put
уникальный ключ строки для конструктора. Затем мы добавляем значения, которые должны включать семейство столбцов, спецификатор столбца и значение в виде байтовых массивов . Как вы, наверное, заметили, служебный Bytes
класс HBase API часто используется; он предоставляет методы для преобразования в и из byte[]
примитивных типов и строк. (Добавление статического импорта для этого toBytes()
метода привело бы к сокращению большого количества стандартного кода.) Затем мы помещаем данные в таблицу, сбрасываем коммиты, чтобы гарантировать вступление в силу локально буферизованных изменений, и, наконец, закрываем таблицу. Обновление данных также осуществляется черезPut
Класс точно так же, как показано в предыдущем листинге. В отличие от реляционных баз данных, в которых обновления должны обновлять целые строки, даже если изменился только один столбец, если вам нужно обновить только один столбец, то это все, что вы указываете в, Put
а HBase будет обновлять только этот столбец. Существует также checkAndPut
операция, которая по существу является формой оптимистического управления параллелизмом — операция будет помещать новые данные только в том случае, если текущие значения соответствуют значениям, указанным клиентом.
Получение строки, которую мы только что создали, выполняется с использованием Get
класса, как показано в следующем листинге. (Начиная с этого момента, списки будут опускать шаблонный код для создания конфигурации, создания HTable
вызовов, а также вызовов сброса и закрытия.)
Get get = new Get(Bytes.toBytes("doe-john-m-12345"));
get.addFamily(Bytes.toBytes("personal"));
get.setMaxVersions(3);
Result result = table.get(get);
Код в предыдущем листинге создает Get
экземпляр, предоставляющий ключ строки, который мы хотим найти. Затем мы используем addFamily
для указания HBase, что нам нужны только данные из семейства personal
столбцов, что также сокращает объем работы, которую HBase должен выполнять при чтении информации с диска. Мы также указываем, что нам нужно до трех версий каждого столбца в нашем результате, возможно, чтобы мы могли перечислить исторические значения каждого столбца. Наконец, вызов get
возвращает Result
экземпляр, который затем можно использовать для проверки всех возвращаемых значений столбца.
Во многих случаях вам нужно найти более одной строки. HBase позволяет вам делать это путем сканирования строк, как показано во второй части, которая показала использование сканирования в сеансе оболочки HBase. Соответствующий класс является Scan
классом. Вы можете указать различные параметры, такие как начальный и конечный ключи строки для сканирования, какие столбцы и семейства столбцов следует включить и максимальное количество версий для извлечения. Вы также можете добавить фильтры, которые позволят вам реализовать собственную логику фильтрации, чтобы еще больше ограничить возвращаемые строки и столбцы. Обычный вариант использования фильтров — это нумерация страниц. Например, нам может понадобиться сканировать всех людей, чья фамилия Смит, по одной странице (например, 25 человек) за раз. Следующий листинг показывает, как выполнить базовое сканирование.
Scan scan = new Scan(Bytes.toBytes("smith-"));
scan.addColumn(Bytes.toBytes("personal"), Bytes.toBytes("givenName"));
scan.addColumn(Bytes.toBytes("contactinfo"), Bytes.toBytes("email"));
scan.setFilter(new PageFilter(25));
ResultScanner scanner = table.getScanner(scan);
for (Result result : scanner) {
// ...
}
В приведенном выше листинге мы создаем новый, Scan
который начинается с ключа строки, smith-
и затем мы используем его addColumn
для ограничения возвращаемых столбцов (таким образом, уменьшая объем переноса диска, который должен выполнять HBase) до personal:givenName
и contactinfo:email
. При PageFilter
сканировании A ограничивается числом проверяемых строк до 25. (Альтернативой использованию фильтра страницы может быть указание ключа остановки строки при построении Scan
.) Затем мы получаем a ResultScanner
для Scan
только что созданного и выполняем цикл по результаты выполнения любых необходимых действий. Поскольку в HBase единственный метод извлечения нескольких строк данных — это сканирование по отсортированным ключам строк, очень важно, как вы проектируете значения ключей строк. Мы вернемся к этой теме позже.
Вы также можете удалить данные в HBase, используя Delete
класс, аналогичный Put
классу, чтобы удалить все столбцы в строке (таким образом, удалив саму строку), удалить семейства столбцов, удалить столбцы или некоторую их комбинацию.
Обработка соединения
В приведенных выше примерах не было уделено большого внимания обработке соединений и RPC (удаленным вызовам процедур). HBase предоставляет HConnection
класс, который предоставляет функциональность, аналогичную классам пула соединений, для совместного использования соединений, например, вы используете getTable()
метод для получения ссылки на HTable
экземпляр. Существует также HConnectionManager
класс, который вы получаете экземпляры HConnection
. Подобно тому, как избегать сетевых обходов в веб-приложениях, важно эффективно управлять количеством RPC и количеством данных, возвращаемых при использовании HBase, и что-то следует учитывать при написании приложений HBase.
Заключение к части 4
В этой части мы использовали HBase Java API для создания people
таблицы, вставки нового человека и поиска информации о вновь вставленном человеке. Мы также использовали Scan
класс для сканирования people
таблицы людей с фамилией «Смит» и показали, как ограничить полученные данные и, наконец, как использовать фильтр для ограничения количества результатов.
В следующей части мы узнаем, как бороться с отсутствием SQL и отношений при моделировании схем в HBase.
Ссылки
- Веб-сайт HBase, http://hbase.apache.org/
- HBase wiki, http://wiki.apache.org/hadoop/Hbase
- Справочное руководство по HBase http://hbase.apache.org/book/book.html
- HBase: полное руководство, http://bit.ly/hbase-definitive-guide
- Google Bigtable Paper, http://labs.google.com/papers/bigtable.html
- Веб-сайт Hadoop, http://hadoop.apache.org/
- Hadoop: полное руководство, http://bit.ly/hadoop-definitive-guide
- Ошибки распределенных вычислений, http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing
- HBase молниеносные слайды, http://www.slideshare.net/scottleber/hbase-lightningtalk
- Пример кода, https://github.com/sleberknight/basic-hbase-examples