** Hadoop框架基础(三)

上一节我们使用eclipse运行展示了hdfs系统中的某个文件数据,这一节我们简析一下离线计算框架MapReduce,以及通过eclipse来编写关于MapReduce的代码,在Hadoop第一小节内容中,我们成功运行了官方的WordCount的案例,这一节我们自己编写代码走一下这个流程。

本节目标:

* 了解mapreduce原理

* 编写wordcount的mapreduce案例

** MapReduce简述及架构

 
 

上图简单的阐明了map和reduce的两个过程或者作用,虽然不够严谨,但是足以提供一个大概的认知,map过程是一个蔬菜到制成食物前的准备工作,reduce将准备好的材料合并进而制作出食物的过程,举个例子(方案3可以对比蔬菜这个图片做一个简单理解):

任务:我想检索全国的身份证信息,将姓名重复最多的名字统计出来。

想要完成这个任务,我们想一下方案

方案1:将全国的身份信息先搜集到某个文件中(比如搜集到“身份信息.txt”文件中),然后写一个程序,遍历该文件所有的名字,统计出名字出现最多的那个,并输出出来。

方案2:多线程,并发同时遍历处理该文件,但前提是:该计算机是物理多核CPU;而且还要手动分割文件,不然会出现内容重复统计,再者还要手动合并结果,做数据同步,效率比1高,但是代码逻辑比1麻烦的多。

方案3:我还是使用“方案1”的代码,把“方案1”的代码部署到多台计算机上,每台计算机遍历身份信息文件的一部分,统计出结果后,所有计算机做一个合并就OK了,但问题是,如何切分文件给所有的计算机,怎么切分合理,所有计算机的结果合并谁来处理,怎么合并。

其实mapreduce过程就是方案3。我们要学习的,也就是别人制定好的方案,并研究其合理性。

** MapReduce代码编写

目标:计算words.txt文档中的所有单词出现的次数,单词如图:

 
 

代码组成部分:

* map

如下图,首先创建WordCountMapper类,继承自org.apache.hadoop.mapreduce.Mapper类,然后复写其map方法,这个map方法会在整个框架需要进行map运算时自动调用的。map方法中,需要做的操作是将单词和出现次数放入map映射,比如这个例子,map过程结束后,出现的结果是:

<one, 1>  <two, 1>  <hadoop, 1>  <element, 1>  <dog, 1>  <cat, 1>  <go, 1>  <for, 1>  <cat, 1>  <nick, 1>  <hello, 1>  <two, 1>

这里需要注意的是:

1、单词作为键

2、单词不管出现了几次,该键所对应的值都为1

3、map方法的参数,key为当前单词,value为分配给当前map任务的整个文本内容,所以后边要做一个split分割,后边的正则表达式的意思为:单词按照任意空白字符分割。

 
 

* reduce

如下图,首先创建WordCountReduce类,继承自org.apache.hadoop.mapreduce.Reducer类,然后覆写其reduce方法,这个reduce方法会在整个框架需要进行reduce运算时自动调用的。reduce方法中,需要做的操作是将map映射好的单词做合并处理(在shuffle过程讲解前,只能这样不太严谨的表述),reduce方法的key参数是当前传入到reduce方法中的单词,比如:cat这个单词,接着values参数,是这个cat单词所对应的映射,此例子为两个1。reduce过程,是将如下数据进行合并运算:

<one, [1]>

<two, [1, 1]>

<hadoop, [1]>

<element, [1]>

<dog, [1]>

<cat, [1, 1]>

<go, [1]>

<for, [1]>

<nick, [1]>

<hello, [1]>

那么对于cat这个单词来讲,reduce中的key参数就代表cat,values参数就代表[1, 1],如此便可统计合并。最后出来的结果,比如cat这个单词,那么就是<cat, 2>

可能的疑惑:

1、map过程产生的<cat, 1>和<cat, 1>是怎么变成<cat, [1, 1]>从而传递给reduce的?

2、如果我这个words.txt文件有10T这么大,那么按照HDFS存储分割成好多个128M分布存储在各个主机,那到底是怎么来协调的。

如上两个问题需要涉及到map和reduce的之间的一些细节,即shuffle过程(后续在说)。

 
 

* job

编写完map和reduce代码后,最后需要创建一个任务来执行mapreduce运算,如下图,首先创建一个App类,继承自Configured并实现Tool接口,这里会让你覆写run方法。在run方法中,我们需要做的是:

1、创建配置实例Configuration

2、创建Job任务并设置Job任务所在类为App.class

3、为当前Job设置数据输入路径inPath

4、为当前Job设置map运算所在的那个类为WordCountMapper.class,设置map任务输出的结果类型,<cat, 1>这个类型当然是Text.class和LongWritable.class了

5、设置Job的reduce运算所在类,为WordCountReducer.class,设置reducer输出结果<cat, 2>的类型分别为Text.class和LongWritable.class。

6、设置Job任务的输出目录outPath

7、如果Job任务成功执行完毕,则返回0,否则返回1。

8、调用时,将输入目录和输出目录传入到args参数中,此时我直接默认:

args = new String[]{"/input/words/words.txt", "/output/"};

最后通过如下两行代码,执行任务并退出系统。

int status = ToolRunner.run(app.getConf(), app, args);

System.exit(status);

 
 

其中的deleteFileInHDFS方法为之前自定义的Tools类中的方法,方法可以在HDFS系统中删除传入的目录,在这个例子里,每次执行都删除之前创建出来的output目录,原因在于在执行某个job任务前,输出目录不能为已经存在的目录,所以要么手动删除之前的目录,要么手动指定新目录。在此为了方便我选择了前者(因为对于本例来讲,之前那些输出数据不需要了)。

 
 

接着就可以运行该案例了,注意运行时,要先开启hdfs和yarn的相关服务,运行完成后,通过查看output目录的结果如图:

 
 

以上便完成了mapreduce关于wordcount单词统计的编码和运行。接下来,我们回忆一下之前使用官方examples.jar运行的单词统计任务,使用的命令是:

$ bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount /input/ /output/

那么我们也想使用类似的方式把自己的代码打成jar包之后调用,怎么玩呢。首先,既然是想手动传入输入数据和输出目录,那么就先把如下代码注释掉:

 
 

接着,我们开始打包程序:

1、在Eclipse中,依次点击:File -- Export -- Java -- JAR file -- Next

2、出现如下界面,这里我把JAR的输出目录改为:/home/z/Desktop/MyWordCount.jar,同时注意选择你要打包的源码,即src/main/java

 
 

3、下一步,再下一步,出现如下界面,注意红框部分,这里我们选择一个jar包的入口类,如果不选择,那么我们执行jar包时,还需要手动输入哪个类为入口类,最后Finish。(如果你的红框内容被遮挡住了,先Cancel下,然后全屏你的虚拟机系统,再次来到这个界面就能看到了)

 
 

4、桌面生成了一个Jar文件则成功。接下来我们通过这个jar来运行一下,输入指令:

$ bin/yarn jar /home/z/Desktop/MyWordCount.jar /input/words/words.txt /output/,如图所示,开始运行任务:

 
 

最后查看该任务结果:

 
 

成功运行!

** 最后我们对比两条命令

运行官方jar:$ bin/yarn jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.5.0.jar wordcount /input/ /output/

运行自己jar:$ bin/yarn jar /home/z/Desktop/MyWordCount.jar /input/words/words.txt /output/

* 运行官方的jar时,除了指定某个位置的jar包运行在yarn平台上之外,还提供了wordcount任务名称,而我们自己写的没有,是因为我们封装的jar就一个单词统计任务,而且在封装jar时指定了主类。

* 运行官方提供的jar中的wordcount任务,提供的数据输入目录为/input/并没有指定哪个具体文件,是因为官方的demo中编写了自动遍历指定目录中所有可用的统计资源,而我们的代码中没有写这样的功能,所以请直接指定文件的绝对路径。

** 总结

本节需要大概了解mapreduce的运行原理,并成功使用eclipse编写mapreduce的单词统计任务,使之成功运行。最后完成jar包封装并成功调用。


个人微博:http://weibo.com/seal13

QQ大数据技术交流群(广告勿入):476966007


作者:Z尽际
链接:https://www.jianshu.com/p/87209aba4465
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Hadoop框架基础(三)的更多相关文章

  1. Hadoop框架基础(五)

    ** Hadoop框架基础(五) 已经部署了Hadoop的完全分布式集群,我们知道NameNode节点的正常运行对于整个HDFS系统来说非常重要,如果NameNode宕掉了,那么整个HDFS就要整段垮 ...

  2. Hadoop 框架基础(四)

    ** Hadoop 框架基础(四) 上一节虽然大概了解了一下 mapreduce,徒手抓了海胆,不对,徒手写了 mapreduce 代码,也运行了出来.但是没有做更深入的理解和探讨. 那么…… 本节目 ...

  3. Hadoop框架基础(二)

    ** Hadoop框架基础(二) 上一节我们讨论了如何对hadoop进行基础配置已经运行一个简单的实例,接下来我们尝试使用eclipse开发. ** maven安装 简单介绍:maven是一个项目管理 ...

  4. Hadoop框架基础(一)

    ** Hadoop框架基础(一)     学习一个新的东西,传统而言呢,总喜欢漫无目的的扯来扯去,比如扯扯发展史,扯扯作者是谁,而我认为这些东西对于刚开始接触,并以开发为目的学者是没有什么帮助的,反而 ...

  5. 集合框架基础三——Map

    Map接口  * 将键映射到值的对象  * 一个映射不能包含重复的键  * 每个键最多只能映射到一个值 Map接口和Collection接口的不同 * Map是双列的,Collection是单列的 * ...

  6. HBase框架基础(三)

    * HBase框架基础(三) 本节我们继续讨论HBase的一些开发常识,以及HBase与其他框架协调使用的方式.在开始之前,为了框架之间更好的适配,以及复习之前HBase的配置操作,请使用cdh版本的 ...

  7. 框架基础:关于ajax设计方案(三)---集成ajax上传技术

    之前发布了ajax的通用解决方案,核心的ajax发布请求,以及集成了轮询.这次去外国网站逛逛,然后发现了ajax level2的上传文件,所以就有了把ajax的上传文件集成进去的想法,ajax方案的l ...

  8. django 基础框架学习 (三)

    Django框架基础-03数据库新增数据    1.save⽅法        >>> from datetime import date        >>> f ...

  9. hadoop框架详解

    Hadoop框架详解 Hadoop项目主要包括以下四个模块 ◆ Hadoop Common: 为其他Hadoop模块提供基础设施 ◆ Hadoop HDFS: 一个高可靠.高吞吐量的分布式文件系统 ◆ ...

随机推荐

  1. 【动态树问题】LCT学习笔记

    我居然还不会LCT QAQ真是太弱了 必须学LCT QAQ ------------------线割分是我www------------ LinkCut-Tree是基于Splay(由于Splay能够非 ...

  2. Revolution Platform

    Revolution Platform 黑暗的极权统治现实 异类的处境 独孤的存在 觉者的形成 信仰的确立 信仰的产物 完整的思想理论 反抗与信仰的一致 反抗的超理性的智慧论 反抗的纯理性的方法论 反 ...

  3. Android自己定义组件系列【4】——自己定义ViewGroup实现双側滑动

    在上一篇文章<Android自己定义组件系列[3]--自己定义ViewGroup实现側滑>中实现了仿Facebook和人人网的側滑效果,这一篇我们将接着上一篇来实现双面滑动的效果. 1.布 ...

  4. PHP第八课 字符串拆分经常使用函数

    课程概要: 通过这节课可以对字符串进行主要的操作. 字符串知识点: 1.字符串的处理介绍 2.经常使用的字符串输出函数 3.经常使用的字符串格式化函数 4.字符串比較函数 5.正則表達式在字符串中的应 ...

  5. jdbc14 及 jdbc16 共存所带来的问题【未完待续】

    在JAVA中JDK版本号与JDBC版本号的一致性十分重要,开发都们经常会忽略了这一点导致非常多不必要的错误. 昨天给客户排查了一个关于EDB在JBoss中使用时关于这方面的问题,希望给大家一点启示. ...

  6. iOS-MBProgressHUD使用

    在码代码过程中,我们经常用到MBProgressHUD,但我很少实例化使用,一般都是偷个懒直接显示隐藏,这里贴上详解,以便日后有样式要求时使用. 1,MBProgressHUD常用属性和用法Demo ...

  7. nyoj--37--回文字符串(动态规划)

    回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然, ...

  8. 【linux】——centos 分辨率配置

    用过centos的朋友肯定知道centos在默认安装的时候显示器的分辨率只有800*600,但是我们想把改成1024*768或者更大,怎么办呢,我也是试过了才知道,首先打开系统-管理-显示-硬件-显示 ...

  9. spm总体说明

    目录 1.如何工作 2.何时使用 1.如何工作 sql plan baseline 是一个关联sql 语句的对象,设计会影响查询优化器生成执行计划,更具体的说,一个sql baseline包含其中的一 ...

  10. 14:Challenge 7(map大法好)

    总时间限制:  10000ms 单个测试点时间限制:  1000ms 内存限制:  262144kB 描述 给一个长为N的数列,有M次操作,每次操作是以下两种之一: (1)修改数列中的一个数 (2)求 ...