WordCount示例深度学习MapReduce过程(1)

我们都安装完Hadoop之后,按照一些案例先要跑一个WourdCount程序,来测试Hadoop安装是否成功。在终端中用命令创建一个文件夹,简单的向两个文件中各写入一段话,然后运行Hadoop,WourdCount自带WourdCount程序指令,就可以输出写入的那句话各个不同单词的个数。但是这不是这篇博客主要讲的内容,主要是想通过一个简单的Wordcount程序,来认识Hadoop的内部机制。并通过此来深入了解MapReduce的详细过程。在Thinking in BigDate(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解中我们已经很大概梳理一下,Hadoop内部集群架构,并对MapReduce也有初步的了解,这里我们以WourdCount程序来深入的探讨MapReduce的过程。

利用命令行,测试WourdCount程序:

WourdCount程序就是统计文本中字母的个数

1、创建Wordcount示例文件

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

[email protected]:~/software$ mkdir input

[email protected]:~/software$ cd input/

[email protected]:~/software/input$ echo "I am zhangzhen">test1.txt

[email protected]:~/software/input$ echo "You are not zhangzhen">test2.txt

[email protected]:~/software/input$ cd ../hadoop-1.2.1/

[email protected]:~/software/hadoop-1.2.1$ cd bin

[email protected]:~/software/hadoop-1.2.1/bin$ ls

hadoop             slaves.sh                  start-mapred.sh           stop-mapred.sh

hadoop-config.sh   start-all.sh               stop-all.sh               task-controller

hadoop-daemon.sh   start-balancer.sh          stop-balancer.sh

hadoop-daemons.sh  start-dfs.sh               stop-dfs.sh

rcc                start-jobhistoryserver.sh  stop-jobhistoryserver.sh

[email protected]:~/software/hadoop-1.2.1/bin$ jps(确定Hadoop已经起来了)

7101 SecondaryNameNode

7193 JobTracker

7397 TaskTracker

9573 Jps

6871 DataNode

6667 NameNode

[email protected]:~/software/hadoop-1.2.1/bin$ cd ..

[email protected]:~/software/hadoop-1.2.1$ ls

bin          data                       hadoop-minicluster-1.2.1.jar  libexec      share

build.xml    docs                       hadoop-test-1.2.1.jar         LICENSE.txt  src

c++          hadoop-ant-1.2.1.jar       hadoop-tools-1.2.1.jar        logs         webapps

CHANGES.txt  hadoop-client-1.2.1.jar    ivy                           NOTICE.txt

conf         hadoop-core-1.2.1.jar      ivy.xml                       README.txt

contrib      hadoop-examples-1.2.1.jar  lib                           sbin

[email protected]:~/software/hadoop-1.2.1$ bin/hadoop dfs -put ../input in  //把文件上传的hdfa中的in目录中,其实这个说法有误

[email protected]:~/software/hadoop-1.2.1$ bin/hadoop dfs -ls .in/*

ls: Cannot access .in/*: No such file or directory.

[email protected]:~/software/hadoop-1.2.1$ bin/hadoop dfs -ls ./in/*

-rw-r--r--   1 zhangzhen supergroup         15 2014-03-22 10:45 /user/zhangzhen/in/test1.txt

-rw-r--r--   1 zhangzhen supergroup         22 2014-03-22 10:45 /user/zhangzhen/in/test2.txt

注意:Hadoop中是没有当前目录这个概念的。所以上传到hdfs中的文件,我们是不能通过cd命令、ls命令,查看目录中的文件。这里我们通过就是上面和下面命令查看hdfs中文件的方法。

在每个版本中,hadoop-examples-1.2.1.jar的位置不一样,在Hadoop1.2.1版本中,我们hadoop-examples-1.2.1.jar文件是在Hadoop目录中的,这里我们需要把这个hadoop-examples-1.2.1.jar拷贝到/bin 目录中。

执行:利用hadoop-examples-1.2.1.jar执行bin目录下in目录中的文件,并把结果写入到 put 的文件夹。

?


1

[email protected]:~/software$ bin/hadoop jar hadoop-examples-1.2.1.jar wordcount in put

查看输出的结果:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

[email protected]:~/software/hadoop-1.2.1$ bin/hadoop dfs -ls

Found 2 items

drwxr-xr-x   - zhangzhen supergroup          0 2014-03-22 10:45 /user/zhangzhen/in

drwxr-xr-x   - zhangzhen supergroup          0 2014-03-22 10:56 /user/zhangzhen/put

[email protected]:~/software/hadoop-1.2.1$ bin/hadoop dfs -ls ./put

Found 3 items

-rw-r--r--   1 zhangzhen supergroup          0 2014-03-22 10:56 /user/zhangzhen/put/_SUCCESS

drwxr-xr-x   - zhangzhen supergroup          0 2014-03-22 10:56 /user/zhangzhen/put/_logs  目录

-rw-r--r--   1 zhangzhen supergroup         39 2014-03-22 10:56 /user/zhangzhen/put/part-r-00000   这是文件

[email protected]:~/software/hadoop-1.2.1/hadoop dfs -cat ./put/*

I      1

You    1

am     1

are    1

not    1

zhangzhen    2

cat: File does not exist: /user/zhangzhen/put/_logs

[email protected]:~/software/hadoop-1.2.1$

上面的结果,就基本可以证明Hadoop搭建是没有问题的。执行hadoop-examples-1.2.1.jar程序,其实是把java程序编译打成一个jar文件,然后直接运行,就可以得到结果。其实这也是以后我们运行java程序的一个方法。把程序编译打包上传,然后运行。还有另一种方面,eclipse连接Hadoop,可以联机测试。两种方法各有优点,不再详述。

运行的程序,我们可以在Hadoop的安装目录中找到源文件,WourdCount.java源代码。

?


1

2

3

[email protected]:~/software/hadoop-1.2.1/src/examples/org/apache/hadoop/examples$ pwd

/home/zhangzhen/software/hadoop-1.2.1/src/examples/org/apache/hadoop/examples

[email protected]:~/software/hadoop-1.2.1/src/examples/org/apache/hadoop/examples$

下面是把源代码拷到eclipse程序中,利用此代码(并未修改)测试一下实际的数据并得到结果。(注释是对上以一行的解释)

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

import java.io.IOException; 

import java.util.StringTokenizer; 

  

import org.apache.hadoop.conf.Configuration; 

import org.apache.hadoop.fs.Path; 

import org.apache.hadoop.io.IntWritable; 

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.util.GenericOptionsParser; 

  

public class Wordcount { 

  

  public static class TokenizerMapper  

       extends Mapper<Object, Text, Text, IntWritable>{

//规定map中用到的数据类型,这里的Text相当于jdk中的String IntWritable相当于jdk的int类型,

//这样做的原因主要是为了hadoop的数据序化而做的。

      

    private final static IntWritable one = new IntWritable(1);

//声时一个IntWritable变量,作计数用,每出现一个key,给其一个value=1的值 

    private Text word = new Text();//用来暂存map输出中的key值,Text类型的 

        

    public void map(Object key, Text value, Context context 

                    ) throws IOException, InterruptedException {

//这就是map函数,它是和Mapper抽象类中的相对应的,此处的Object key,Text value的类型和上边的Object,

//Text是相对应的,而且最好一样,不然的话,多数情况运行时会报错。

      StringTokenizer itr = new StringTokenizer(value.toString());

//Hadoop读入的value是以行为单位的,其key为该行所对应的行号,因为我们要计算每个单词的数目,

//默认以空格作为间隔,故用StringTokenizer辅助做字符串的拆分,也可以用string.split("")来作。

      while (itr.hasMoreTokens()) { //遍历一下每行字符串中的单词

        word.set(itr.nextToken());  //出现一个单词就给它设成一个key并将其值设为1

        context.write(word, one);   //输出设成的key/value值

//上面就是map打散的过程

      

    

  

    

  public static class IntSumReducer  

       extends Reducer<Text,IntWritable,Text,IntWritable> {

//reduce的静态类,这里和Map中的作用是一样的,设定输入/输出的值的类型

    private IntWritable result = new IntWritable(); 

  

    public void reduce(Text key, Iterable<IntWritable> values,  

                       Context context 

                       ) throws IOException, InterruptedException { 

      int sum = 0; 

      for (IntWritable val : values) {

 //由于map的打散,这里会得到如,{key,values}={"hello",{1,1,....}},这样的集合

        sum += val.get();              

//这里需要逐一将它们的value取出来予以相加,取得总的出现次数,即为汇和

      

      result.set(sum);                  //将values的和取得,并设成result对应的值

      context.write(key, result);

//此时的key即为map打散之后输出的key,没有变化,变化的时result,以前得到的是一个数字的集合,

//已经给算出和了,并做为key/value输出。 

    

  

  

  public static void main(String[] args) throws Exception { 

    Configuration conf = new Configuration();  //取得系统的参数

    String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); 

    if (otherArgs.length != 2) {              

 //判断一下命令行输入路径/输出路径是否齐全,即是否为两个参数

      System.err.println("Usage: wordcount <in> <out>"); 

      System.exit(2);                           //若非两个参数,即退出

    

    Job job = new Job(conf, "word count");     

//此程序的执行,在hadoop看来是一个Job,故进行初始化job操作

    job.setJarByClass(Wordcount.class);       

 //可以认为成,此程序要执行MyWordCount.class这个字节码文件

    job.setMapperClass(TokenizerMapper.class);

//在这个job中,我用TokenizerMapper这个类的map函数

    job.setCombinerClass(IntSumReducer.class); 

    job.setReducerClass(IntSumReducer.class);  

//在这个job中,我用IntSumReducer这个类的reduce函数

    job.setOutputKeyClass(Text.class);         

//在reduce的输出时,key的输出类型为Text

    job.setOutputValueClass(IntWritable.class); 

//在reduce的输出时,value的输出类型为IntWritable

    FileInputFormat.addInputPath(job, new Path(otherArgs[0])); 

//初始化要计算word的文件的路径

    FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

//初始化要计算word的文件的之后的结果的输出路径

    System.exit(job.waitForCompletion(true) ? 0 : 1);

 //提交job到hadoop上去执行了,意思是指如果这个job真正的执行完了则主函数退出了,若没有真正的执行完就退出了。 

  }

//参考:http://hi.baidu.com/erliang20088/item/ce550f2f088ff1ce0e37f930

}

WourdCount程序中隐藏的秘密

1、具体流程:

1)文件拆分成splits,由于测试用的文件较小,所以每个文件为一个split,并将文件按行分割形成<key,value> 对,如下图。这一步由MapReduce框架自动完成,其中偏移量(即key值)包括了回车所占的字符数和Linux环境有关。

2)将分割好的<key,value>对交给用户定义的map方法进行处理,生成新的<key,value>对。

3)得到map方法输出的<key,value>对后,Mapper会将它们按照key值进行排序,并执行Combine过程,将key至相同value值累加,得到Mapper的最终输出结果。

2、Map Task的整体流程:

可以概括为5个步骤:

1)Read:Map Task通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value。

2)Map:该阶段主要将解析出的key/value交给用户编写的map()函数处理,并产生一系列的key/value。

3)Collect:在用户编写的map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输入结果。在该函数内部,它会将生成的key/value分片(通过Partitioner),并写入一个环形内存缓冲区中。

4)Spill:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件。将数据写入本地磁盘之前,先要对数据进行一次本地排序,并在必要时对数据进行合并,压缩等操作。

5)Combine:当所有数据处理完成后,Map Task对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。

3、Reduce的整体流程:

可以概括为5个步骤:

1)Shuffle:也称Copy阶段。Reduce Task从各个Map Task上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阀值,则写到磁盘上,否则直接放到内存中。

2)Merge:在远程拷贝的同时,Reduce Task启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或者磁盘上文件过多。

3)Sort:按照MapReduce语义,用户编写的reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一 起,Hadoop采用了基于排序的策略。由于各个Map Task已经实现了对自己的处理结果进行了局部排序,因此,Reduce Task只需对所有数据进行一次归并排序即可。

4)Reduce:在该阶段中,Reduce Task将每组数据依次交给用户编写的reduce()函数处理。

5)Write:reduce()函数将计算结果写到HDFS。

通过一些博客对WourdCount的介绍示例,总结Map、Reduce的整个过程。加上Thinking in BigDate(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解所将的内容,大致把整个文件数据处理的过程梳理一遍。但是还有很多细节没有讲明。如:Spill、Combine、Shuffle的过程,Shuffle整个MapReduce的核心。接下来,我们更深入了解MapReduce的过程,更深入的了解,便于我们在以后在操作Hadoop集群的过程中,有利于系统调优,甚至修改Hadoop源代码。

时间: 2024-10-20 10:31:02

WordCount示例深度学习MapReduce过程(1)的相关文章

WordCount示例深度学习MapReduce过程

转自: http://blog.csdn.net/yczws1/article/details/21794873 . 我们都安装完Hadoop之后,按照一些案例先要跑一个WourdCount程序,来测试Hadoop安装是否成功.在终端中用命令创建一个文件夹,简单的向两个文件中各写入一段话,然后运行Hadoop,WourdCount自带WourdCount程序指令,就可以输出写入的那句话各个不同单词的个数.但是这不是这篇博客主要讲的内容,主要是想通过一个简单的Wordcount程序,来认识Hado

免费的中文深度学习全书:《深度学习理论与实战:提高篇》

在线阅读:深度学习理论与实战:提高篇 序言 16年9月的时候我在CSDN发了一些深度学习的文章,主要是面向没有太多经验的开发者.达文读了后觉得我的文章比较通俗易懂,邀请我写一本书,当时头脑一热就答应下来.虽然现在出版的书籍汗牛充栋,但是对我来说著书立言始终是一件非常严肃和重大的事情.立德.立功.立言乃儒家的三不朽,可见古人对于其重视.我的这本书只是关于深度学习的技术类书籍,远远谈不上立言,但是总归会有一些读者的,因此我希望这本书至少对读者有一些帮助,而不是误人子弟.从开始写下第一个字到现在,前后

[转]深度学习之浅见

通常来说,大家认为深度学习的观点是Geoffrey Hinton在2006年提出的.这一算法提出之后,得到了迅速的发展.关于深度学习,zouxy09的专栏中有详细的介绍,Free Mind 的博文也很值得一读.本博文是我对深度学习的一点看法,主要内容在第4.5部分,不当之处还请指教. 1.深度学习 深度学习,即Deep Learning,是一种学习算法(Learning algorithm).学习算法这个很好理解,那么Deep指的是什么呢?这里的Deep是针对算法的结构而言的. 譬如,SVMs及

DeepMind背后的人工智能:深度学习原理初探

去年11月,一篇名为<Playing Atari with Deep Reinforcement Learning>的文章被初创人工智能公司DeepMind的员工上传到了arXiv网站.两个月之后,谷歌花了500万欧元买下了DeepMind公司,而人们对这个公司的了解仅限于这篇文章.近日,Tartu大学计算机科学系计算神经学小组的学者在robohub网站发表文章,阐述了他们对DeepMind人工智能算法的复现. 在arXiv发表的原始论文中,描述了一个单个的网络,它能够自我学习从而自动的玩一些

深度学习卷积神经网络大事件一览

深度学习(DeepLearning)尤其是卷积神经网络(CNN)作为近几年来模式识别中的研究重点,受到人们越来越多的关注,相关的参考文献也是层出不穷,连续几年都占据了CVPR的半壁江山,但是万变不离其宗,那些在深度学习发展过程中起到至关重要的推动作用的经典文献依然值得回味,这里依据时间线索,对CNN发展过程中出现的一些经典文献稍作总结,方便大家在研究CNN时追本溯源,在汲取最新成果的同时不忘经典. 首先这里给出CNN在发展过程中的一些具有里程碑意义的事件和文献: 对于CNN最早可以追溯到1986

深度学习之浅见

通常来说,大家认为深度学习的观点是Geoffrey Hinton在2006年提出的.这一算法提出之后,得到了迅速的发展.关于深度学习,zouxy09的专栏中有详细的介绍,Free Mind 的博文也很值得一读.本博文是我对深度学习的一点看法,主要内容在第4.5部分,不当之处还请指教. 1.深度学习 深度学习,即Deep Learning,是一种学习算法(Learning algorithm).学习算法这个很好理解,那么Deep指的是什么呢?这里的Deep是针对算法的结构而言的. 譬如,SVMs及

AI在汽车中的应用:实用深度学习

https://mp.weixin.qq.com/s/NIza8E5clC18eMF_4GMwDw 深度学习的"深度"层面源于输入层和输出层之间实现的隐含层数目,隐含层利用数学方法处理(筛选/卷积)各层之间的数据,从而得出最终结果.在视觉系统中,深度(vs.宽度)网络倾向于利用已识别的特征,通过构建更深的网络最终来实现更通用的识别.这些多层的优点是各种抽象层次的学习特征. 在未来的某个时候,人们必定能够相对自如地运用人工智能,安全地驾车出行.这个时刻何时到来我无法预见:但我相信,彼时&

深入浅出计算机组成原理:GPU(下)-为什么深度学习需要使用GPU?(第31讲)

一.引子 上一讲,我带你一起看了三维图形在计算机里的渲染过程.这个渲染过程,分成了顶点处理.图元处理.栅格化.片段处理,以及最后的像素操作.这一连串的过程, 也被称之为图形流水线或者渲染管线. 因为要实时计算渲染的像素特别地多,图形加速卡登上了历史的舞台.通过3dFx的Voodoo或者NVidia的TNT这样的图形加速卡,CPU就不需要再去处理一个个像素点的图元处理.栅格化和片段处理这些操作.而3D游戏也是从这个时代发展起来的. 你可以看这张图,这是“古墓丽影”游戏的多边形建模的变化.这个变化,

【Big Data - Hadoop - MapReduce】初学Hadoop之图解MapReduce与WordCount示例分析

Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算. HDFS是Google File System(GFS)的开源实现. MapReduce是Google MapReduce的开源实现. HDFS和MapReduce实现是完全分离的,并不是没有HDFS就不能MapReduce运算. 本文主要参考了以下三篇博客学习整理而成. 1. Hadoop示例程序WordCount详解及实例 2. hadoop 学习笔