注:本文注重原理介紹,較少涉及程式設計實現,有錯誤請指正,感謝~
在進入正文之前需要了解這幾個概念:
hdfs:可以先簡單理解為它是乙個大型分布式的檔案系統,裡面存放了大量檔案,也可以理解為放著俗稱的大資料。
資料塊:hdfs中的資料以資料塊為單位存放,預設是64mb,hdfs中的檔案可能遠遠大於64mb,它被分割成很多個資料塊,存放在集群上,資料塊不一定存放在一台機器上,也不一定是連續存放的。
首先大致了解一下map的操作流程。
hdfs中待處理的資料首先進行切分(input split)得到很多個資料分片,對應很多個map任務。每個資料分片都是由鍵值對組成的,其中鍵是乙個長整數偏移量,是某一行起始位置相對於檔案起始位置的偏移量(這裡的鍵值並不是很重要,沒必要過分關注),值就是對應的一行文字資料。資料分片中的一對(鍵-值)資料送給乙個map方法來處理,處理之後的結果仍是鍵值對的形式,這裡的鍵值對由你重寫的map函式來指定(這裡的鍵就很重要了)。
執行到這裡,相當於之前的資料分片中的每條資料都經過處理,得到了新的鍵值對資料。不同的資料分片中可能會包含相同的key值,因此需要對這些資料片進行合併排序,將相同key值對應的資料整合到一起。姑且將整合以後得到的很多資料稱為資料段(不是官方說法,只是為了方便解釋並與前面的定義做區分)。
關於資料段有四條:
相同key值的資料一定在同乙個資料段中
每個資料段內key值都是有序排列的,但資料段中所有key值不是全域性有序的
乙個資料段對應乙個reduce任務
乙個資料段的資料最終一定是放在要執行該reduce任務的機器的磁碟中
1. map的輸出結果在**?
上面我們提到對資料分片進行處理後,得到map的輸出結果。map任務將其輸出寫入本地硬碟。這是因為map輸出是中間結果,還需要傳給reduce做下一步操作,輸出到hdfs上,根據hdfs的備份機制會自動備份,這是完全沒有必要的。
2. shuffle和排序
這個過程是在得到map輸出後進行的,也就是經過shufffle和排序得到了上面提到的「資料段」,將這些資料段通過網路傳輸傳送給執行reduce任務的節點。關於shuffle和排序的機制不做詳細說明,現在只要知道有這麼回事就行了。要知道的是,資料段也是邏輯上的資料段,在物理記憶體中完全可能是不連續的,所以執行reduce任務的機器收到的可能是資料段的部分資料,需要做合併操作後再執行任務
乙個reduce任務對應乙個資料段,資料段中含有多條經map處理後的鍵值對,並按鍵值排序。reduce任務將同樣key值的所有記錄給乙個reduce函式進行處理,並將處理結果輸出到hdfs上。
reduce的輸出結果也會組合成資料塊,第乙個副本村儲存在本地節點上,其他讀副本存在其他機架的節點上。我們需要指定reduce任務個數,乙個任務對應乙個輸出檔案,如果在程式中選擇多路輸出,那乙個任務就對應多個輸出檔案。
1. 如何理解 reduce函式被重複呼叫
在大致了解了mapreduce的操作流程以後,考慮乙個jvm虛擬機器的問題。在配置中可以設定:
mapred.job.reuse.jvm.num.tasks : -1
這表示多個執行於同乙個datanode上的map和reduce的任務可以共用乙個jvm,也就是說這台機器上可能有map任務,也可能有reduce任務,在執行完map任務後,接下來要執行的reduce任務可以使用這個jvm。
我們知道乙個reduce任務對應的資料段中包含了很多個不同的key值,乙個key值對應一reduce函式處理,如果我想要對乙個資料塊中不同key值的物件進行操作,是需要放在reduce函式外實現就可以。舉個栗子來理解,假如我要對每個key抽取一條記錄,我只需要在reduce函式外宣告乙個list,然後再reduce函式內新增元素即可。
可以理解為對於乙個reduce任務而言,他是在乙個jvm上執行的,所以宣告在reduce函式外的變數只宣告一次(因為只有reduce函式才重複呼叫)所以變數一直有效且不會被覆蓋。
並且,這與是否設定「mapred.job.reuse.jvm.num.tasks「無關,我測試了不設定這個引數也是可行的,其實也就驗證了這個引數只是設定不同的reduce任務和map任務是否共用jvm,對於同乙個reduce任務而言他就是在乙個jvm中進行處理的。
hadoop map reduce 階段筆記
shuffle and sort mr 框架保證 每個 reducer 的輸入都是按照 key 鍵排過序的。shuffle 將map輸出結果送到reducer和排序的功能。1 map 每個map task將結果輸出到環形記憶體緩衝區,當到達一定閾值,則啟動乙個後台程序將快取中的資料 1 按照 red...
Hadoop MapReduce 效能優化
我們時常談論說到mapreduce時,我們都會說它是離線計算框架,磁碟io開銷大,job執行比較慢等等。這一篇部落格,南國系統回顧下mr程式執行慢的原因,以及如何優化mr程式。我們都知道mapreduce是離線計算框架,不同於spark記憶體計算框架模型。乙個標準的mr程式由map方法和reduce...
九 hadoop mapreduce分割槽
一 什麼時候分割槽?1 分割槽的實現 通過繼承partitioner類,實現getpartition方法。public int getpartition key key,value value,int reducetasknumber map結束後得到的每個key value都呼叫該方法,並把key...