我遇到了一个有趣的情况,现在正在寻找有意做的事情。在本地单节点设置上,我从终端屏幕同时运行了2个作业。我的两个作业都使用相同的化约器,它们的映射功能(聚合键-分组依据)仅具有差异,两个作业的输出均写入第一个作业的输出中(尽管第二个作业确实创建了自己的文件夹,但它为空)。我正在研究的是提供各个级别的汇总聚合,这种行为令我着迷,两个不同级别的聚合输出可在一个文件中获得(也可以完美排序)。

我的问题是如何在真正的Hadoop集群中实现相同的目标,在该集群中我们有多个数据节点,即我以编程方式启动了多个作业,所有人都访问相同的输入文件,以不同的方式映射数据,但是使用相同的reducer,并且输出在一个中可用单个文件,而不是5个不同的输出文件。

请指教。

在决定问我的问题之前,我正在看merge output files after reduce phase

谢谢和亲切的问候,

Moiz Ahmed。

最佳答案

当不同的Mappers使用相同的输入文件(即具有相同的数据结构)时,可以将所有这些不同Mappers的源代码放入单个Mapper实现的单独方法中,并使用上下文中的参数来确定要调用的映射函数。从正面来看,您仅需要启动一个Map Reduce作业。示例是伪代码:

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);
   }
}

因此,可以使用接口(interface)等更优雅地实现它。

在作业设置中,只需添加:
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

10-07 19:00
查看更多