当不同的 Mapper 使用相同的输入文件,也就是相同的数据结构时,所有这些不同的 Mapper 的源代码可以放在单个 Mapper 实现的不同方法中,并使用上下文中的参数来决定调用哪些映射函数. 从好的方面来说,您只需要启动一个 Map Reduce Job。示例是伪代码:
class ComplexMapper extends Mapper {
protected BitSet mappingBitmap = new BitSet();
protected void setup(Context context) ... {
{
String params = context.getConfiguration().get("params");
---analyze params and set bits into the mappingBitmap
}
protected void mapA(Object key, Object value, Context context){
.....
context.write(keyA, value);
}
protected void mapB(Object key, Object value, Context context){
.....
context.write(keyA, value);
}
protected void mapB(Object key, Object value, Context context){
.....
context.write(keyB, value);
}
public void map(Object key, Object value, Context context) ..... {
if (mappingBitmap.get(1)) {
mapA(key, value, context);
}
if (mappingBitmap.get(2)) {
mapB(key, value, context);
}
if (mappingBitmap.get(3)) {
mapC(key, value, context);
}
}
当然,它可以通过接口等更优雅地实现。
在作业设置中添加:
Configuration conf = new Configuration();
conf.set("params", "AB");
Job job = new Job(conf);
正如 Praveen Sripati 所提到的,拥有一个输出文件将迫使您只拥有一个 Reducer,这可能对性能不利。当您从 hdfs 下载 part** 文件时,您始终可以连接它们。例子:
hadoop fs -text /output_dir/part* > wholefile.txt