hdfs,mapreduce相關流程總結

HDFS讀寫數據的過程



1)client向namenode發送請求,namenode從元數據中檢查目標文件是否存在,上傳路徑路徑是否合法

2)namenode返回是否可以上傳文件,假設可以上傳

3)client請求第一個 block該傳輸到哪些datanode服務器上 

4)namenode返回可以上傳的datanode 服務器dn1 dn2  dn4

5)client將於datanode中最近的一個datanode 建立RPC連接  ,形成pipeline 通道 ,  pipeline會連接所有將被上傳的datanode機器,

6)、client開始往dn1上傳第一個block(先從磁盤讀取數據放到一個本地內存緩存),以packet爲單位,dn1收到一個packet就會傳給dn2,dn2傳給dn4

7)當一個block傳輸完成之後,client再次請求namenode上傳第二個block的服務器。最終完成上傳


1)client向namenode通信查詢元數據,找到存放block文件的datanode

2)挑選一臺datanode(就近原則,然後隨機)服務器,請求建立socket流  利用FileChannel讀取數據

3)datanode開始發送數據(從磁盤裏面讀取數據放入流,以packet爲單位來做校驗)

4)客戶端以packet爲單位接收,現在本地緩存,然後寫入目標文件

mapreduce的執行流程 (大體流程)


1、 一個mr程序啓動的時候,最先啓動的是MRAppMasterMRAppMaster啓動後根據本次job的描述信息,計算出需要的maptask實例數量,然後向集羣申請機器啓動相應數量的maptask進程

2、 maptask進程啓動之後,根據給定的數據切片範圍進行數據處理,主體流程爲:T

        a) 利用客戶指定的inputformat來獲取RecordReader讀取數據,形成輸入KV

        b) 將輸入KV對傳遞給客戶定義的map()方法,做邏輯運算,並將map()方法輸出的KV對收集到緩存

        c) 將緩存中的KV對按照K分區排序後不斷溢寫到磁盤文.

3、 MRAppMaster監控到所有maptask進程任務完成之後,會根據客戶指定的參數啓動相應數量的reducetask進程,並告知reducetask進程要處理的數據範圍(數據分區)

4、 Reducetask進程啓動之後,根據MRAppMaster告知的待處理數據所在位置,從若干臺maptask運行所在機器上獲取到若干個maptask輸出結果文件,並在本地進行重新歸併排序,然後按照相同keyKV爲一個組,調用客戶定義的reduce()方法進行邏輯運算,並收集運算輸出的結果KV,然後調用客戶指定的outputformat將結果數據輸出到外部存儲


mapTast 的 並行機制

    一個job的map階段並行度由客戶端在提交job時決定。而客戶端對應map階段並行度的劃分規則:

    將文件劃分爲多個split  每個split 交給一個mapTast進行處理  一個split的大小默認爲128MB

切片的形成是由FileInputFormat實現類的getSplits()方法完成,

如果input的文件非常的大,比如1TB,可以考慮將hdfs上的每個block size設大,比如設成256MB或者512MB

如果input的文件的文件非常小 ,且非常多    啓動多個maptast明顯會降低程序的效率 , 可以先將小文件合併成大文件 再交給mapreduce處理

FileInputFormat切片機制

1、切片定義在InputFormat類中的getSplit()方法

2、FileInputFormat中默認的切片機制:

簡單地按照文件的內容長度進行切片 切片大小,默認等於block大小 切片時不考慮數據集整體,而是逐個針對每一個文件單獨切片

比如待處理數據有兩個文件:

file1.txt    320M
file2.txt    10M

經過FileInputFormat的切片機制運算後,形成的切片信息如下:

file1.txt.split1--  0~128
file1.txt.split2--  128~256
file1.txt.split3--  256~320
file2.txt.split1--  0~10M

3、FileInputFormat中切片的大小的參數配置

通過分析源碼,在FileInputFormat中,計算切片大小的邏輯:Math.max(minSize, Math.min(maxSize, blockSize)); 切片主要由這幾個值來運算決定

minsize:默認值:1

配置參數: 

mapreduce.input.fileinputformat.split.minsize 

maxsize:默認值:Long.MAXValue

配置參數:mapreduce.input.fileinputformat.split.maxsize

blocksize
因此,默認情況下,切片大小=blocksize

maxsize(切片最大值):
參數如果調得比blocksize小,則會讓切片變小,而且就等於配置的這個參數的值

minsize (切片最小值):
參數調的比blockSize大,則可以讓切片變得比blocksize還大

選擇併發數的影響因素:

運算節點的硬件配置 運算任務的類型:CPU密集型還是IO密集型 運算任務的數據量


ReduceTask並行度的決定

 這個是由我們自己設置的

//默認值是1,手動設置爲4

job.setNumReduceTasks(4);

如果數據分佈不均勻,就有可能在reduce階段產生數據傾斜

注意: reducetask數量並不是任意設置,還要考慮業務邏輯需求,有些情況下,需要計算全局彙總結果,就只能有1個reducetask

儘量不要運行太多的reduce task。對大多數job來說,最好rduce的個數最多和集羣中的reduce持平,或者比集羣的 reduce slots小。這個對於小集羣而言,尤其重要。

mapreduceshuffle機制(只能簡單概述一下以統計統計單詞爲例)

  shuffle  分爲map端和reduce端

   map端

  當map函數通過context.write()開始輸出數據數,outputCollector將數據以<key,value>輸出到輸出到環形緩衝

環形緩衝區(kvbuffer) 默認大小爲100 實際上是是一個 字節數組 ,其中包括了數據區,和索引區  當輸出到環形緩衝區的數據達到閥值的時候,

默認爲80%  系統就會開啓一個線程將數據寫入磁盤, 這個過程叫做spill    (索引區的內容保存在內存, 也肯也寫入到文件中)

在寫入之前 , 通過調用PartitionergetPartition(),計算出數據要分到那個reduce,將這個信息同數據一起保存kvbuffer, 並對數據的key進行了一個快速排序(QuickSort)

排序後的數據被寫入到mapreduce.cluster.local.dir配置的目錄中的其中一個,Spill文件名像sipll0.out,spill1.out等

最後, 多個spill小文件 ,會合併成一個大文件 (這裏進行了一個合併排序, 分區),並最終形成一個唯一大文件     以及相對於的索引文件      建立索引文件是爲了方便進行數據的查找,

 

   

Reducer端

Reducer端的shuffle主要包括三個階段,copy、sort(merge)和reduce。

   copy:  Mrappmaster告知reduce ,mapTast的位置 , 每個Reducer只獲取屬於自己分區的數據

    sort:這個階段按照 ,在每個reduce對自己這個分區的數據  進行一個歸併排序 ,

    reduce: 合併後的文件作爲輸入傳遞給Reducer,Reducer針對每個key及其排序的數據調用reduce函數。產生的reduce輸出一般寫入到HDFS







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