• 基于hadoop的专利数据处理示例
  • MapReduce程序框架
  • 用于计数统计的MapReduce基础程序
  • 支持用脚本语言编写MapReduce程序的hadoop流式API
  • 用于提升性能的Combiner
 
1、获取专利数据集
 
获取网址:http://www.nber.org/patents/
使用数据集:cite75_99.txt和apat63_99.txt
 
2、构建MapReduce程序的基础模版
 
 

代码清单 典型hadoop程序模版
 
  1. import java.io.IOException;
  2. import java.util.Iterator;
  3.  
  4. import org.apache.hadoop.conf.Configuration;
  5. import org.apache.hadoop.conf.Configured;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.Text;
  8. import org.apache.hadoop.mapred.FileInputFormat;
  9. import org.apache.hadoop.mapred.FileOutputFormat;
  10. import org.apache.hadoop.mapred.JobClient;
  11. import org.apache.hadoop.mapred.JobConf;
  12. import org.apache.hadoop.mapred.KeyValueTextInputFormat;
  13. import org.apache.hadoop.mapred.MapReduceBase;
  14. import org.apache.hadoop.mapred.Mapper;
  15. import org.apache.hadoop.mapred.OutputCollector;
  16. import org.apache.hadoop.mapred.Reducer;
  17. import org.apache.hadoop.mapred.Reporter;
  18. import org.apache.hadoop.mapred.TextOutputFormat;
  19. import org.apache.hadoop.util.Tool;
  20. import org.apache.hadoop.util.ToolRunner;
  21.  
  22. public class MyJob extends Configured implements Tool {
  23.  
  24. public static class MapClass extends MapReduceBase
  25. implements Mapper<Text, Text, Text, Text> {
  26.  
  27. public void map(Text key, Text value,
  28. OutputCollector<Text, Text> output,
  29. Reporter reporter) throws IOException {
  30.  
  31. output.collect(value, key);
  32. }
  33. }
  34.  
  35. public static class Reduce extends MapReduceBase
  36. implements Reducer<Text, Text, Text, Text> {
  37.  
  38. public void reduce(Text key, Iterator<Text> values,
  39. OutputCollector<Text, Text> output,
  40. Reporter reporter) throws IOException {
  41.  
  42. String csv = "";
  43. while (values.hasNext()) {
  44. if (csv.length() > 0) csv += ",";
  45. csv += values.next().toString();
  46. }
  47. output.collect(key, new Text(csv));
  48. }
  49. }
  50.  
  51. public int run(String[] args) throws Exception {
  52. Configuration conf = getConf();
  53.  
  54. JobConf job = new JobConf(conf, MyJob.class);
  55.  
  56. Path in = new Path(args[0]);
  57. Path out = new Path(args[1]);
  58. FileInputFormat.setInputPaths(job, in);
  59. FileOutputFormat.setOutputPath(job, out);
  60.  
  61. job.setJobName("MyJob");
  62. job.setMapperClass(MapClass.class);
  63. job.setReducerClass(Reduce.class);
  64.  
  65. job.setInputFormat(KeyValueTextInputFormat.class);
  66. job.setOutputFormat(TextOutputFormat.class);
  67. job.setOutputKeyClass(Text.class);
  68. job.setOutputValueClass(Text.class);
  69. job.set("key.value.separator.in.input.line", ",");
  70.  
  71. JobClient.runJob(job);
  72.  
  73. return 0;
  74. }
  75.  
  76. public static void main(String[] args) throws Exception {
  77. int res = ToolRunner.run(new Configuration(), new MyJob(), args);
  78.  
  79. System.exit(res);
  80. }
  81. }
 

 
     框架的核心在run()方法中,也称为driver。它实例化、配置并传递一个JobConf对象命名的作业给JobClient.runJob()以启动MapReduce作业。JobConf对象将保持作业运行所需的全部配置参数。Driver需要在作业中为每个作业定制基本参数,包括输入路径、输出路径、Mapper类和Reducer类。另外,每个作业可以重置默认的作业属性,例如InputFormat、OutputFormat等,也可以调用JobConf对象中的set()方法填充人意配置参数。一旦传递JobConf对象到JobClient.runJob(),它就被视为作业的总体规划,成为决定这个作业如何运作的蓝本。
 
     JobConf对象有许多参数,但我们并不希望全部的参数都通过编写driver来设置,可以把Hadoop安装时的配置文件作为一个很好的起点。同时,用户可能希望在命令行启动一个作业时传递额外的参数来改变作业配置。Driver可以通过自定义一组命令并自行处理用户参数,来支持用户修改其中的一些配置。因为经常需要做这样的任务,hadoop框架便提供了ToolRunner、Tool和Configured来简化其实现。
 
     通过使用ToolRunner,MyJob可以自动支持下表中的选项:
 
选项
描述
-conf <configuration file>  指定一个配置文件
-D <property=value> 给JobConf属性赋值
-fs <local | namenode:port> 指定一个NameNode,可以是“local”
-jt <local | jobtracker:port> 指定一个JobTracker
-files <list of files> 指定一个以逗号分隔的文件列表,用于MapReduce作业。这些文件自动地分布到所有节点,使之可从本地获取
-libjars <list of jars> 指定一个以逗号分隔的jar文件列表,使之包含在所有任务JVM的classpath中
-archives <list of archives> 指定一个以逗号分隔的存档文件列表,使之可以在所有任务节点上打开
 
Mapper类和Reducer类如下所示:
 
public static class MapClass extends MapReduceBase
     implements Mapper<k1, v1, k2, v2> {
     public void map(k1 key, v1 value, OutputCollector<k2, v2> output, Reporter reporter) throws IOException { }
}
 
public static class Reducer extends MapReduceBase
     implements Mapper<k2, v2, k3, v3> {
     public void map(k2 key, Iterator<v2> values, OutputCollector<k3, v3> output, Reporter reporter) throws IOException { }
}
 
     Mapper类的核心操作为map()方法,Reducer类为reduce()方法。每个map()方法的调用分别被赋予一个类型为k1和v1的键/值对。这个键/值对由mapper生成,并通过OutputCollector对象的collect()方法来输出。你需要在map()方法中的合适位置调用:
     output.collect((k2) k, (v2) v);
 
     在Reudcer中reduce()方法的每次调用均被赋予k2类型的键,以及v2类型的一组值。注意它必须与mapper中使用的k2和v2类型相同。Reduce()方法可能会循环遍历v2类型的所有值:
     while (values.hasNext()) {
          v2 v = values.next();
          ...
     }
 
     Reduce()方法还使用OutputCollector来搜集其键/值的输出,它们的类型为k3/v3。在reduce()方法中可以调用:
     output.collect((k3) k, (v3) v);
 
     除了在Mapper和Reducer之间保持k2和v2的类型一致,还需要确保在Mapper和Reducer中使用的键值类型与在driver中设置的输入格式、输出键的类,以及输出值的类保持一致。
 
 
3、计数
 
可以修改获取反向引用索引的程序来输出技术结果,只需要修改Reducer。如果选择让计数结果输出的类型为IntWritable,就需要在Reducer代码中的3个地方进行声明:
 
public static class Reduce extends MapReduceBase
     implements Reducer<Text, Text, Text, IntWritable> {
     public void reduce(Text key, Iterator<Text> values, OutputCollector<Text, IntWritable> output,
                                    Reporter reporter) throws IOException {
          int count = 0;
          while (values.hasNext()) {
          values.next();
          count++;
          }
          output.collect(key, new IntWritable(count));
     }
}
 
  1. 编写MapReduce程序的第一步是了解数据流;
  2. 基于对数据流的理解,可以为输入、中间结果、输出的键/值对k1、v1、k2、v2、k3和v3设定类型;
  3. 根据数据流河数据类型,很容易能够理解程序代码。
 

代码清单 CitationHistogram.java
 
  1. import java.io.IOException;
  2. import java.util.Iterator;
  3.  
  4. import org.apache.hadoop.conf.Configuration;
  5. import org.apache.hadoop.conf.Configured;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.Text;
  9. import org.apache.hadoop.mapred.FileInputFormat;
  10. import org.apache.hadoop.mapred.FileOutputFormat;
  11. import org.apache.hadoop.mapred.JobClient;
  12. import org.apache.hadoop.mapred.JobConf;
  13. import org.apache.hadoop.mapred.KeyValueTextInputFormat;
  14. import org.apache.hadoop.mapred.MapReduceBase;
  15. import org.apache.hadoop.mapred.Mapper;
  16. import org.apache.hadoop.mapred.OutputCollector;
  17. import org.apache.hadoop.mapred.Reducer;
  18. import org.apache.hadoop.mapred.Reporter;
  19. import org.apache.hadoop.mapred.TextOutputFormat;
  20. import org.apache.hadoop.util.Tool;
  21. import org.apache.hadoop.util.ToolRunner;
  22.  
  23. public class CitationHistogram extends Configured implements Tool {
  24.  
  25. public static class MapClass extends MapReduceBase
  26. implements Mapper<Text, Text, IntWritable, IntWritable> {
  27.  
  28. private final static IntWritable uno = new IntWritable(1);
  29. private IntWritable citationCount = new IntWritable();
  30.  
  31. public void map(Text key, Text value,
  32. OutputCollector<IntWritable, IntWritable> output,
  33. Reporter reporter) throws IOException {
  34.  
  35. citationCount.set(Integer.parseInt(value.toString()));
  36. output.collect(citationCount, uno);
  37. }
  38. }
  39.  
  40. public static class Reduce extends MapReduceBase
  41. implements Reducer<IntWritable,IntWritable,IntWritable,IntWritable>
  42. {
  43.  
  44. public void reduce(IntWritable key, Iterator<IntWritable> values,
  45. OutputCollector<IntWritable, IntWritable>output,
  46. Reporter reporter) throws IOException {
  47.  
  48. int count = 0;
  49. while (values.hasNext()) {
  50. count += values.next().get();
  51. }
  52. output.collect(key, new IntWritable(count));
  53. }
  54. }
  55.  
  56. public int run(String[] args) throws Exception {
  57. Configuration conf = getConf();
  58.  
  59. JobConf job = new JobConf(conf, CitationHistogram.class);
  60.  
  61. Path in = new Path(args[0]);
  62. Path out = new Path(args[1]);
  63. FileInputFormat.setInputPaths(job, in);
  64. FileOutputFormat.setOutputPath(job, out);
  65.  
  66. job.setJobName("CitationHistogram");
  67. job.setMapperClass(MapClass.class);
  68. job.setReducerClass(Reduce.class);
  69.  
  70. job.setInputFormat(KeyValueTextInputFormat.class);
  71. job.setOutputFormat(TextOutputFormat.class);
  72. job.setOutputKeyClass(IntWritable.class);
  73. job.setOutputValueClass(IntWritable.class);
  74.  
  75. JobClient.runJob(job);
  76.  
  77. return 0;
  78. }
  79.  
  80. public static void main(String[] args) throws Exception {
  81. int res = ToolRunner.run(new Configuration(),
  82. new CitationHistogram(),
  83. args);
  84.  
  85. System.exit(res);
  86. }
  87. }
 

 
4、适应Hadoop API的改变
 
     (1)首先值得注意的是,在新的API中org.apache.hadoop.mapred的许多类都被移走了。多数被放入org.apache.hadoop.mapreduce,而且类库都放在org.apache.hadoop.mapreduce.lib的一个包中。当转为使用新API时,org.apache.hadoop.mapred下所有类的import声明就不存在了,它们都被弃用。
 
     (2)新API中最有益的变化是引入了上下文对象context。最直接的影响在于替换了map()和reduce()方法中使用的OutputCollector和Reporter对象。深远的影响是统一了应用代码和MapReduce框架之间的通信,并固定了Mapper和Reduce的API,使得添加新功能时不会改变基本方法签名。
 
     (3)新的map()和reduce()方法分别被包含在新的抽象类Mapper和Reducer中。它们取代了原始API中的Mapper和Reducer接口。新的抽象类也替换了MapReduceBase类,使之被弃用。
 
     (4)新的map()和Reduce()方法多了一两处细微的改变。它们可以抛出InterruptedException而非单一的IOException。而且,reduce()方法不再以Iterator而以Iterable来接受一个值的列表,这样更容易使用Java的foreach语义来实现迭代。
 
原始API中的签名
 
public static class MapClass extends MapReduceBase
     implements Mapper<k1, v1, k2, v2> {
     public void map(k1 key, v1 value, OutputCollector<k2, v2> output, Reporter reporter) throws IOException { }
}
 
public static class Reducer extends MapReduceBase
     implements Mapper<k2, v2, k3, v3> {
     public void map(k2 key, Iterator<v2> values, OutputCollector<k3, v3> output, Reporter reporter) throws IOException { }
}
 
新API一定程度上对它们做了简化
 
public static class MapClass extends Mapper<k1, v1, k2, v2> {
     public void map(k1 key, v1 value, Context context) throws IOException, InterruptedException { }
}
 
public static class Reduce extends Reducer<k2, v2, k3, v3> {
     public void map(k2 key, Iterable<v2> value, Context context) throws IOException, InterruptedException { }
}
 
     (5)还需要改变driver中的一些内容来支持新的API。在新的API中JobConf和JobClient被替换了。它们的功能已经被放入Configuration类和一个新的类Job中。Configuration类纯粹为了配置作业而设,而Job类负责定义和控制一个作业的执行。作业的构造和提交执行现在放在Job中。
 
原API
 
JobConf job = new JobConf(conf, MyJob.calss);
job.setJobName(“MyJob");
 
JobClient.runJob(job);
 
新API
 
Job job = new Job(conf, “MyJob”);
job.setJarByClass(MyJob.class);
 
System.exit(job.waitForCompletion(true)?0:1);
 

代码清单 基于版本0.20新API重写的hadoop基础程序模版
 
  1. import java.io.IOException;
  2. import java.util.Iterable;
  3.  
  4. import org.apache.hadoop.conf.Configuration;
  5. import org.apache.hadoop.conf.Configured;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.Text;
  8. import org.apache.hadoop.io.LongWritable;
  9. import org.apache.hadoop.mapreduce.Job;
  10. import org.apache.hadoop.mapreduce.Mapper;
  11. import org.apache.hadoop.mapreduce.Reducer;
  12. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  13. import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
  14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  15. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  16. import org.apache.hadoop.util.Tool;
  17. import org.apache.hadoop.util.ToolRunner;
  18.  
  19. public class MyJob extends Configured implements Tool {
  20.  
  21. public static class MapClass extends Mapper<LongWritable, Text, Text, Text> {
  22.  
  23. public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  24.  
  25. String[] citation = value.toString().split(",");
  26. context.write(new Text(citation[1]), new Text(citation[0]));
  27. }
  28. }
  29.  
  30. public static class Reduce extends Reducer<Text, Text, Text, Text> {
  31.  
  32. public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
  33.  
  34. String csv = "";
  35. for (Text val:values) { //Iterable类型允许foreach循环
  36. if (csv.length() > 0) csv += ",";
  37. csv += val.toString();
  38. }
  39.  
  40. context.write(key, new Text(csv));
  41. }
  42. }
  43.  
  44. public int run(String[] args) throws Exception {
  45. Configuration conf = getConf();
  46.  
  47. Job job = new Job(conf, "MyJob");
  48. job.setJarByClass(MyJob.class);
  49.  
  50. Path in = new Path(args[0]);
  51. Path out = new Path(args[1]);
  52. FileInputFormat.setInputPaths(job, in);
  53. FileOutputFormat.setOutputPath(job, out);
  54.  
  55. job.setMapperClass(MapClass.class);
  56. job.setReducerClass(Reduce.class);
  57.  
  58. job.setInputFormatClass(TextInputFormat.class); //兼容的InputFormat类
  59. job.setOutputFormatClass(TextOutputFormat.class);
  60. job.setOutputKeyClass(Text.class);
  61. job.setOutputValueClass(Text.class);
  62.  
  63. System.exit(job.waitForCompletion(true)?0:1);
  64.  
  65. return 0;
  66. }
  67.  
  68. public static void main(String[] args) throws Exception {
  69. int res = ToolRunner.run(new Configuration(), new MyJob(), args);
  70.  
  71. System.exit(res);
  72. }
  73. }
 

 
5、Hadoop的Streaming
 
  1. 通过Unix命令使用Streaming
  2. 通过脚本使用Streaming
  3. 用Streaming处理键/值对
  4. 通过Aggregate包使用Streaming
 
6、使用combiner提升性能
 
hadoop通过扩展MapReduce框架,在mapper和reducer之间增加了一个combiner。你可以将combiner视为reducer的助手。它致力于减少mapper的输出以降低网络和reducer上的压力。为了使combiner工作,它在数据的转换上必须与reducer等价。
 
 
 [转载请注明] http://www.cnblogs.com/zhengrunjian/ 
 
 
 
 

[Hadoop in Action] 第4章 编写MapReduce基础程序的更多相关文章

  1. 第 3 章 编写 PAM 应用程序和服务

    Solaris 开发者安全性指南 Previous: 第 2 章 开发特权应用程序 Next: 第 4 章 编写使用 GSS-API 的应用程序 第 3 章 编写 PAM 应用程序和服务 可插拔验证模 ...

  2. [Hadoop in Action] 第5章 高阶MapReduce

    链接多个MapReduce作业 执行多个数据集的联结 生成Bloom filter   1.链接MapReduce作业   [顺序链接MapReduce作业]   mapreduce-1 | mapr ...

  3. [Hadoop in Action] 第7章 细则手册

    向任务传递定制参数 获取任务待定的信息 生成多个输出 与关系数据库交互 让输出做全局排序   1.向任务传递作业定制的参数        在编写Mapper和Reducer时,通常会想让一些地方可以配 ...

  4. [Hadoop in Action] 第1章 Hadoop简介

    编写可扩展.分布式的数据密集型程序和基础知识 理解Hadoop和MapReduce 编写和运行一个基本的MapReduce程序   1.什么是Hadoop   Hadoop是一个开源的框架,可编写和运 ...

  5. [Hadoop in Action] 第6章 编程实践

    Hadoop程序开发的独门绝技 在本地,伪分布和全分布模式下调试程序 程序输出的完整性检查和回归测试 日志和监控 性能调优   1.开发MapReduce程序   [本地模式]        本地模式 ...

  6. [hadoop in Action] 第3章 Hadoop组件

    管理HDFS中的文件 分析MapReduce框架中的组件 读写输入输出数据   1.HDFS文件操作   [命令行方式]   Hadoop的文件命令采取的形式为: hadoop fs -cmd < ...

  7. [Hadoop in Action] 第2章 初识Hadoop

    Hadoop的结构组成 安装Hadoop及其3种工作模式:单机.伪分布和全分布 用于监控Hadoop安装的Web工具   1.Hadoop的构造模块   (1)NameNode(名字节点)       ...

  8. 《Hadoop权威》学习笔记五:MapReduce应用程序

    一.API的配置---Configuration类 API的配置:Hadoop提供了专门的API对资源进行配置,Configuration类的实例(在org.apache.hadoop.conf包)包 ...

  9. 编写mapreduce的程序的套路

    https://blog.csdn.net/qq_42881421/article/details/83543926 给出下面6个经典案例: http://www.cnblogs.com/xia520 ...

随机推荐

  1. HTML中的拖拉框----在路上(29)

    拖拽框---当鼠标按在指定的区域才可进行拖拽 思想:只有当鼠标是按在一个大div里的小div才可拖拽,其他不可:拖拽框有多种方法,这里以其中一种分享:下面使我自己写的demo,简单有效. <!D ...

  2. Entity Framework中使用IEnumerable<T>、IQueryable<T>及IList<T>的区别

    1. IEnumerable<T> IEnumerable<T> :对于在内存中集合上运行的方法,返回的可枚举对象将捕获传递到方法的参数.在枚举该对象时,将使用查询运算符的逻辑 ...

  3. Eclipse 实用技巧

    代码智能提示 Java智能提示 Window -> Preferences -> Java -> Editor -> Content Assist -> Auto Act ...

  4. 微信企业号开发(1)WebAPI在回调模式中的URL验证

    微信回调模式的官方文档. 开发语言:C#(微信相关功能代码可以从官网下载) 首先,必须要明确几个参数,这几个参数在微信企业号中,每次调用都会使用到. 1.msg_signature:签名(已加密,加密 ...

  5. C#中级-开机自动启动程序

    一.前言 关于C#开机自动启动程序的方法,网上出现比较多的是修改注册表: 1. HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion ...

  6. 自己动手写计算器v1.0

    今天突发奇想,想着看了还几个设计模式了,倒不如写点东西来实践它们.发现计算器这种就比较合适,打算随着设计模式的学习,会对计算器不断的做改进. 包括功能的增加和算法的改进.初学者难免犯错,希望大家不吝指 ...

  7. nginx添加 nginx_heath模块

    原因?为什么会使用nginx_heath 这个模块,主要是如nginx+tomcat部署的时,tomcat挂了之后nginx->upstream 轮询是可以踢掉挂掉的tomcat服务的,如果部署 ...

  8. 企业级应用架构模式N-Tier多层架构

              先来看经典的3层架构,看下图: 涉及到平台可以是: Ruby on Rails, Java EE, ASP.NET, PHP, ColdFusion, Perl, Python 层 ...

  9. Struts2入门(四)——数据输入验证

    一.前言 1.1.什么是输入验证?为什么需要输入验证? 在上一篇文章中,我们学习了数据类型转换,我们提到了表示层数据处理的两个方法,也提到了用户输入数据需要进行类型转换才能得到我们想要的数据,那么,我 ...

  10. NodeJs端口被占用的情况

    在NodeJs运行的时候,我们往往会遇到一个问题:“端口被占用”,这个问题,我们的处理办法有哪些呢? 这里我只介绍一下linux下的方法: 1.使用nodeme(忘记是不是这个啦,回去查下,这个要安装 ...