MapReduce的工作流程
1.客戶端將每個block塊切片(邏輯切分),每個切片都對應一個map任務,默認一個block塊對應一個切片和一個map任務,split包含的信息:分片的元數據信息,包含起始位置,長度,和所在節點列表等
2.map按行讀取切片數據,組成鍵值對,key為當前行在源文件中的字節偏移量,value為讀到的字符串
3.map函數對鍵值對進行計算,輸出<key,value,partition(分區號)>格式數據,partition指定該鍵值對由哪個reducer進行處理。通過分區器,key的hashcode對reducer個數取模。
4.map將kvp寫入環形緩沖區內,環形緩沖區默認為100MB,閾值為80%,當環形緩沖區達到80%時,就向磁盤溢寫小文件,該小文件先按照分區號排序,區號相同的再按照key進行排序,歸並排序。溢寫的小文件如果達到三個,則進行歸並,歸並為大文件,大文件也按照分區和key進行排序,目的是降低中間結果數據量(網絡傳輸),提升運行效率
5.如果map任務處理完畢,則reducer發送http get請求到map主機上下載數據,該過程被稱為洗牌shuffle
6.可以設置combinclass(需要算法滿足結合律),先在map端對數據進行一個壓縮,再進行傳輸,map任務結束,reduce任務開始
7.reduce會對洗牌獲取的數據進行歸並,如果有時間,會將歸並好的數據落入磁盤(其他數據還在洗牌狀態)
8.每個分區對應一個reduce,每個reduce按照key進行分組,每個分組調用一次reduce方法,該方法迭代計算,將結果寫到hdfs輸出
洗牌階段
1.copy:一個reduce任務需要多個map任務的輸出,每個map任務完成時間很可能不同,當只要有一個map任務完成,reduce任務立即開始復制,復制線程數配置mapred-site.xml參數“mapreduce.reduce.shuffle.parallelcopies",默認為5.
2.copy緩沖區:如果map輸出相當小,則數據先被復制到reduce所在節點的內存緩沖區大小配置mapred-site.xml參數“mapreduce.reduce.shuffle.input.buffer.percent”,默認0.70),當內存緩沖區大小達到閥值(mapred-site.xml參數“mapreduce.reduce.shuffle.merge.percent”,默認0.66)或內存緩沖區文件數達到閥值(mapred-site.xml參數“mapreduce.reduce.merge.inmem.threshold”,默認1000)時,則合並后溢寫磁盤。
3.sort:復制完成所有map輸出后,合並map輸出文件並歸並排序
4.sort的合並:將map輸出文件合並,直至≤合並因子(mapred-site.xml參數“mapreduce.task.io.sort.factor”,默認10)。例如,有50個map輸出文件,進行5次合並,每次將10各文件合並成一個文件,最后5個文件。
K,V使用自定義數據類型
框架會對鍵,值序列化,因此鍵類型和值類型需要實現writable接口
框架會對鍵進行排序,因此必須實現writableComparable接口