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

测试数据:ip-to-hosts.txt

18.217.167.70 United States
206.96.54.107 United States
196.109.151.139 Mauritius
174.52.58.113 United States
142.111.216.8 Canada

代码实现:

package country;

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; public class Ip2Hosts {
public static void main(String[] args) throws Exception { //指定输入输出路径
args =new String[] {"hdfs://10.16.17.182:9000/test/in/ip-to-hosts.txt","hdfs://10.16.17.182:9000/test/out/0821/09"};
System.exit(run(args));
} public static int run(String[] args) throws Exception { Job job = Job.getInstance(new Configuration());
job.setJarByClass(Ip2Hosts.class); job.setMapperClass(IPCountryMapper.class);
job.setReducerClass(IPCountryReducer.class); job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class); job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1])); /**
* 输出 08 和 09 需要调用此设置,07 就需要注释掉
*/
MultipleOutputs.addNamedOutput(job,"abc",TextOutputFormat.class,Text.class,IntWritable.class); //通过此配置可以不再产生默认的空文件【part-*-00000】
LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class); return job.waitForCompletion(true) ? 1 : 0; }
//map阶段
public static class IPCountryMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
@Override
protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
String[] splited = value.toString().split("\t");
context.write(new Text(splited[1]), new IntWritable(1));
}
}
//reduce阶段
public static class IPCountryReducer extends Reducer<Text, IntWritable, Text, IntWritable> { //1.定义多文件输出类MultipleOutputs
private MultipleOutputs<Text, IntWritable> mos; @Override
protected void setup(Context context
) throws IOException, InterruptedException { //2.MultipleOutputs初始化
mos = new MultipleOutputs<Text, IntWritable>(context);
} @Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context
) throws IOException, InterruptedException {
int total = 0;
for(IntWritable value: values) {
total += value.get();
}
        //3.调用MultipleOutputs中的write()方法
  //07-输出
mos.write(/*"abc",*/ key, new IntWritable(total),key.toString()); //08-输出
mos.write("abc", key, new IntWritable(total)/*,key.toString()*/); //09-输出
mos.write("abc", key, new IntWritable(total),key.toString());
} @Override
protected void cleanup(Context context
) throws IOException, InterruptedException { //4.关闭流资源
mos.close();
}
} }

代码解读:

1).输出-07所调用的方法和对应的输出结果:

/**
* @ 输出的key类型
* @ 输出的value类型
* @ 输出的基路径,实际输出结果为:'基路径-r-00000'
*/
MultipleOutputs.write(KEYOUT key, VALUEOUT value, String baseOutputPath)

2).输出-所调用的方法和对应的输出结果:

/**
* @ 自定义的输出.对于不指定'基路径',则结果为:'自定义的输出-r-00000'
* @ 输出的key类型
* @ 输出的value类型
*/
MultipleOutputs.write(String namedOutput, K key, V value)

3).输出-09所调用的方法和对应的输出结果:

/**
* @ 自定义的输出.
* @ 输出的key类型
* @ 输出的value类型
* @ 输出的基路径,指定输出'基路径',则结果为:'基路径-r-00000'
*/
MultipleOutputs.write(String namedOutput, K key, V value, String baseOutputPath)

用法总结:

  1. 在Mapper或Reducer类中创建 MultipleOutputs 成员变量 mos
  2. 在setup()方法中初始化 mos 变量,
  3. 在map()或reduce()方法中调用 mos.write() 方法输出数据,代替context.write()
  4. mos.write() 方法具有三个重载,对于 输出-08-09 还需在Job配置中指定输出格式
  5. 在cleanup()方法中调用 mos.close() 方法关闭输出流

MR案例:多文件输出MultipleOutputs的更多相关文章

  1. MR案例:小文件处理方案

    HDFS被设计来存储大文件,而有时候会有大量的小文件生成,造成NameNode资源的浪费,同时也影响MapReduce的处理效率.有哪些方案可以合并这些小文件,或者提高处理小文件的效率呢? 1). 所 ...

  2. MR案例:Reduce-Join

    问题描述:两种类型输入文件:address(地址)和company(公司)进行一对多的关联查询,得到地址名(例如:Beijing)与公司名(例如:Beijing JD.Beijing Red Star ...

  3. MR案例:倒排索引

    1.map阶段:将单词和URI组成Key值(如“MapReduce :1.txt”),将词频作为value. 利用MR框架自带的Map端排序,将同一文档的相同单词的词频组成列表,传递给Combine过 ...

  4. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  5. hadoop多文件输出

    现实环境中,经常遇到一个问题就是想使用多个Reduce,可是迫于setup和cleanup在每个Reduce中会调用一次,仅仅能设置一个Reduce,无法是实现负载均衡. 问题,假设要在reduce中 ...

  6. JAVA实用案例之文件导出(JasperReport踩坑实录)

    写在最前面 想想来新公司也快五个月了,恍惚一瞬间. 翻了翻博客,因为太忙,也有将近五个多月没认真总结过了. 正好趁着今天老婆出门团建的机会,记录下最近这段时间遇到的大坑-JasperReport. 六 ...

  7. MR案例:定制InputFormat

    数据输入格式 InputFormat类用于描述MR作业的输入规范,主要功能:输入规范检查(比如输入文件目录的检查).对数据文件进行输入切分和从输入分块中将数据记录逐一读取出来.并转化为Map的输入键值 ...

  8. Java IO流操作(III)——File类&案例一:输出制定目录下所有java文件名(包含子目录)&案例二:删除指定的目录(包含子目录)

    1. File常用的构造 File file = new File("字符串路径"); File f = new File("D:\\a\\b.txt"); F ...

  9. 使用log4j配置不同文件输出不同内容

    敲代码中很不注意写日志,虽然明白很重要.今天碰到记录日志,需要根据内容分别输出到不同的文件. 参考几篇文章: 感觉最详细:http://blog.csdn.net/azheng270/article/ ...

随机推荐

  1. Servlet------>jsp自定义标签5(标签体内容改为大写)

    5.把标签体内容改为大写(tld中的配置我就省略了,详细请看jsp自定义标签1) import java.io.IOException; import javax.servlet.jsp.JspExc ...

  2. http协议----->请求头和响应头

    http实用头字段-----Range 如果请求里有这个range头,那么响应里也有 1.首先在webroot下放好a.txt 内容如下: 2.然后在本地有个下载未完成的a.txt 本地a.txt内容 ...

  3. 联合约束 CONCAT()

    w SELECT 原理. SELECT * FROM wz WHERE CONCAT(wint,wchar) NOT IN (SELECT CONCAT(wint,wchar) FROM wa); S ...

  4. QQ空间发表日志的图片上传功能实现

    w间接促使了用户注意图片的顺序,进一步优化的方向的是手指触动或鼠标点击来同时进行图片的增删和调序,避免精确的数字输入. 有效code <form action="wcon/wact&q ...

  5. 数字货币量化分析报告_20170905_P

    [分析时间]2017-09-05 16:36:46 [数据来源]中国比特币 https://www.chbtc.com/ef4101d7dd4f1faf4af825035564dd81聚币网 http ...

  6. 剑指Offer——数组中重复的数字

    题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度 ...

  7. C++的全部目标就是最优化资源的利用,以人付出更多为代价。Python刚好是另一个极端(Bjarne就说,一个人至少应该掌握两种计算机语言)

    说 C++ 反人类,是如果把 C++ 看作人(程序员)和资源(电子系统)的桥梁,他的全部目标就是最优化资源的利用,以人付出更多为代价.Python刚好是另一个极端.做好两个一起学.Bjarne就说,一 ...

  8. 【numpy】

    ndarray在某个维度上堆叠,np.stack() np.hstack() np.vstack() https://blog.csdn.net/csdn15698845876/article/det ...

  9. JavaWeb-HttpServletResponse对象一

    web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象,和代表响应的response对象.resquest和response对象既然代表请求和响应,那么要 ...

  10. Php 创建XML

    Php 创建XML  Php 创建XML并保存,学习示比例如以下: <? php try{ //创建DOMDocument 对象 $dom = new DOMDocument("1.0 ...