用Java中的Pig / Piglatin对HBase中的排序进行排序

时间:2013-08-14 08:44:26

标签: java hadoop hbase apache-pig

我在shell中创建了一个HBase表并添加了一些数据。在http://hbase.apache.org/book/dm.sort.html中写道,数据集首先按行键排序,然后按列排序。所以我在HBase Shell中尝试了一些东西:

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喜欢预期。

现在我在Java中尝试使用Apache Pig:

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])

所以,现在订单是c - > d - >一个。这对我来说有点奇怪,难道不应该像HBase一样吗?对我来说,获得正确的顺序非常重要,因为我之后将地图转换为包,然后将其与其他表连接。如果两个输入都已排序,我可以使用合并连接而不将这些输入分类到数据集?!那么现在有人如何获得列的有序映射(或包)?

1 个答案:

答案 0 :(得分:1)

您从根本上误解了某些内容 - HBaseStorage后端将每个加载为单个Tuple。您已经告诉Pig将列族cf加载为map:[],这正是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)获取ORDERk列表。

至于是否有办法将数据排序 - 通常没有。如果列族中的字段数量不是常数或字段不总是相同/已定义,则唯一的选项是

  • map转换为bag元组,然后排序
  • 或撰写自定义LoadFunc,其中包含一个表,一个列系列,并按扫描每个KeyValue对发出一个元组。 HBase将确保排序并按照您在shell中看到的排序顺序为您提供数据,但请注意,订单仅在加载时保证。你申请的任何进一步转型都会破坏这种转变。