2

我在 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 -> a。这对我来说似乎有点奇怪,不应该和 HBase 一样吗?获得正确的顺序对我来说很重要,因为我之后将地图转换成一个袋子,然后将它与其他表连接起来。如果两个输入都已排序,我可以使用合并连接而不将它们排序到数据集?!那么现在有没有人如何获得列的排序图(或包)?

4

1 回答 1

1

您从根本上误解了一些东西-HBaseStorage后端将每一加载为单个Tuple. 您已经告诉 Pig 将列族加载cfmap:[],这正是 Pig 正在做的事情。引擎盖下的Pigmap只是 a java.util.HashMap,显然没有顺序。

目前在 pig 中没有办法将 a 转换map为 a 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为 abag然后排序
  • 或者编写一个自定义,它接受一个表、一个列族并为每对扫描LoadFunc发出一个元组。KeyValueHBase 将确保排序并按照您在 shell 中看到的排序顺序为您提供数据,但请注意,仅在加载时才能保证顺序。您应用的任何进一步转换都会破坏它。
于 2013-10-22T15:28:31.467 回答