2013-08-14 3 views
2

Я создал таблицу HBase в оболочке и добавил некоторые данные. В http://hbase.apache.org/book/dm.sort.html записано, что наборы данных сначала сортируются по строке rowkey, а затем по столбцу. Поэтому я попробовал что-то в оболочке HBase:Порядок сортировки в HBase с Pig/Piglatin в Java

hbase(main):013:0> put 'mytable', 'key1', 'cf:c', 'val' 
0 row(s) in 0.0110 seconds 

hbase(main):011:0> put 'mytable', 'key1', 'cf:d', 'val' 
0 row(s) in 0.0060 seconds 

hbase(main):012:0> put 'mytable', 'key1', 'cf:a', 'val' 
0 row(s) in 0.0060 seconds 


hbase(main):014:0> get 'mytable', 'key1' 
COLUMN    CELL              
cf:a     timestamp=1376468325426, value=val       
cf:c     timestamp=1376468328318, value=val       
cf:d     timestamp=1376468321642, value=val       
3 row(s) in 0.0570 seconds 

Все выглядит нормально. Я получил правильный порядок a -> c -> d, как ожидалось.

Теперь я попробовал то же самое с Apache Pig в Java:

pigServer.registerQuery("mytable_data = load 'hbase://mytable' using org.apache.pig.backend.hadoop.hbase.HBaseStorage('cf', '-loadKey true') as (rowkey:chararray, columncontent:map[]);"); 
printAlias("mytable_data"); // own function, which itereate over the keys 

Я получил этот результат:

(key1,[c#val,d#val,a#val]) 

Итак, теперь порядок с -> d -> а. Это кажется мне немного странным, разве это не должно быть так же, как в HBase? Для меня важно получить правильный порядок, потому что впоследствии я преобразую карту в сумку, а затем присоединяю ее к другим столам. Если оба входа отсортированы, я могу использовать объединение слияния, не сортируя их по наборам данных! Так кто-нибудь теперь, как можно получить отсортированную карту (или сумку) столбцов?

+0

Отсортировано по алфавиту или по заказу вставки? – mr2ert

+0

Выход, похоже, сортируется по вставке –

+0

Упс, это было немного неясно. Итак, в нужном вам виде значения карты нужно сортировать в алфавитном порядке? Почему бы просто не отсортировать значения в UDF? – mr2ert

ответ

1

Вы принципиально то недоразумение - в HBaseStorage бэкэнде нагрузки каждых строк как единый Tuple. Вы сказали Pig загрузить семейство столбцов cf как map:[], что и делает Pig. A Pig map под капотом - это всего лишь java.util.HashMap, который, очевидно, не имеет порядка.

Там нет никакого способа, в настоящее время в свинью, чтобы преобразовать map в bag, но это должно быть тривиальной UDF писать, если не считать null чеки и другие шаблонного, тело что-то вроде

public DataBag exec(Tuple input) { 
    DataBag resultBag = bagFactory.newDefaultBag(); 
    HashMap<String, Object> map = (HashMap<String, Object>) input.get(0); 
    for (Map.Entry<String, Object> entry : map) { 
     Tuple t = tupleFactory.newTuple(); 
     t.append(entry.getKey()); 
     t.append(entry.getValue().toString()); 
     resultBag.add(t); 
    } 
    return resultBag; 
} 

С что тогда вы можете создать bag{(k:chararray, v:chararray)}, используйте FLATTEN, чтобы получить список (k:chararray, v:chararray) и ORDER тех, что указаны на k.

Что касается способа сортировки данных - вообще нет. Если количество полей в семье столбца не является постоянной или поля не всегда одни и те же/определены, только ваши варианты

  • преобразуя map к bag кортежей и сортировки затем
  • или написания custom LoadFunc, который берет таблицу, семейство столбцов и испускает кортеж на KeyValue пару отсканированных. HBase обеспечит упорядочение и предоставит вам данные в отсортированном порядке, который вы видите в оболочке, но обратите внимание, что заказ гарантируется только при загрузке. Любое дальнейшее преобразование, которое вы применяете, разрушает это.