2

Reduce 操作によって生成された出力ファイルは巨大です (Gzip 後 1 GB)。ブレーク出力を 200 MB の小さなファイルに生成したい。出力をサイズまたはいいえで分割するプロパティ/Javaクラスはありますか。行の?レデューサーの数を増やすことはできません。これは Hadoop ジョブのパフォーマンスに悪影響を及ぼすためです。

4

2 に答える 2

2

なぜあなたがより多くのレデューサーを使用できないのか、私は興味がありますが、私はあなたの言葉を受け入れます.

できるオプションの 1 つは、MultipleOutputs を使用して、1 つのレデューサーから複数のファイルに書き込むことです。たとえば、各レデューサーの出力ファイルが 1GB で、代わりに 256MB のファイルが必要だとします。これは、1 つのファイルではなく、レデューサーごとに 4 つのファイルを書き込む必要があることを意味します。

ジョブ ドライバーで、次の操作を行います。

JobConf conf = ...;

// You should probably pass this in as parameter rather than hardcoding 4.
conf.setInt("outputs.per.reducer", 4);

// This sets up the infrastructure to write multiple files per reducer.
MultipleOutputs.addMultiNamedOutput(conf, "multi", YourOutputFormat.class, YourKey.class, YourValue.class);

レデューサーで、次のようにします。

@Override
public void configure(JobConf conf) {
  numFiles = conf.getInt("outputs.per.reducer", 1);
  multipleOutputs = new MultipleOutputs(conf);

  // other init stuff
  ...
}

@Override
public void reduce(YourKey key
                   Iterator<YourValue> valuesIter,
                   OutputCollector<OutKey, OutVal> ignoreThis,
                   Reporter reporter) {
    // Do your business logic just as you're doing currently.
    OutKey outputKey = ...;
    OutVal outputVal = ...;

    // Now this is where it gets interesting. Hash the value to find
    // which output file the data should be written to. Don't use the
    // key since all the data will be written to one file if the number
    // of reducers is a multiple of numFiles.
    int fileIndex = (outputVal.hashCode() & Integer.MAX_VALUE) % numFiles;

    // Now use multiple outputs to actually write the data.
    // This will create output files named: multi_0-r-00000, multi_1-r-00000,
    // multi_2-r-00000, multi_3-r-00000 for reducer 0. For reducer 1, the files
    // will be multi_0-r-00001, multi_1-r-00001, multi_2-r-00001, multi_3-r-00001.
    multipleOutputs.getCollector("multi", Integer.toString(fileIndex), reporter)
      .collect(outputKey, outputValue);
}

@Overrider
public void close() {
   // You must do this!!!!
   multipleOutputs.close();
}

この疑似コードは、古い mapreduce API を念頭に置いて作成されました。ただし、mapreduce api を使用した同等の api が存在するため、いずれにせよ、準備は整っているはずです。

于 2012-05-04T06:21:18.177 に答える
0

これを行うプロパティはありません。独自の出力形式とレコード ライターを作成する必要があります。

于 2012-05-03T21:20:14.730 に答える