2015-10-19 11 views
5

セットアップ:

私は100M +行と1百万+列のHBaseテーブルを持っています。すべての行には2〜5列のデータしかありません。列ファミリは1つだけです。HBaseテーブルからすべての列名を取得できますか?

問題:

私はこのcolumn family内のすべての異なるqualifiers(列)を知りたいです。それをすばやく行う方法はありますか?

テーブル全体をスキャンして、各行にfamilyMapを入力すると、qualifierが得られ、Set<>に追加されます。しかし、それは100M +の行があるので、非常に遅いでしょう。

我々は、任意のより良いを行うことができますか?

答えて

1

のHBaseは、すべての地域のサーバで利用できるすべての修飾子のリストについては何ら「メタデータ」(と言う集中マスターノードに保存されている何かが)ありません分散NavigableMap<byte[], NavigableMap<byte[], NavigableMap<byte[], NavigableMap<Long, byte[]>>>>

として可視化することができます。

1回限りのユースケースがある場合は、言及したように、表全体をスキャンして修飾子名をSet<>に追加する方法があります。

これはリピートユースケースをされた場合(プラスあなたの技術スタックにコンポーネントを追加する裁量権を持っている場合)、あなたはRedisの追加を検討することをお勧めします。修飾子のセットは、Redis Setを使用して分散して維持することができます。

0

HBaseのコプロセッサは、このシナリオのために使用することができます。 RDBMSのストアドプロシージャのように機能するカスタムEndPoint実装を記述することができます。サーバー側でコードを実行し、各地域ごとに異なる列を取得します。クライアントでは、すべての地域で異なる列を取得できます。

性能上の利点:すべての列が減少ネットワーク呼び出し、その結果をクライアントに転送されません。

2

あなたは、このためのMapReduceを使用することができます。この場合、コプロセッサの場合と同様に、hbase用のカスタムライブラリをインストールする必要はありません。 mapreduceタスクを作成するためのコードの下にあります。

仕事セットアップ

Job job = Job.getInstance(config); 
    job.setJobName("Distinct columns"); 

    Scan scan = new Scan(); 
    scan.setBatch(500); 
    scan.addFamily(YOU_COLUMN_FAMILY_NAME); 
    scan.setFilter(new KeyOnlyFilter()); //scan only key part of KeyValue (raw, column family, column) 
    scan.setCacheBlocks(false); // don't set to true for MR jobs 


    TableMapReduceUtil.initTableMapperJob(
      YOU_TABLE_NAME, 
      scan,   
      OnlyColumnNameMapper.class, // mapper 
      Text.class,    // mapper output key 
      Text.class,    // mapper output value 
      job); 

    job.setNumReduceTasks(1); 
    job.setReducerClass(OnlyColumnNameReducer.class); 
    job.setReducerClass(OnlyColumnNameReducer.class); 

マッパー

public class OnlyColumnNameMapper extends TableMapper<Text, Text> { 
    @Override 
    protected void map(ImmutableBytesWritable key, Result value, final Context context) throws IOException, InterruptedException { 
     CellScanner cellScanner = value.cellScanner(); 
     while (cellScanner.advance()) { 

      Cell cell = cellScanner.current(); 
      byte[] q = Bytes.copy(cell.getQualifierArray(), 
           cell.getQualifierOffset(), 
           cell.getQualifierLength()); 

      context.write(new Text(q),new Text()); 

     } 
} 

}

リデューサー

public class OnlyColumnNameReducer extends Reducer<Text, Text, Text, Text> { 

    @Override 
    protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {  
      context.write(new Text(key), new Text());  
    } 
} 
関連する問題