//MultipleOutputs类用于简化多文件输出
The MultipleOutputs class simplifies writing output data to multiple outputs

//案例一:在job默认的输出之外,附加自定义的输出.自定义的输出可以指定:输出格式以及 key/value 类型.
Case one: writing to additional outputs other than the job default output. Each additional output, or named output, may be configured with its own OutputFormat, with its own key class and with its own value class.

//案例二:将不同的数据写到不同的文件中
Case two: to write data to different files provided by user

//MultipleOutputs支持计数器,默认是不启用状态.计数器组名是MultipleOutputs类的名字.计数器名字是自定义输出的名字.将记录个数写入对应的计数器.
MultipleOutputs supports counters, by default they are disabled. The counters group is the MultipleOutputs class name. The names of the counters are the same as the output name. These count the number records written to each output name.

//Job配置模板
Usage pattern for job submission: Job job = new Job(); FileInputFormat.setInputPath(job, inDir);
FileOutputFormat.setOutputPath(job, outDir); job.setMapperClass(MOMap.class);
job.setReducerClass(MOReduce.class);
... //定义TextOutputFormat格式的'text'输出
MultipleOutputs.addNamedOutput(job, "text", TextOutputFormat.class,
LongWritable.class, Text.class); //定义SequenceFileOutputFormat格式的'seq'输出
MultipleOutputs.addNamedOutput(job, "seq",
SequenceFileOutputFormat.class,
LongWritable.class, Text.class);
... job.waitForCompletion(true);
...
//reduce中使用
Usage in Reducer: String generateFileName(K k, V v) {
return k.toString() + "_" + v.toString();
} public class MOReduce extends
Reducer<WritableComparable, Writable,WritableComparable, Writable> { //1. 定义MultipleOutputs类型变量
private MultipleOutputs mos;

public void setup(Context context) {
...
//2. setup()方法对其初始化
mos = new MultipleOutputs(context);
} public void reduce(WritableComparable key, Iterator<Writable> values,
Context context)
throws IOException {
...
mos.write("text", , key, new Text("Hello"));

//3. reduce()方法中使用MultipleOutputs类的write方法输出 /**
*参数列表
* @ 自定义的输出名
* @ 输出的key
* @ 输出的value
* @ 输出的基础路径
*/
mos.write("seq", LongWritable(1), new Text("Bye"), "seq_a");
mos.write("seq", LongWritable(2), key, new Text("Chau"), "seq_b");
mos.write(key, new Text("value"), generateFileName(key, new Text("value")));
...
} public void cleanup(Context) throws IOException { //4. 关闭MultipleOutputs输出流
mos.close();
...
}
}

When used in conjuction with org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat, MultipleOutputs can mimic the behaviour of MultipleTextOutputFormat and MultipleSequenceFileOutputFormat from the old Hadoop API - ie, output can be written from the Reducer to more than one location.

//使用以下方法可以不用指定自定义输出
Use MultipleOutputs.write(KEYOUT key, VALUEOUT value, String baseOutputPath) to write key and value to a path specified by baseOutputPath, with no need to specify a named output:

//定义变量
private MultipleOutputs out; public void setup(Context context) {
//初始化变量
out = new MultipleOutputs(context);
...
} public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {
for (Text t : values) {

//调用类中的Write()方法
/**
*参数列表
* @ 输出的key
* @ 输出的value
* @ 指定输出的基础路径
*/
out.write(key, t, generateFileName(<parameter list...>));
}
} protected void cleanup(Context context) throws IOException, InterruptedException {

//关闭输出流
out.close();
}
//自定义的生成基础路径的方法,即符号"/"有无的区别 Use your own code in generateFileName() to create a custom path to your results. '/' characters in baseOutputPath will be translated into directory levels in your file system. Also, append your custom-generated path with "part" or similar, otherwise your output will be -00000, -00001 etc. No call to context.write() is necessary. See example generateFileName() code below. private String generateFileName(Text k) {
// expect Text k in format "Surname|Forename"
String[] kStr = k.toString().split("\\|"); String sName = kStr[0];
String fName = kStr[1]; // example for k = Smith|John
// output written to /user/hadoop/path/to/output/Smith/John-r-00000 (etc)
return sName + "/" + fName;
}

//以上使用MultipleOutputs类的方法方式都会产生一个空的默认的【part-*-00000】的文件.
//在Job的配置中使用 LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);
//代替
job.setOutputFormatClass(TextOutputFormat.class);
//可以避免差生【part-*-00000】这一空文件
Using MultipleOutputs in this way will still create zero-sized default output, eg part-00000. To prevent this use LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class); instead of job.setOutputFormatClass(TextOutputFormat.class); in your Hadoop job configuration.

总结:MR案例:多文件输出MultipleOutputs

  • 使用指定 自定义输出 的write方法,需要在Job配置中添加 MultipleOutputs.addNamedOutput(Job job, String namedOutput, Class<? extends OutputFormat> outputFormatClass, Class<?> keyClass, Class<?> valueClass);方法
  • 对于不使用指定 自定义输出 的write方法则不需要
  • Job结果中不再产生默认的空文件【part-*-00000】需要在配置中使用 LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);

解读:MultipleOutputs类的更多相关文章

  1. 【java源码】解读HashTable类背后的实现细节

    HashTable这个类实现了哈希表从key映射到value的数据结构形式.任何非null的对象都可以作为key或者value. 要在hashtable中存储和检索对象,作为key的对象必须实现has ...

  2. 详细解读LruCache类

    LruCache是android提供的一个缓存工具类,其算法是最近最少使用算法.它把最近使用的对象用“强引用”存储在LinkedHashMap中,并且把最近最少使用的对象在缓存值达到预设定值之前就从内 ...

  3. 逐步解读String类(一)

    一句题外话 面试刚入行的Java新手,侧重基础知识:面试有多年工作经验的老鸟,多侧重对具体问题的解决策略. 从一类面试题说起 考察刚入行菜鸟对基础知识的掌握程度,面试官提出关于String类的内容挺常 ...

  4. MR案例:多文件输出MultipleOutputs

    问题描述:现有 ip-to-hosts.txt 数据文件,文件中每行数据有两个字段:分别是ip地址和该ip地址对应的国家,以'\t'分隔.要求汇总不同国家的IP数,并以国家名为文件名将其输出.解读:M ...

  5. 通过MultipleOutputs写到多个文件

    MultipleOutputs 类可以将数据写到多个文件,这些文件的名称源于输出的键和值或者任意字符串.这允许每个 reducer(或者只有 map 作业的 mapper)创建多个文件. 采用name ...

  6. MapReduce 规划 六系列 MultipleOutputs采用

    在前面的示例,输出文件名是默认: _logs part-r-00001 part-r-00003 part-r-00005 part-r-00007 part-r-00009 part-r-00011 ...

  7. hadoop多文件输出MultipleOutputFormat和MultipleOutputs

    1.MultipleOutputFormat可以将相似的记录输出到相同的数据集.在写每条记录之前,MultipleOutputFormat将调用generateFileNameForKeyValue方 ...

  8. 详细解读Volley(三)—— ImageLoader & NetworkImageView

    ImageLoader是一个加载网络图片的封装类,其内部还是由ImageRequest来实现的.但因为源码中没有提供磁盘缓存的设置,所以咱们还需要去源码中进行修改,让我们可以更加自如的设定是否进行磁盘 ...

  9. 使用MultipleInputs和MultipleOutputs

    还是计算矩阵的乘积,待计算的表达式如下: S=F*[B+mu(u+s+b+d)] 其中,矩阵B.u.s.d分别存放在名称对应的SequenceFile文件中. 1)我们想分别读取这些文件(放在不同的文 ...

随机推荐

  1. INFORMATION_SCHEMA.STATISTICS 统计 表 库 大小

    INFORMATION_SCHEMA MySQL :: MySQL 5.5 Reference Manual :: 21 INFORMATION_SCHEMA Tables https://dev.m ...

  2. YAML 语言

    1. YAML 介绍 YAML:以数据为中心,比JSON,XML更适合做配置文件; //示例: server: port: 8081 //此处有空格 2. YAML 基本语法 使用缩进表示层级关系; ...

  3. JSON.parse和JSON.stringify

    var json_arr = [];                //parse用于从一个字符串中解析出json对象;stringify()用于从一个对象解析出字符串                 ...

  4. git本地与远程分支

    已经有远程分支,在本地检出,并且关联到远程分支 git checkout --trach origin/远程分支名 git checkout -b 本地分支名  origin/远程分支名 $ git ...

  5. XTU1198:Candy(背包)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/libin56842/article/details/26182519 题目描写叙述 Henry和Le ...

  6. spring MVC 学习(四)---拦截器,视图解析器

    1.接口HandlerInterceptor 该接口包含3个方法,分别是preHandle,postHandle,afterCompletion,分别代表着执行前,执行后,执行完成要执行的方法,其中p ...

  7. JDK 注解详解

    注解用途 我们在使用spring MVC框架时用到了很多的注解,如:@Controller.@RequestMapping等等,spring框架通过反射获取到标签进行不同的逻辑处理.注解是代码的附属信 ...

  8. redis实现cache系统实践(六)

    1. 介绍 rails中就自带有cache功能,不过它默认是用文件来存储数据的.我们要改为使用redis来存储.而且我们也需要把sessions也存放到redis中.关于rails实现cache功能的 ...

  9. 理解java动态代理

    java动态代理是java语言的一项高级特性.在平时的项目开发中,可能很难遇到动态代理的案例.但是动态代理在很多框架中起着不可替代的作用,例如Spring的AOP.今天我们就聊一聊java动态代理的实 ...

  10. Hadoop2.7.3+spark2.1.0+hbase0.98分布式集群部署

    运行环境配置(10.79.115.111-114) 1.关闭防火墙与selinux 关闭防火墙: CentOS 7.x默认使用的是firewall作为防火墙. systemctl stop firew ...