我是Hadoop和MapReduce的新手,并一直尝试根据键将输出写入多个文件。任何人都可以提供有关如何使用它的清晰思路或Java代码片段示例。我的映射器工作得很好,并且在随机播放后,可以按预期获得键和相应的值。谢谢!
我想做的是从输入文件到新文件仅输出少量记录。
因此,新的输出文件应仅包含那些必需的记录,而忽略其余无关的记录。
即使我不使用MultipleTextOutputFormat,也可以正常工作。
我在mapper中实现的逻辑如下:
public static class MapClass extends
Mapper {
StringBuilder emitValue = null;
StringBuilder emitKey = null;
Text kword = new Text();
Text vword = new Text();
public void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
String[] parts;
String line = value.toString();
parts = line.split(" ");
kword.set(parts[4].toString());
vword.set(line.toString());
context.write(kword, vword);
}
}
要减少的输入是这样的:
[key1]-> [value1,value2,...]
[key2]-> [value1,value2,...]
[key3]-> [value1,value2,...]等
我的兴趣是在[key2]-> [value1,value2,...]中忽略其他键和相应的值。请帮助我 reducer 。
最佳答案
使用MultipleOutputs
可让您在多个文件中发射记录,但是仅在一组预定义数量/类型的文件中发出记录,而不是任意数量的文件,并且不会根据键/值即时决定文件名。
您可以通过扩展org.apache.hadoop.mapred.lib.MultipleTextOutputFormat
来创建自己的OutputFormat。您的OutputFormat类将允许根据reducer发出的键/值决定输出文件名以及文件夹。这可以通过以下方式实现:
package oddjob.hadoop;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.lib.MultipleTextOutputFormat;
public class MultipleTextOutputFormatByKey extends MultipleTextOutputFormat<Text, Text> {
/**
* Use they key as part of the path for the final output file.
*/
@Override
protected String generateFileNameForKeyValue(Text key, Text value, String leaf) {
return new Path(key.toString(), leaf).toString();
}
/**
* When actually writing the data, discard the key since it is already in
* the file path.
*/
@Override
protected Text generateActualKey(Text key, Text value) {
return null;
}
}
有关更多信息,请阅读here。
PS:您将需要使用旧的
mapred
API来实现。就像在较新的API中一样,尚不支持MultipleTextOutput
!请参阅this。
关于java - 如何使用MultipleOutputs <KEYOUT,VALUEOUT>将输出数据写入多个输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15340638/