热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

7.3WordCount示例编写(二)

任务目的理解WordCount示例的业务逻辑掌握MapReduceReduce端编程规范理解WordCount示例Reduce端的自定义业务逻辑的编写熟记MapReduceDri

任务目的
  • 理解 WordCount 示例的业务逻辑
  • 掌握 MapReduce Reduce 端编程规范
  • 理解 WordCount 示例 Reduce 端的自定义业务逻辑的编写
  • 熟记 MapReduce Driver 端编程规范

任务清单


  • 任务1:WordCount Reduce 端程序编写
  • 任务2:WordCount Driver 端程序编写

详细任务步骤

首先回顾一下 WordCount 示例的业务逻辑:

  MapTask 阶段处理每个数据分块的单词统计分析&#xff0c;思路是将每一行文本拆分成一个个的单词&#xff0c;每遇到一个单词则把其转换成一个 key-value 对&#xff0c;比如单词 Car&#xff0c;就转换成<’Car’,1>发送给 ReduceTask 去汇总。

  ReduceTask 阶段将接收 MapTask 的结果&#xff0c;按照 key 对 value 做汇总计数。

Vditor

图1

 

任务1&#xff1a;WordCount Reduce 端程序编写

  回顾 MapReduce Reduce 端编码规范&#xff1a;

  1. 用户自定义的 Reducer 需要继承父类 Reducer
  2. Reducer 的输入数据类型对应 Mapper 的输出数据类型&#xff0c;也是 KV
  3. Reducer 的输出数据是 KV 对的形式&#xff08;KV 的类型可自定义&#xff09;
  4. Reducer 的业务逻辑写在 reduce() 方法
  5. ReduceTask 进程对每一组相同 k 的组调用一次 reduce() 方法

  接下来进入 WordCount Reduce 端程序的编写&#xff0c;eclipse 成功连接到 Hadoop 集群后&#xff0c;在 com.hongyaa.mr 包下创建名为 WordCountReducer.java 的类&#xff0c;如下图所示&#xff1a;

Vditor

图2

 

  首先编写 Reduce 端编程框架&#xff0c;自定义的 WordCountReducer 需要继承父类 Reducer&#xff0c;输入数据和输出数据都是KV 对的形式。具体框架代码如下&#xff1a;

public class WordCountReducer extends Reducer {}

  • KEYIN:对应 Mapper 端输出的 KEYOUT&#xff0c;即单个单词&#xff0c;所以是 String&#xff0c;对应 Hadoop 中的 Text
  • VALUEIN:对应 Mapper 端输出的 VALUEOUT&#xff0c;即单词的数量&#xff0c;所以是Integer&#xff0c;对应 Hadoop 中的 IntWritable
  • KEYOUT:用户自定义逻辑方法返回数据中key的类型&#xff0c;由用户业务逻辑决定&#xff0c;在此wordcount程序中&#xff0c;我们输出的key是单词&#xff0c;所以是String&#xff0c;对应 Hadoop 中的 Text
  • VALUEOUT:用户自定义逻辑方法返回数据中value的类型,由用户业务逻辑决定,在此wordcount程序中,我们输出的value是单词的出现的总次数&#xff0c;所以是Integer&#xff0c;对应 Hadoop 中的 IntWritable

  将框架中的KV对对应的类型修改完成后的代码如下所示&#xff1a;

public class WordCountReducer extends Reducer {}

  已知 Reducer 中的业务逻辑写在 reduce() 方法中&#xff0c;在此 reduce()方法中我们需要接收 MapTask 的输出结果&#xff0c;然后按照 key&#xff08;单词&#xff09; 对 value&#xff08;数量1&#xff09; 做汇总计数。具体代码如下所示&#xff1a;

/*** * * 框架在Map处理完成之后&#xff0c;将所有key-value对缓存起来&#xff0c;进行分组&#xff0c;然后传递一个组&#xff0c;调用一次reduce()方法* * 入参key&#xff0c;是一组相同单词kv对的key*/
&#64;Override
protected void reduce(Text key, Iterable values, Context context)throws IOException, InterruptedException {//&#xff08;1&#xff09;做每个key&#xff08;单词&#xff09;的结果汇总int sum &#61; 0;for (IntWritable v : values) {sum &#43;&#61; v.get();}//&#xff08;2&#xff09;输出每个key&#xff08;单词&#xff09;和其对应的总次数context.write(key, new IntWritable(sum));
}

  WordCountReducer.java 的完整代码如下所示&#xff1a;

public class WordCountReducer extends Reducer {/*** * * 框架在Map处理完成之后&#xff0c;将所有key-value对缓存起来&#xff0c;进行分组&#xff0c;然后传递一个组&#xff0c;调用一次reduce()方法* * 入参key&#xff0c;是一组相同单词kv对的key*/&#64;Overrideprotected void reduce(Text key, Iterable values, Context context)throws IOException, InterruptedException {//做每个单词的结果汇总int sum &#61; 0;for (IntWritable v : values) {sum &#43;&#61; v.get();}//写出最后的结果context.write(key, new IntWritable(sum));}
}

任务2&#xff1a;WordCount Driver 端程序编写

  回顾 MapReduce Driver 端编码规范&#xff1a;整个程序需要一个 Drvier 来进行提交&#xff0c;提交的是一个描述了各种必要信息的 job 对象。

  接下来进入 WordCount Driver 端程序的编写&#xff0c;在 com.hongyaa.mr 包下创建名为 WordCount.java 的类&#xff0c;如下图所示&#xff1a;

Vditor

图3

 

  Driver 端为该 WordCount 程序运行的入口&#xff0c;相当于 YARN 集群&#xff08;分配运算资源&#xff09;的客户端&#xff0c;需要创建一个 Job 类对象来管理 MapReduce 程序运行时需要的相关运行参数&#xff0c;最后将该 Job 类对象提交给 YARN。

  Job对象指定作业执行规范&#xff0c;我们可以用它来控制整个作业的运行。接下来&#xff0c;我们分步讲述作业从提交到执行的整个过程。

  1. 创建 Job

  Job 的创建比较容易&#xff0c;其实就是 new 一个实例&#xff0c;先创建一个配置文件的对象&#xff0c;然后将配置文件对象作为参数&#xff0c;构造一个 Job 对象就可以了。具体代码如下&#xff1a;

// 创建配置文件对象
Configuration conf &#61; new Configuration();
// 新建一个 job 任务
Job job &#61; Job.getInstance(conf);

  2. 打包作业

  我们在 Hadoop 集群上运行这个作业时&#xff0c;要把代码打包成一个Jar文件&#xff0c;只需要在Job对象的setJarByClass()方法中传递一个类即可&#xff0c;Hadoop会利用这个类来查找包含它的Jar文件&#xff0c;进而找到相关的Jar文件。具体代码如下&#xff1a;

// 将 job 所用到的那些类&#xff08;class&#xff09;文件&#xff0c;打成jar包
job.setJarByClass(WordCount.class);

  3. 设置各个环节的函数

  指定我们自定义的 mapper 类和 reducer 类&#xff0c;通过 Job 对象进行设置&#xff0c;将自定义的函数和具体的作业联系起来。具体代码如下&#xff1a;

// 指定 mapper 类和 reducer 类
job.setMapperClass(WordCountMapper.class);
job.setReducerClass(WordCountReducer.class);

  4. 设置输入输出数据类型

  分别指定 MapTask 和 ReduceTask 的输出key-value类型。如果 MapTask 的输出的key-value类型与 ReduceTask 的输出key-value类型一致&#xff0c;则可以只指定ReduceTask 的输出key-value类型。具体代码如下&#xff1a;

// 指定 MapTask 的输出key-value类型&#xff08;可以省略&#xff09;
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);// 指定 ReduceTask 的输出key-value类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);

  5. 设置输入输出文件目录

  在设置输入输出文件目录时&#xff0c;可以选择使用绝对目录&#xff0c;就是直接在语句中写入目录&#xff1b;也可以使用参数输入&#xff0c;即在运行程序时&#xff0c;再在控制台输入目录。具体代码如下&#xff1a;

// 指定该 mapreduce 程序数据的输入和输出路径&#xff0c;此处输入、输出为固定文件目录
Path inPath&#61;new Path("/wordcount/input");
Path outpath&#61;new Path("/wordcount/output");
FileInputFormat.setInputPaths(job,inPath);
FileOutputFormat.setOutputPath(job, outpath);// 此处为参数
FileInputFormat.setInputPaths(job,new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));

  6. 提交并运行作业

  单个任务的提交可以直接使用如下语句&#xff1a;

job.waitForCompletion(true);

  WordCount.java 的完整代码如下所示&#xff1a;

public class WordCount {/*** 该MR程序运行的入口&#xff0c;相当于YARN集群&#xff08;分配运算资源&#xff09;的客户端*/public static void main(String[] args) throws Exception {// &#xff08;1&#xff09;创建配置文件对象Configuration conf &#61; new Configuration();// &#xff08;2&#xff09;新建一个 job 任务Job job &#61; Job.getInstance(conf);// &#xff08;3&#xff09;将 job 所用到的那些类&#xff08;class&#xff09;文件&#xff0c;打成jar包 &#xff08;打成jar包在集群运行必须写&#xff09;job.setJarByClass(WordCount.class);// &#xff08;4&#xff09;指定 mapper 类和 reducer 类job.setMapperClass(WordCountMapper.class);job.setReducerClass(WordCountReducer.class);// &#xff08;5&#xff09;指定 MapTask 的输出key-value类型&#xff08;可以省略&#xff09;job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(IntWritable.class);// &#xff08;6&#xff09;指定 ReduceTask 的输出key-value类型job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);// &#xff08;7&#xff09;指定该 mapreduce 程序数据的输入和输出路径Path inPath&#61;new Path("/wordcount/input");Path outpath&#61;new Path("/wordcount/output");FileSystem fs&#61;FileSystem.get(conf);if(fs.exists(outpath)){fs.delete(outpath,true);}FileInputFormat.setInputPaths(job,inPath);FileOutputFormat.setOutputPath(job, outpath);// &#xff08;8&#xff09;最后给YARN来运行&#xff0c;等着集群运行完成返回反馈信息&#xff0c;客户端退出boolean waitForCompletion &#61; job.waitForCompletion(true);System.exit(waitForCompletion ? 0 : 1);}
}


推荐阅读
  • 本文介绍了如何在 MapReduce 作业中使用 SequenceFileOutputFormat 生成 SequenceFile 文件,并详细解释了 SequenceFile 的结构和用途。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 本文详细介绍了如何利用 Bootstrap Table 实现数据展示与操作,包括数据加载、表格配置及前后端交互等关键步骤。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 2012年9月12日优酷土豆校园招聘笔试题目解析与备考指南
    2012年9月12日,优酷土豆校园招聘笔试题目解析与备考指南。在选择题部分,有一道题目涉及中国人的血型分布情况,具体为A型30%、B型20%、O型40%、AB型10%。若需确保在随机选取的样本中,至少有一人为B型血的概率不低于90%,则需要选取的最少人数是多少?该问题不仅考察了概率统计的基本知识,还要求考生具备一定的逻辑推理能力。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • 如何高效启动大数据应用之旅?
    在前一篇文章中,我探讨了大数据的定义及其与数据挖掘的区别。本文将重点介绍如何高效启动大数据应用项目,涵盖关键步骤和最佳实践,帮助读者快速踏上大数据之旅。 ... [详细]
  • Hadoop 2.6 主要由 HDFS 和 YARN 两大部分组成,其中 YARN 包含了运行在 ResourceManager 的 JVM 中的组件以及在 NodeManager 中运行的部分。本文深入探讨了 Hadoop 2.6 日志文件的解析方法,并详细介绍了 MapReduce 日志管理的最佳实践,旨在帮助用户更好地理解和优化日志处理流程,提高系统运维效率。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • publicclassBindActionextendsActionSupport{privateStringproString;privateStringcitString; ... [详细]
  • 问题场景用Java进行web开发过程当中,当遇到很多很多个字段的实体时,最苦恼的莫过于编辑字段的查看和修改界面,发现2个页面存在很多重复信息,能不能写一遍?有没有轮子用都不如自己造。解决方式笔者根据自 ... [详细]
author-avatar
易秀胜_444
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有