9

MapReduce ジョブの 1 つのソースとして HBase を使用することを考えています。TableInputFormat は、リージョンごとに 1 つの入力分割 (したがって 1 つのマッパー) を指定することを知っています。ただし、これは効率が悪いようです。複数のマッパーが特定のリージョンで同時に作業できるようにしたいと考えています。TableInputFormatBase を拡張することでこれを達成できますか? 例を教えてください。さらに、これは良い考えですか?

助けてくれてありがとう。

4

5 に答える 5

3

InputFormat を拡張するカスタム入力形式が必要です。回答から質問への回答から、大量のデータをスキャンしたい (範囲ベースのクエリ)、スキャンを高速化するためにデータの書き込み中に実行できるすべての最適化について理解できます。これは、データ処理時間がデータ取得時間よりも長い場合に有効です。

于 2012-07-06T15:55:20.583 に答える
1

特定のリージョンに複数のマッパーを指定できるかどうかはわかりませんが、次のことを考慮してください。

リージョンごとに 1 つのマッパーでは効率が悪いと思われる場合 (データ ノードに #cpus などの十分なリソースがない可能性があります)、ファイル hbase-site.xml でより小さなリージョン サイズを指定できます。

変更を検討したい場合は、デフォルトの構成オプションのサイトを次に示します。 http://hbase.apache.org/configuration.html#hbase_default_configurations

領域サイズを小さくすると、DFS 内のファイル数が増えることになり、namenode のメモリに応じて Hadoop DFS の容量が制限される可能性があることに注意してください。namenode のメモリ使用量は、DFS 内のファイル数に直接関係していることを思い出してください。クラスターがどのように使用されているかがわからないため、これは状況に関連している場合とそうでない場合があります。これらの質問に対する特効薬の答えはありません。

于 2012-07-04T05:05:44.473 に答える
0

この MultipleScanTableInputFormat を使用すると、MultipleScanTableInputFormat.PARTITIONS_PER_REGION_SERVER 構成を使用して、単一のリージョンサーバーに対して実行するマッパーの数を制御できます。このクラスはすべての入力分割をその場所 (regionserver) でグループ化し、RecordReader はマッパーのすべての集約された分割を適切に反復処理します。

これが例です

https://gist.github.com/bbeaudreault/9788499#file-multiplescantableinputformat-Java-L90

単一のマッパーに対して複数の集約された分割を作成した作業

private List<InputSplit> getAggregatedSplits(JobContext context) throws IOException {
final List<InputSplit> aggregatedSplits = new ArrayList<InputSplit>();

final Scan scan = getScan();

for (int i = 0; i < startRows.size(); i++) {
  scan.setStartRow(startRows.get(i));
  scan.setStopRow(stopRows.get(i));

  setScan(scan);

  aggregatedSplits.addAll(super.getSplits(context));
}

// set the state back to where it was.. 
scan.setStopRow(null);
scan.setStartRow(null);

setScan(scan);

return aggregatedSplits;
 }

リージョン サーバーごとにパーティションを作成する

 @Override
 public List<InputSplit> getSplits(JobContext context) throws IOException {
List<InputSplit> source = getAggregatedSplits(context);

if (!partitionByRegionServer) {
  return source;
}

// Partition by regionserver
Multimap<String, TableSplit> partitioned = ArrayListMultimap.<String, TableSplit>create();
for (InputSplit split : source) {
  TableSplit cast = (TableSplit) split;
  String rs = cast.getRegionLocation();

  partitioned.put(rs, cast);
}
于 2016-12-08T08:51:03.200 に答える