我的Reduce操作生成的输出文件很大(Gzipping后为1 GB)。我希望它产生中断输出到200 MB的较小文件。是否有一个属性/ Java类来分割减少输出大小或否。线? 我无法增加减速器的数量,因为这会对hadoop作业的性能产生负面影响。
答案 0 :(得分:2)
我很好奇为什么你不能只使用更多的减速器,但我会接受你的话。
您可以执行的一个选项是使用MultipleOutputs并从一个reducer写入多个文件。例如,假设每个reducer的输出文件是1GB,而您想要256MB文件。这意味着您需要为每个reducer而不是一个文件写入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,所以不管怎样,你应该全部设置。
答案 1 :(得分:0)
没有财产可以做到这一点。你需要编写自己的输出格式&amp;记录作家。