map reduce原理
shuffle是連線Map和Reduce之間的橋樑,Map的輸出要用到Reduce中必須經過shuffle這個環節,shuffle的效能高低直接影響了整個程式的效能和吞吐量。
shuffle的目的是以下三點:
- 完整地從map task端讀取資料到reduce 端。
- 在跨節點讀取資料時,儘可能地減少對頻寬的不必要消耗。
- 減少磁碟IO對task執行的影響。
在進入map這一步之前,首先是split(分片),按輸入檔案大小和數量切分多個片,每一個片對應一個maptask。
MR過程中共涉及三次排序,每一步如下
InputFormat
預設一般使用FileInputFormat,HDFS檔案做為輸入,一行行處理(預設是TextOutputFormat)
是一個介面,可以有多種實現方式,如:資料庫、HTTP、FTP等
需要實現Split、RecordReader等介面。InputFormat實現了split的機制,此時也決定了map的數量
Split切片
map task的併發量由切片的數量決定,有多少切片就會有多少map task
切片是邏輯概念,指的是檔案中資料的偏移量範圍
切片的具體大小應該是根據要處理的檔案大小來調整的
MAP階段
快取、分組(partition)、排序、combiner、合併溢寫(需要排序)
在讀取資料過程中會首先寫到對應的環形記憶體緩衝區,當達到閥值(預設寫到緩衝區80%)時會溢寫磁碟
io.sort.spill.percent可以設定閥值
mapred.local.dir溢寫路徑,設定多路徑時有助於利用磁碟i/o
分組partition
它分割map每個節點的結果,按照key分別對映給不同的reduce。也可以理解為根據key或value及reduce的數量來決定當前的這對輸出資料最終應該交由哪個reduce task處理。partition的作用就是把這些資料歸類。每個map任務會針對輸出進行分割槽,及對每一個reduce任務建立一個分割槽。劃分分割槽由使用者定義的partition函式控制,預設使用雜湊函式來劃分分割槽。
(1)計算(key,value)所屬與的分割槽
當map輸出的時候,寫入快取之前,會呼叫partition函式,計算出資料所屬的分割槽,並且把這個元資料儲存起來。
(2)把屬與同一分割槽的資料合併在一起
當資料達到溢位的條件時(即達到溢位比例,啟動執行緒準備寫入檔案前),讀取快取中的資料和分割槽元資料,然後把屬與同一分割槽的資料合併到一起。
combiner
為了減少map到reduce間傳輸的資料量,提高傳輸效率,可以使用此方式進行優化,在map端把同一個key的鍵值對合並在一起並計算,計算規則同reduce,故等同於reduce過程。
當map輸出資料根據分割槽排序完成後,寫入檔案前會執行一次combine操作
如果map輸出比較大,溢位檔案個數大於3(此值可以通過屬性min.num.spills.for.combine配置)時,在merge的過程(多個spill檔案合併為一個大檔案)中前還會執行combiner操作
注意
combine只用於reduce輸入k/v和輸出k/v型別完成相同情況
經過combine不會影響最終計算結果,如求和、最大值,但平均值會受影響
copy、排序、合併
經http檔案傳輸,再次合併排序,做為reduce的輸入
reduce階段
OutputFormat
預設使用FileOutputFormat,HDFS檔案做為輸出,是一個介面