1. 程式人生 > >hadoop學習(六)WordCount示例深度學習MapReduce過程(1)

hadoop學習(六)WordCount示例深度學習MapReduce過程(1)

        花了整整一個下午(6個多小時),整理總結,也算是對這方面有一個深度的瞭解。日後可以回頭多看看。

        我們都安裝完Hadoop之後,按照一些案例先要跑一個WourdCount程式,來測試Hadoop安裝是否成功。在終端中用命令建立一個資料夾,簡單的向兩個檔案中各寫入一段話,然後執行Hadoop,WourdCount自帶WourdCount程式指令,就可以輸出寫入的那句話各個不同單詞的個數。但是這不是這篇部落格主要講的內容,主要是想通過一個簡單的Wordcount程式,來認識Hadoop的內部機制。並通過此來深入瞭解MapReduce的詳細過程。在中我們已經很大概梳理一下,Hadoop內部叢集架構,並對MapReduce也有初步的瞭解,這裡我們以WourdCount程式來深入的探討MapReduce的過程。

利用命令列,測試WourdCount程式:

WourdCount程式就是統計文字中字母的個數

1、建立Wordcount示例檔案


[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.shhadoop-config.sh start-all.sh stop-all.sh task-controllerhadoop-daemon.sh start-balancer.sh stop-balancer.shhadoop-daemons.sh start-dfs.sh stop-dfs.shrcc 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 sharebuild.xml docs hadoop-test-1.2.1.jar LICENSE.txt srcc++ hadoop-ant-1.2.1.jar hadoop-tools-1.2.1.jar logs webappsCHANGES.txt hadoop-client-1.2.1.jar ivy NOTICE.txtconf hadoop-core-1.2.1.jar ivy.xml README.txtcontrib 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 的資料夾。

<span style="font-family:Times New Roman;">
[email protected]:~/software$ bin/hadoop jar hadoop-examples-1.2.1.jar wordcount in put

</span>

檢視輸出的結果

<span style="font-family:Times New Roman;">
[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$ 

</span>

         上面的結果,就基本可以證明Hadoop搭建是沒有問題的。執行hadoop-examples-1.2.1.jar程式,其實是把java程式編譯打成一個jar檔案,然後直接執行,就可以得到結果。其實這也是以後我們執行java程式的一個方法。把程式編譯打包上傳,然後執行。還有另一種方面,eclipse連線Hadoop,可以聯機測試。兩種方法各有優點,不再詳述。

執行的程式,我們可以在Hadoop的安裝目錄中找到原始檔,WourdCount.java原始碼。

<span style="font-family:Times New Roman;">
[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$ 

</span>

      下面是把原始碼拷到eclipse程式中,利用此程式碼(並未修改)測試一下實際的資料並得到結果。(註釋是對上以一行的解釋

<span style="font-family:Times New Roman;">
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
}

</span>

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的整個過程。加上所將的內容,大致把整個檔案資料處理的過程梳理一遍。但是還有很多細節沒有講明。如:Spill、Combine、Shuffle的過程,Shuffle整個MapReduce的核心。接下來,我們更深入瞭解MapReduce的過程,更深入的瞭解,便於我們在以後在操作Hadoop叢集的過程中,有利於系統調優,甚至修改Hadoop原始碼。

Copyright©BUAA

相關推薦

hadoop學習WordCount示例深度學習MapReduce過程1

        花了整整一個下午(6個多小時),整理總結,也算是對這方面有一個深度的瞭解。日後可以回頭多看看。         我們都安裝完Hadoop之後,按照一些案例先要跑一個WourdCount程式,來測試Hadoop安裝是否成功。在終端中用命令建立一個資料夾,簡單的

機器學習深度學習系列連載: 第二部分 深度學習迴圈神經網路 4BiDirectional RNN, Highway network, Grid-LSTM

深度學習(十六)迴圈神經網路 4(BiDirectional RNN, Highway network, Grid-LSTM) RNN處理時間序列資料的時候,不僅可以正序,也可以正序+逆序(雙向)。下面顯示的RNN模型,不僅僅是simple RNN,可以是LSTM,或者GRU 1 B

機器學習深度學習系列連載: 第二部分 深度學習深度學習技巧3Deep learning tips- Early stopping and Regularization

深度學習技巧3( Early stopping and Regularization) 本節我們一起探討 Early stopping and Regularization,這兩個技巧不是深度學習特有的方法,是機器學習通用的方法。 1. Early stopp

Storm入門WordCount示例

etl rri emit lis auto deb turn output -- Storm API文檔網址如下: http://storm.apache.org/releases/current/javadocs/index.html 一、關聯代碼 使用maven,代碼如

TensorFlow筆記7-----實戰Google深度學習框架----隊列與多線程

一起 width nbsp stop 之前 圖片 第一個 queue enqueue 一、創建一個隊列: FIFOQueue:先進先出 RandomShuffleQueue:會將隊列中的元素打亂,每次出列操作得到的是從當前隊列所有元素中隨機選擇的一個。 二、操作一個隊列的函

深度學習轉--入門深度學習的一些開源代碼

姿態估計 multi 入門 nat project bic obj algorithm taf 原文作者:aircraft 原文鏈接: 沒錯這篇又是轉發的,因為覺得學習深度學習難免要從別人的代碼開始,所以就轉發了。不過轉發的時候沒找到原作者是誰,所以原作者看到不要

機器學習深度學習系列連載: 第二部分 深度學習十五迴圈神經網路 3Gated RNN - GRU

迴圈神經網路 3(Gated RNN - GRU) LSTM 是1997年就提出來的模型,為了簡化LSTM的複雜度,在2014年 Cho et al. 提出了 Gated Recurrent Units (GRU)。接下來,我們在LSTM的基礎上,介紹一下GRU。 主要思路是: •

機器學習深度學習系列連載: 第二部分 深度學習十四迴圈神經網路 2Gated RNN - LSTM

迴圈神經網路 2(Gated RNN - LSTM ) simple RNN 具有梯度消失或者梯度爆炸的特點,所以,在實際應用中,帶有門限的RNN模型變種(Gated RNN)起著至關重要的作用,下面我們來進行介紹: LSTM (Long Short-term Memory )

機器學習深度學習系列連載: 第二部分 深度學習十三迴圈神經網路 1Recurre Neural Network 基本概念

迴圈神經網路 1(Recurre Neural Network 基本概念 ) 迴圈神經網路的特點: • RNNs 在每個時間點連線引數值,引數只有一份 • 神經網路出了輸入以外,還會建立在以前的“記憶”的基礎上 • 記憶體的要求與輸入的規模有關 當然,他的深度不只有一層:

機器學習深度學習系列連載: 第二部分 深度學習十二卷積神經網路 3 經典的模型LeNet-5,AlexNet ,VGGNet,GoogLeNet,ResNet

卷積神經網路 3 經典的模型 經典的卷積神經網路模型是我們學習CNN的利器,不光是學習原理、架構、而且經典模型的超引數、引數,都是我們做遷移學習最好的源材料之一。 1. LeNet-5 [LeCun et al., 1998] 我們還是從CNN之父,LeCun大神在98年提出的模

機器學習深度學習系列連載: 第二部分 深度學習十一卷積神經網路 2 Why CNN for Image?

卷積神經網路 2 Why CNN 為什麼處理圖片要用CNN? 原因是: 一個神經元無法看到整張圖片 能夠聯絡到小的區域,並且引數更少 圖片壓縮畫素不改變圖片內容 1. CNN 的特點 卷積: 一些卷積核遠遠小於圖片大小; 同樣的pat

機器學習深度學習系列連載: 第二部分 深度學習卷積神經網路 1 Convolutional Neural Networks

卷積神經網路 Convolutional Neural Networks 卷積神經網路其實早在80年代,就被神經網路泰斗Lecun 提出[LeNet-5, LeCun 1980],但是由於當時的資料量、計算力等問題,沒有得到廣泛使用。 卷積神經網路的靈感來自50年代的諾貝爾生物學獎

機器學習深度學習系列連載: 第二部分 深度學習Keras- “hello world” of deep learning

Keras Kearas 是深度學習小白程式碼入門的最佳工具之一。 如果想提升、練習程式碼能力,還是建議演算法徒手python實現。 複雜的深度神經網路專案還是推薦TensorFlow或者Pytorch Keras是一個高層神經網路API,Keras由純Pyt

【蜂口 | AI人工智慧】人臉檢測——龍鵬 深度學習與人臉影象應用連載

我們接著上一節的分享,繼續分享人臉檢測的下半部分。這次的分享主要是深度學習相關的。我們會主要講述當前深度學習在人臉檢測這個領域的發展水平。主要從以下幾個方向進行分享: 首先,我們會講講當前主流的基於深度學習的一個人臉檢測的框架,包括兩個框架,一個是級聯CNN框架

深度學習】線性迴歸使用MXNet深度學習框架實現線性迴歸

文章目錄 概述 程式碼 概述 這篇文章使用MXNet深度學習框架中的Gluon包實現小批量隨機梯度下降的線性迴歸問題。可以參考我的上一篇文章【深度學習】線性迴歸(二)小批量隨機梯度下降及其python實現。 主要包

機器學習深度學習系列連載: 第二部分 深度學習深度學習技巧4Deep learning tips- Dropout

深度學習技巧4( Dropout) Dropout 在2012年imagenet 比賽中大放異彩,是當時CNN模型奪冠的功勳環節之一。 那什麼是Dropout 我們先直觀的理解: 練武功的時候,訓練的時候腳上綁上重物 等到練成下山的時候: 我們從幾個方面來解

機器學習深度學習系列連載: 第二部分 深度學習可以自己學習的啟用函式Maxout

可以自己學習的啟用函式(Maxout) 在深度學習中啟用函式有sigma, tanh, relu,還有以後會將到的selu,但是有沒有一個啟用函式不是人為設定的,是機器學出來的呢?對抗網路(GAN)之父Goodfellow,給我們一個肯定的答案。Learnabl

機器學習深度學習系列連載: 第二部分 深度學習十四迴圈神經網路 2Gated RNN

迴圈神經網路 2(Gated RNN - LSTM ) simple RNN 具有梯度消失或者梯度爆炸的特點,所以,在實際應用中,帶有門限的RNN模型變種(Gated RNN)起著至關重要的作用,下面我們來進行介紹: LSTM (Long Short-term

吳恩達.深度學習系列-C1神經網路與深度學習-w3-作業:一個隱藏層進行二維資料分類

前言 **注意:coursera要求不要在網際網路公佈自己的作業。如果你在學習這個課程,建議你進入課程系統自行完成作業。使用邏輯迴歸作為一個最簡單的類似神經網路來進行影象判別。我覺得程式碼有參考和保留的意義。v 使用一個 2×4×1的網路來對資料進

吳恩達.深度學習系列-C1神經網路與深度學習-W2-作業:神經網路思想的邏輯迴歸

注意:coursera要求不要在網際網路公佈自己的作業。如果你在學習這個課程,建議你進入課程系統自行完成作業。使用邏輯迴歸作為一個最簡單的類似神經網路來進行影象判別。我覺得程式碼有參考和保留的意義。 Logistic Regression with a N