hadoop 簡單入門與streaming常用配置參數說明

1. Hadoop包含兩核心部分

  1. hdfs
    1. Hadoop distribute file system -- hadoop分佈式文件系統,存儲數據
    2. NamenodeDatanode
    3. 常用命令形式hadoop fs -ls  /  hadoop fs -mkdir
  2. MapReduce
    1. 分而治之;map:實現分治;reduce:實現合併
    2. 解決數據可分割的計算問題
    3. 編程接口:常用Streaming;組成Job配置文件、map函數,reduce函數

2. hdfs結構圖

  1. Namenode存儲元數據,數據信息,數據備份信息
  2. Datanode 數據備份:本機架備份、異地備份

3. MapReduce調度框架

  1. JobClient負責根據用戶指定參數生成一個mapreduce作業,提交到JobTracker
  2. JobTracker: Master節點,將Job所有task調度到TaskTracker
  3. TaskTracker: 部署在每臺計算機節點的一個service

4.  MapReduce 執行層

  1. Map階段,讀入數據,通過partition聚集相同key數據,並寫到本機磁盤
  2. Reduce階段,不同reduce,讀入Map階段各maps相應輸出

5. streaming 作業

  1. streaming mapper
    1. 先啓動用戶提交作業時指定的一個外部程序,一般是腳本
    2. 這個外部程序作爲streaming mapper的子進程,streaming mapper讀取用戶輸入後,不再是調用map函數處理,而是通過管道寫到子進程的標準輸入
    3. 從子進程的標準輸出讀取數據,寫到磁盤上
  2. streaming 作業數據流向
    1. 父進程是Java,負責讀取數據通過管道發送給子進程
    2. 通過管道把結果再讀取回來

      一份數據在兩個不同進程中傳遞兩次

6 mapreduce – shuffle

  1. map --> shuffle –> reduce
  2. shuffle 從多個節點傳遞到多個節點,而不是多個節點到一個節點
  3. shuffle 包含partition、combiner
    1. partition : 數據歸併,分割map每個節點的結果,按照key分別映射給不同的reduce,默認是HashPartition,which reducer == (key.hashCode & Integer.MAX_VALUE)% numReduceTasks
    2. 作用:計算(key, value)所屬分區 ; 把同一分區數據合併、聚集
  4. combiner: combiner屬於優化方案,由於帶寬限制,應該儘量map和reduce之間的數據傳輸數量。它在Map端把同一個key的鍵值對合並在一起並計算,計算規則與reduce一致,所以combiner也可以看作特殊的Reducer

7. streaming 常用配置項

  1. stream.map.output.field.separator // 該參數屬於streaming作業參數,設置map輸出的字段分隔符,默認爲“\t”,該分隔符只對下面的stream.num.map.output.key.fields參數生效
  2. stream.num.map.output.key.fields // 設置map輸出的前幾個字段作爲key,一般與第二項stream.map.output.field.separator 結合使用
  3. mapred.text.key.partitioner.options  // 設置key內某個字段或者某個字段範圍用做partition
  4. mapred.text.key.comparator.options // 設置key中需要比較的字段或字節範圍
  5. partitioner // 主要用於對鍵值進行劃分,負責將map的輸出結果根據key進行分割。Key用於確定不同的key落到不同的reduce上,通常對key進行Hash以後對reduce取mod,該key對應的紀錄最終將根據mod值落到對應的reduce上進行處理。HashPartitioner, IndexUpdatePartitioner, KeyFieldBasedPartitioner, SleepJob,默認的爲 HashPartitioner,即對key直接進行hash分到對應的reduce,具體見第6部分。更高級一點的爲 KeyFieldBasedPartitioner,該partitioner可以指定key中前幾個字段用於分割
  6. HashPartition  最基本的Partitioner,如果不指定Partitioner的話則默認使用該類。輸出格式爲最基本的key”\t“value
  7. KeyFieldBasedPartitioner 可以看做HashPartitioner的擴展,他將原有的對單字段Key的hash擴展到可以靈活地對多字段key進行分桶並排序,對應配置參數如下:
  8. -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner // 該參數表示作業啓用KeyFieldBasedParitioner
  9. -D map.ouput.key.field.separator // 該參數屬於KeyFieldBasedPartitioner參數,只有當啓用KeyFieldBasedParititioner時,該參數纔會生效;該參數指明map輸出結果中字段之間的分隔符(該分隔符只對下面的num.key.fields.for.partition參數生效);
  10. -D num.key.fields.for.partition // 該參數同樣屬於KeyFieldBasedPartitioner參數;該參數指明map輸出結果的key按上述分隔符切分後,前幾個字段將用來做partition;該參數不能與mapred.text.key.partitioner.options共用;
  11. -D mapred.text.key.partitioner.options // 該參數同樣屬於KeyFieldBasedPartitioner參數; 該參數指明map輸出結果的key按上述分隔符切分後,使用哪些字段用來做partition;該參數不能與num.key.fields.for.partition共用,一起使用則以num.key.fields.for.partition爲準;
  12. KeyFieldBaseComparator // 可以靈活設置比較位置的高級比較器,但是它和沒有自己獨有的比較邏輯,而是使用默認Text的基於字典序或者通過-n來基於數字比較,直觀來說,partition指定key中的分區元素,KeyFieldBaseComparator用作指定key排序字段以及排序規則,參數配置如下:
  13. -D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator // 該參數表示作業啓用KeyFieldBasedComparator
  14. -D mapred.text.key.comparator.options="-k3,3 -k4nr" // 以key中第三個字段正序,第四個字段逆序比較排序
  15. stream.memory.limit // 任務內存限制
  16. mapred.reduce.tasks // 指定reducer個數
  17. cmdenv //傳遞給streaming命令的環境變量
  18. -input //HDFS目錄或文件路徑, Mapper的輸入數據,文件要在任務提交前手動上傳到HDFS
  19. -output // reducer輸出結果的HDFS存放路徑,  不能已存在,但腳本中一定要配置,多次-input,指定多個輸入文件
  20. -mapper // 可執行命令,mapper程序
  21. -reducer // 可執行命令, reduce程序,不需要reduce處理就不指定
  22. -file //本地mapper、reducer程序文件、程序運行需要的其他文件,將本地文件分發給計算節點;文件作爲作業的一部分,一起被打包並提交,所有分發的文件最終會被放置在datanode該job的同一個專屬目錄下:jobcache/job_xxx/jar
  23. -cacheFile //分發HDFS文件
  24. -cacheArchive // 分發HDFS壓縮文件、壓縮文件內部具有目錄結構
  25. mapred.job.priority //作業優先級
  26. mapred.job.map.capacity // 最多同時運行map任務數
  27. mapred.job.reduce.capacity //最多同時運行reduce任務數
  28. mapred.job.name // job name

 

8. key-partition 實例

  1. key 不等於 partition,也就是說,分桶規則跟map階段的key有可能不是一回事
  2. 假設,文件A中內容如下:

                      

 

  • 第一種作業方式(部分參數):
./hadoop streaming
-D stream.map.output.field.separator=.
-D stream.num.map.output.key.fields=2

                                 

        只是將map的輸出結果按兩個字段切分成了key和value;再分桶上我們可以看出,它是以前兩個字段作爲一個整體來進行分桶的,e.5與e.9沒有分在一個reduce

  • 第二種作業:
./hadoop streaming
-D stream.map.output.field.separator=.
-D stream.num.map.output.key.fields=2
-D map.output.key.field.separator=.
-D num.key.fields.for.partition=1
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner\

                                   

              這裏啓用了KeyFieldBasedPartitioner,並且制定分桶以key的第一個字段爲準;我們可以看出mapred依然採用的是前兩個字段爲key,但是在分桶上只對第一個字段做了哈希函數,因此這次e.5和e.9分到了一個reducer內

  • 第三種作業
./hadoop streaming
-D stream.map.output.field.separator=.
-D stream.num.map.output.key.fields=3
-D map.output.key.field.separator=.
-D num.key.fields.for.partition=1  
-D mapred.text.key.partitioner.options=-k2,3
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

       這次將key的長度改成3個字段,分桶標準也變成key的第2、3個字段,可以看出e.5.1被分在了一起,而第三個字段不同的e.5.9被分到了其他的reducer中

  • 第四種作業
./hadoop streaming \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator \
-D stream.num.map.output.key.fields=4 \
-D stream.map.output.field.separator=. \
-D map.output.key.field.separator=. \
-D mapred.text.key.partitioner.options=-k1,2 \
-D mapred.text.key.comparator.options="-k3,3 -k4nr" \

                                    

         這次key的長度爲4,分桶標準爲key的第一、二個字段,可以看出,e.5被分到一個桶內,而輸出結果,按照key的第三個字段的正序,第四個字段的逆序排列輸出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章