Статьи

Выровнять целые семейства столбцов HBase с помощью UDF Pig и Python

Большинство Pig учебники вы найдете предположите , что вы работаете с данными , где вы знаете имена всех столбцов заранее, а сами имена столбцов просто ярлыки, против того композитов меток и данных. Например, при работе с HBase на самом деле нередко оба эти предположения ложны. Будучи столбчатой ​​базой данных, очень распространено работать со строками, имеющими тысячи столбцов . При таких обстоятельствах также часто имена столбцов кодируются в измерения, такие как дата и тип счетчика .

Как вы решаете это несоответствие? Если вы находитесь на ранних этапах разработки схемы, вы можете пересмотреть более рядовой подход. Однако, если вам нужно работать с существующей схемой, вы можете это сделать с помощью пользовательских функций Pig .

Скажем, у нас есть следующая таблица:

RowKey cf1: 20130101post cf1: 20130101comment cf1: 20130101like cf1: 20130102post
ce410-00005031-00089182 147 5 41 153
ce410-00005031-00021915 1894 33 86 1945
5faa4-00009521-00019828 30 2 8 31

Здесь есть составной ключ строки, но также составные ключи столбца. Поскольку дата является частью ключей столбцов, потенциально существует много, много столбцов. Перечислять их все в своих сценариях Свинья непрактично. Обратите внимание, что они также находятся в одном семействе столбцов. Чтобы загрузить их все, вы можете сделать следующее в Pig:

data = load 'hbase://table_name' using org.apache.pig.backend.hadoop.hbase.HBaseStorage('cf1:*', '-loadKey true') AS (id:chararray, stats:map[int]);
illustrate data;

Это приведет к тому, что все столбцы будут загружены в карту Pig , которая является просто набором кортежей:

-----------------------------------------------------------------------------------------------------
| data         | id:chararray            | stats:map(:int)                                          |
-----------------------------------------------------------------------------------------------------
|              | ce410-00005031-00089182 | {20130101post=147,20130101comment=5,20130101like=41,...} |
-----------------------------------------------------------------------------------------------------

Итак, теперь вы загрузили все данные, но как вам разобрать имена столбцов в их соответствующие части, чтобы можно было применить логику к значениям? Вот очень простая реализация UDF на Python, которая превратит эту карту в пакет:

@outputSchema("values:bag{t:tuple(key, value)}")
def bag_of_tuples(map_dict):
    return map_dict.items()

Вы можете включить этот UDF (поместите вышеупомянутое в файл с именем udfs.py в текущем рабочем каталоге для pig) и вызовите его так:

register 'udfs.py' using jython as py
data = load 'hbase://table_name' using org.apache.pig.backend.hadoop.hbase.HBaseStorage('cf1:*', '-loadKey true') AS (id:chararray, stats:map[int]);
databag = foreach data generate id, FLATTEN(py.bag_of_tuples(stats));
illustrate databag;

Это использует встроенный оператор FLATTEN , который берет сумку и делает перекрестное произведение с рядом сумок, чтобы получить N новых рядов.

------------------------------------------------------------------------------
| databag      | id:chararray            | key:bytearray  | value:bytearray  |
------------------------------------------------------------------------------
|              | ce410-00005031-00089182 | 20130101post    | 147             |
------------------------------------------------------------------------------
|              | ce410-00005031-00089182 | 20130101comment | 5               |
------------------------------------------------------------------------------
|              | ce410-00005031-00089182 | 20130101like    | 41              |
------------------------------------------------------------------------------

Затем вы можете обработать ваши данные как обычно. Затем вы можете записать свой пакет данных в HBase в том же формате, используя встроенный UDF- файл TOMAP и тот же * синтаксис. Предполагая, что вы создали новые имена и значения столбцов в вашем скрипте, вы можете сделать:

...
mapped = foreach processed_data generate TOMAP(columnname, value) as stats;
store mapped into 'hbase://table_name' using org.apache.pig.backend.hadoop.hbase.HBaseStorage('stats:*');