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

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

  1. 18.217.167.70 United States
  2. 206.96.54.107 United States
  3. 196.109.151.139 Mauritius
  4. 174.52.58.113 United States
  5. 142.111.216.8 Canada

代码实现:

  1. package country;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.LongWritable;
  9. import org.apache.hadoop.io.Text;
  10. import org.apache.hadoop.mapreduce.Job;
  11. import org.apache.hadoop.mapreduce.Mapper;
  12. import org.apache.hadoop.mapreduce.Reducer;
  13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  15. import org.apache.hadoop.mapreduce.lib.output.LazyOutputFormat;
  16. import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
  17. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  18.  
  19. public class Ip2Hosts {
  20. public static void main(String[] args) throws Exception {
  21.  
  22. //指定输入输出路径
  23. 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"};
  24. System.exit(run(args));
  25. }
  26.  
  27. public static int run(String[] args) throws Exception {
  28.  
  29. Job job = Job.getInstance(new Configuration());
  30. job.setJarByClass(Ip2Hosts.class);
  31.  
  32. job.setMapperClass(IPCountryMapper.class);
  33. job.setReducerClass(IPCountryReducer.class);
  34.  
  35. job.setMapOutputKeyClass(Text.class);
  36. job.setMapOutputValueClass(IntWritable.class);
  37.  
  38. job.setOutputKeyClass(Text.class);
  39. job.setOutputValueClass(IntWritable.class);
  40.  
  41. FileInputFormat.addInputPath(job, new Path(args[0]));
  42. FileOutputFormat.setOutputPath(job, new Path(args[1]));
  43.  
  44. /**
  45. * 输出 08 和 09 需要调用此设置,07 就需要注释掉
  46. */
    MultipleOutputs.addNamedOutput(job,"abc",TextOutputFormat.class,Text.class,IntWritable.class);
  47.  
  48. //通过此配置可以不再产生默认的空文件【part-*-00000】
  49. LazyOutputFormat.setOutputFormatClass(job, TextOutputFormat.class);
  50.  
  51. return job.waitForCompletion(true) ? 1 : 0;
  52.  
  53. }
  54. //map阶段
  55. public static class IPCountryMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
  56. @Override
  57. protected void map(LongWritable key, Text value,Context context) throws IOException, InterruptedException {
  58. String[] splited = value.toString().split("\t");
  59. context.write(new Text(splited[1]), new IntWritable(1));
  60. }
  61. }
  62. //reduce阶段
  63. public static class IPCountryReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
  64.  
  65. //1.定义多文件输出类MultipleOutputs
  66. private MultipleOutputs<Text, IntWritable> mos;
  67.  
  68. @Override
  69. protected void setup(Context context
  70. ) throws IOException, InterruptedException {
  71.  
  72. //2.MultipleOutputs初始化
  73. mos = new MultipleOutputs<Text, IntWritable>(context);
  74. }
  75.  
  76. @Override
  77. protected void reduce(Text key, Iterable<IntWritable> values, Context context
  78. ) throws IOException, InterruptedException {
  79. int total = 0;
  80. for(IntWritable value: values) {
  81. total += value.get();
  82. }
  83.         //3.调用MultipleOutputs中的write()方法
      //07-输出
  84. mos.write(/*"abc",*/ key, new IntWritable(total),key.toString());
  85.  
  86. //08-输出
  87. mos.write("abc", key, new IntWritable(total)/*,key.toString()*/);
  88.  
  89. //09-输出
  90. mos.write("abc", key, new IntWritable(total),key.toString());
  91. }
  92.  
  93. @Override
  94. protected void cleanup(Context context
  95. ) throws IOException, InterruptedException {
  96.  
  97. //4.关闭流资源
  98. mos.close();
  99. }
  100. }
  101.  
  102. }

代码解读:

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

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

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

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

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

  1. /**
  2. * @ 自定义的输出.
  3. * @ 输出的key类型
  4. * @ 输出的value类型
  5. * @ 输出的基路径,指定输出'基路径',则结果为:'基路径-r-00000'
  6. */
  7. 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. python2--升级python3

    先安装开发工具包: yum -y group install "Development Tools" 安装Python的依赖包: yum -y install openssl-de ...

  2. Centos6.5升级openssh至7.4版本

    一,备份配置文件,以备升级失败进行回退 二,下载安装包 wget http://www.zlib.net/zlib-1.2.11.tar.gz wget https://openbsd.mirror. ...

  3. find-if-an-item-is-in-a-javascript-array

    http://stackoverflow.com/questions/143847/best-way-to-find-if-an-item-is-in-a-javascript-array Best ...

  4. Yii2 里使用Redis扩展

    Redis是个很不错的Nosql数据库,比Memcached的好处是能持久化数据. Yii2里使用Redis ,首先要扩展Redis.可以在composer.json 里添加 redis " ...

  5. SQLALchemy的其他常用操作

    使用连接池的两种方式 第一种方式: 直接从SessionFactory里获取,此时如果需要开启多个进程,那么创建连接池的代码一定要放在循环里面 不然的话每个进程都是用一个session了 from s ...

  6. 一次因为文件名开头包含空格而导致FTP文件一直无法下载的悲剧!

    最近负责公司研究新的多渠道打包方案,之前的打包方案太慢了,因此采用了美团的Android Signature V2 Scheme签名下的新一代渠道包打包神器 方案进行了多渠道打包.但是由于马虎,在配置 ...

  7. 每人涨10%的工资,涨的前一共不超过5万,从低工资往高工资的人涨,超过5W则停止涨,问涨的钱花了多少,多少人获得了涨薪。

    ;with test(CID,money,NewAmount) as ( SELECT Row_Number() over ( order by money ) as CID ,money ,mone ...

  8. 缓存系统MemCached的Java客户端优化历程

    Memcached 是什么? Memcached是一种集中式Cache,支持分布式横向扩展.这里需要解释说明一下,很多开发者觉得Memcached是一种分布式缓存系统,但是其实Memcached服务端 ...

  9. SIP UserAgent (B2BUA client)——linphonec

    1.linphone编译 linphone一般用在android/ios/windows/mobile上,但是没有图形界面的linphonec命令行程序用在资源紧张的硬件平台上也跟pjsip命令行一样 ...

  10. git零散知识

    集中式与分布式的差别: 集中式的服务器挂了所有人都挂了,因为完整仓库只存在服务器上,分布式如果github挂了你可以重新建一个服务器,然后把任何一个人的仓库clone过去 一句话总结:分布式版本控制的 ...