Hadoop使用MultipleOutputs输出多文件或者指定命名

Hadoop使用MultipleOutputs输出多文件或者指定命名

@(HADOOP)[hadoop]

(一)输出多文件(未测试)

比如将不同国家的信息分别输出到一份对应的文件中。

1、在reduce或map类中创建MultipleOutputs对象,将结果输出

class reduceStatistics extends Reducer<Text, IntWritable, Text, IntWritable>{  

    //将结果输出到多个文件或多个文件夹  
    private MultipleOutputs<Text,IntWritable> mos;  
    //创建对象  
    protected void setup(Context context) throws IOException,InterruptedException {  
        mos = new MultipleOutputs<Text, IntWritable>(context);  
     }  

        //关闭对象  
    protected void cleanup(Context context) throws IOException,InterruptedException {  
        mos.close();  
    }  
}  

2、在map或reduce方法中使用MultipleOutputs对象输出数据,代替congtext.write()
Java代码 收藏代码

protected void reduce(Text key, Iterable<IntWritable> values, Context context)  
            throws IOException, InterruptedException {  
        IntWritable V = new IntWritable();  
        int sum = 0;  
        for(IntWritable value : values){  
            sum = sum + value.get();  
        }  
        System.out.println("word:" + key.toString() + "     sum = " + sum);  
        V.set(sum);  

        //使用MultipleOutputs对象输出数据  
        if(key.toString().equals("hello")){  
            mos.write("hello", key, V);  
        }else if(key.toString().equals("world")){  
            mos.write("world", key, V);  
        }else if(key.toString().equals("hadoop")){  
            //输出到hadoop/hadoopfile-r-00000文件  
            mos.write("hadoopfile", key, V, "hadoop/");  
        }  

    }  

3、在创建job时,定义附加的输出文件,这里的文件名称与第二步设置的文件名相同
Java代码 收藏代码

//定义附加的输出文件  
            MultipleOutputs.addNamedOutput(job,"hello",TextOutputFormat.class,Text.class,IntWritable.class);  
            MultipleOutputs.addNamedOutput(job,"world",TextOutputFormat.class,Text.class,IntWritable.class);  
            MultipleOutputs.addNamedOutput(job,"hadoopfile",TextOutputFormat.class,Text.class,IntWritable.class);  

(二)指定输出命名

1、创建变量

private static MultipleOutputs<Text, Text> mos;

2、初始化变量

在map或者reduce的setup()方法中初始化变量

mos = new MultipleOutputs<Text, Text>(context);

3、使用变量代替context来write

在map()或者reduce()方法中使用mos作输出:

mos.write("outputname", key, new Text(""));

4、关于变量传递

在主类中定义的变量,如定义了一个outputname,需要将其写入conf分发至其它nodemanager:

    Configuration conf = new Configuration();
    //需要将变量分发至所有的nodemanager
    conf.set("outputname", outputName);

然后在map/reduce中从context获取这个变量:

    context.getConfiguration().get("outputname")

5、关于part-**的输出

使用multioutput改变了默认的输出名称后,原有的part-**也会输出的,此时需要加上:

import org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat;
LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);

这将在有内容写入文件时才创建文件,详细可看:http://stackoverflow.com/questions/14555313/renaming-part-files-in-hadoop-map-reduce
另外,即使不使用multiOutput,如果任务输出中有大量的空文件,也应加上这代码。x

发布了325 篇原创文章 · 获赞 98 · 访问量 197万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览