mapreduce框架會確保每乙個reducer的輸入都是按key進行排序的。
一般,將排序以及map的輸出傳輸到reduce的過程稱為混洗(shuffle)。
每乙個map都包含乙個環形的快取,預設100m,map首先將輸出寫到快取當中。當快取的內容達到「閾值」時(閾值預設的大小是快取的80%),乙個後台執行緒負責將結果寫到硬碟,這個過程稱為「spill」。spill過程中,map仍可以向快取寫入結果,如果快取已經寫滿,那麼map進行等待。
spill的具體過程如下:
首先,後台執行緒根據reducer的個數將輸出結果進行分組,每乙個分組對應乙個reducer。
其次,對於每乙個分組後台執行緒對輸出結果的key進行排序。在排序過程中,如果有combiner函式,則對排序結果進行combiner函式進行呼叫。每一次spill都會在硬碟產生乙個spill檔案。
因此,乙個map task有可能會產生多個spill檔案,當map寫出最後乙個輸出時,會將所有的spill檔案進行合併與排序,
輸出最終的結果檔案。
在這個過程中combiner函式仍然會被呼叫。從整個過程來看,combiner函式的呼叫次數是不確定的。
hadoop是如何進行排序的呢?
根據筆者的理解,mapreduce的排序過程分為兩個步驟,乙個按照key進行排序;乙個是按照key進行分組。這兩部分分別由
sortcomparator和
groupingcomparator來完成。
具體的配置如下面黑體所示:
job.setpartitionerclass(firstpartitioner.class);
job.setsortcomparatorclass(keycomparator.class);
job.setgroupingcomparatorclass(groupcomparator.class);
如果使用者想自定義排序方式,首先需要實現兩個comparator並將其按照上面的格式進行配置。每乙個comparator需要繼承writablecomparator基類。如下所示:
public static class groupcomparator extends writablecomparator
@override
public int compare(writablecomparable w1, writablecomparable w2) }
hadoop的shuffle和排序
1.1 maptask執行內部原理 當map task開始運算,並產生中間資料時,其產生的中間結果並非直接就簡單的寫入磁碟。這中間的過程比較複雜,並且利用到了記憶體buffer來進行已經產生的部分結果的快取,並在記憶體buffer中進行一些預排序來優化整個map的效能。如上圖所示,每乙個map都會對...
hive中的排序和分組
order by order by 會對輸入坐全域性排序,因此 只有乙個reducer 多個reducer會無法保證全域性有序 只有乙個reducer,會導致當輸入規模較大時,需要較長的計算時間.set hive.mapred.mode nonstrict default value 預設值 set...
SQL中的排序和分組
sql中的排序和分組 一 排序 order by 語法 select 字段 from 表名稱 where 篩查條件 order by 排序字段列表 順序不能亂 desc ace select from student where name like 文 order by name desc二 分組 ...