hadoop streaming 輸出數據分割與二次排序

輸出數據分割

默認情況下Streaming框架將map輸出的每一行第一個”\t”之前的部分作爲key,之後的部分作爲value,key\tvalue又作爲reduce的輸入。可以用-D stream.map.output.field.separator改變map輸出中key和value的分隔符,用-D stream.num.map.output.key.fields設置分隔符的位置,該位置之前的部分作爲key,之後的部分作爲value。如下所示,其中-D stream.map. output.field.separator=:指定使用冒號”:”將map輸出的一行分隔爲key/value,-D stream.num.map.output.key.fields=2指定在第二個冒號處進行分隔,也就是第二個冒號之前的作爲key,之後的作爲value。如果沒有冒號或冒號少於兩個,則key爲整行,value爲空。 

   $HADOOP_HOME/bin/hadoop streaming \

       -D stream.map.output.field.separator=: \

       -D stream.num.map.output.key.fields=2 \

-input /user/test/input -output /user/test/output \

-mapper mymapper.sh -reducer myreducer.sh \

-file /home/work/mymapper.sh \

-file /home/work/myreducer.sh \

-jobconf mapred.job.name=”output-sep-demo”

與map類似,對於reduce的輸出,同樣也可以用-D stream.reduce.output.field.separator-D stream.num.reduce.output.key.fields定製key/value分隔方式。

二次排序

轉自:

我們知道,一個典型的Map-Reduce過程包 括:Input->Map->Patition->Reduce->Output。Pation負責把Map任務輸出的中間結果 按key分發給不同的Reduce任務進行處理。Hadoop 提供了一個非常實用的partitioner類KeyFieldBasedPartitioner,通過配置相應的參數就可以使用。通過 KeyFieldBasedPartitioner可以方便地實現二次排序。 
使用方法: 
      -partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner 
一般配合: 
      -D map.output.key.field.separator及-D num.key.fields.for.partition使用。 
map.output.key.field.separator指定key內部的分隔符 
      num.key.fields.for.partition指定對key分出來的前幾部分做partition而不是整個key

示例: 
1. 編寫map程序mapper.sh;reduce程序reducer.sh; 測試數據test.txt

mapper.sh:  

#!/bin/sh  cat    

reducer.sh:  

#!/bin/sh  sort    

test.txt內容:  

1,2,1,1,1  

1,2,2,1,1  

1,3,1,1,1  

1,3,2,1,1  

1,3,3,1,1  

1,2,3,1,1  

1,3,1,1,1  

1,3,2,1,1  

1,3,3,1,1  

2. 測試數據test.txt放入hdfs,運行map-reduce程序

$ hadoop streaming /    

-D stream.map.output.field.separator=, /    

-D stream.num.map.output.key.fields=4 /    

-D map.output.key.field.separator=, /    

-D num.key.fields.for.partition=2 /    

-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner /    

-input /app/test/test.txt  /  

-output /app/test/test_result / 
-mapper ./mapper.sh  /    

-reducer ./reducer.sh /    

-file mapper.sh /    

-file reducer.sh /    

-jobconf mapre.job.name="sep_test"    

$ hadoop fs –cat /app/test/test_result/part-00003      

1,2,1,1     1      

1,2,2,1     1      

1,2,3,1     1    

$ hadoop fs –cat /app/test/test_result/part-00004      

1,3,1,1     1      

1,3,1,1     1      

1,3,2,1     1      

1,3,2,1     1      

1,3,3,1     1      

1,3,3,1     1  

通過這種方式,就做到前4個字段是key,但是通過前兩個字段進行partition的目的
注意:
-D map.output.key.field.separator=, /  

這個分隔符使用TAB鍵貌似不管用

參數對比

hadoop中的map-reduce是處理<key,value>這樣的鍵值對,故指定<key,value>的分割符等參數可以分成三類:
map輸出時分割符
分桶時的分隔符
reduce輸出時的分割符
下面分別敘述:
1. map輸出時分割符
參數:
stream.map.output.field.separator
作用:
指定map輸出時的分割符
stream.num.map.output.key.fields
指定輸出按照分隔符切割後,key所佔有的列數
舉例:
input數據:
2,2,c,c,c,c
參數配置:
-mapper "cat" # map 爲分佈式的cat命令
-reducer ""  #reduce爲空 /
-jobconf stream.map.output.field.separator=','  /
-jobconf stream.num.map.output.key.fields=2 /
即按照','逗號分隔後,去前2列作爲key
output數據:
2,2     c,c,c,c  #其中key爲2,2  value爲c,c,c,c
2. 分桶時的分隔符
map.output.key.field.separator
指定map輸出<key,value>對之後,其中key內部的分割符
num.key.fields.for.partition
指定分桶時,按照分隔符切割後,用於分桶key所佔的列數
舉例:
map的output數據:
2,2     c,c,c,c
參數配置:
-jobconf map.output.key.field.separator=',' /
-jobconf num.key.fields.for.partition='1'   /
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner /
output數據:
這樣用於partition分桶的key就爲:2
注意,這裏分桶不應該用默認的HashPartitioner
3. reduce輸出時的分割符
這個與map類似,分別用於reduce輸出時分隔符以及key佔有的列數
stream.reduce.output.field.separator
stream.num.reduce.output.key.fields


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