2

シェルで HBase テーブルを作成し、いくつかのデータを追加しました。http://hbase.apache.org/book/dm.sort.htmlには、データセットが最初に行キーでソートされ、次に列でソートされることが書かれています。だから私はHBaseシェルで何かを試しました:

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ロードします。列ファミリーを としてロードするように Pig に指示しましたが、これはまさに Pig が行っていることです。ボンネットの下のPigは単なる であり、明らかに順序がありません。Tuplecfmap:[]mapjava.util.HashMap

現在 pig で を に変換する方法はありませんが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ごとにタプルを発行するカスタムを作成します。KeyValueHBase は順序付けを保証し、シェルで表示される並べ替え順序でデータを提供しますが、順序はロード時にのみ保証されることに注意してください。それ以上の変換を適用すると、それが台無しになります。
于 2013-10-22T15:28:31.467 に答える