解读:MultipleOutputs类
//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.
- 使用指定 自定义输出 的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类的更多相关文章
- 【java源码】解读HashTable类背后的实现细节
HashTable这个类实现了哈希表从key映射到value的数据结构形式.任何非null的对象都可以作为key或者value. 要在hashtable中存储和检索对象,作为key的对象必须实现has ...
- 详细解读LruCache类
LruCache是android提供的一个缓存工具类,其算法是最近最少使用算法.它把最近使用的对象用“强引用”存储在LinkedHashMap中,并且把最近最少使用的对象在缓存值达到预设定值之前就从内 ...
- 逐步解读String类(一)
一句题外话 面试刚入行的Java新手,侧重基础知识:面试有多年工作经验的老鸟,多侧重对具体问题的解决策略. 从一类面试题说起 考察刚入行菜鸟对基础知识的掌握程度,面试官提出关于String类的内容挺常 ...
- MR案例:多文件输出MultipleOutputs
问题描述:现有 ip-to-hosts.txt 数据文件,文件中每行数据有两个字段:分别是ip地址和该ip地址对应的国家,以'\t'分隔.要求汇总不同国家的IP数,并以国家名为文件名将其输出.解读:M ...
- 通过MultipleOutputs写到多个文件
MultipleOutputs 类可以将数据写到多个文件,这些文件的名称源于输出的键和值或者任意字符串.这允许每个 reducer(或者只有 map 作业的 mapper)创建多个文件. 采用name ...
- MapReduce 规划 六系列 MultipleOutputs采用
在前面的示例,输出文件名是默认: _logs part-r-00001 part-r-00003 part-r-00005 part-r-00007 part-r-00009 part-r-00011 ...
- hadoop多文件输出MultipleOutputFormat和MultipleOutputs
1.MultipleOutputFormat可以将相似的记录输出到相同的数据集.在写每条记录之前,MultipleOutputFormat将调用generateFileNameForKeyValue方 ...
- 详细解读Volley(三)—— ImageLoader & NetworkImageView
ImageLoader是一个加载网络图片的封装类,其内部还是由ImageRequest来实现的.但因为源码中没有提供磁盘缓存的设置,所以咱们还需要去源码中进行修改,让我们可以更加自如的设定是否进行磁盘 ...
- 使用MultipleInputs和MultipleOutputs
还是计算矩阵的乘积,待计算的表达式如下: S=F*[B+mu(u+s+b+d)] 其中,矩阵B.u.s.d分别存放在名称对应的SequenceFile文件中. 1)我们想分别读取这些文件(放在不同的文 ...
随机推荐
- JRebel插件安装配置与破解激活(多方案)详细教程
JRebel 介绍 IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,浪费不少生命啊.目前对于idea热部署最好的解决方案就是安装JRebel插件 ...
- Struts2中的类型转换与复杂对象配合使用
form 标签可以被映射到一个属性的属性 manager.java package com.atguigu.struts2.model; import java.util.Date; public c ...
- window.navigator.userAgent $_SERVER['HTTP_USER_AGENT']
wjs php返回结果一致 <script> !function () { var UA = window.navigator.userAgent, docEl = document.do ...
- [LeetCode] 1.Two Sum - Swift
1. Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...
- datasnap 关于lifecycle的问题
首先DSServerClass的lifecycle属性有Invocation.Server.Session三种模式: 简单叙述一下三点区别: server:datasnap只初始化一个TDSServe ...
- requests和bs4
requests模块,仿造浏览器发送Http请求bs4主要对html或xml格式字符串解析成对象,使用find/find_all查找 text/attrs 爬取汽车之家 爬取汽车之家的资讯信息,它没有 ...
- 【我的Android进阶之旅】Jenkins挂载slave节点,增强分布式编译的效率
由于公司的Jenkins任务越来越多,而且所有的Android Jenkins任务都在同一台服务器上进行编译,而且该服务器配置Jenkins任务最多3个任务同时运行,所以有时候大家一起编译的时候,只能 ...
- (转)VC串口小程序(用SerialPort类)
××××××××××××××××××××××××××××××××××××××××××××××××××××× 在MFC里面实现串口通讯有很多方式: 方案一:使用微软公司提供的 串口类,SerialPor ...
- codeblocks opengl的配置
codeblocks opengl的配置 GLUT 3.7 下载地址:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip ...
- Web 框架 Flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...