6.mr中理解分區和分組

1.MapReduce中數據流動
(1)最簡單的過程:  map reduce
(2)定製了partitioner以將map的結果送往指定reducer的過程: map partition reduce
(3)增加了在本地先進性一次reduce(優化)過程: map combin(本地reduce) partition -reduce

自定義一個分區方案,默認通過key的hash值
job中添加設置:
結果參考:

2.Mapreduce中Partition的概念以及使用
1)Partition的原理和作用
          得到map給的記錄後,他們該分配給哪些reducer來處理呢?hadoop採用的默認的派發方式是根據散列值來派發的,但是實際中,這並不能很高效或者按照我們要求的去執行任務。例如,經過partition處理後,一個節點的reducer分配到了20條記錄,另一個卻分配道了10W萬條,試想,這種情況效率如何。又或者,我們想要處理後得到的文件按照一定的規律進行輸出,假設有兩個reducer,我們想要最終結果中part-00000中存儲的是"h"開頭的記錄的結果,part-00001中存儲其他開頭的結果,這些默認的partitioner是做不到的。所以需要我們自己定製partition來根據自己的要求,選擇記錄的reducer。自定義partitioner很簡單,只要自定義一個類,並且繼承Partitioner類,重寫其getPartition方法就好了,在使用的時候通過調用Job的setPartitionerClass指定一下即可
          Map的結果,會通過partition分發到Reducer上。Mapper的結果,可能送到Combiner做合併,Combiner在系統中並沒有自己的基類,而是用Reducer作爲Combiner的基類,他們對外的功能是一樣的,只是使用的位置和使用時的上下文不太一樣而已。Mapper最終處理的鍵值對<key, value>,是需要送到Reducer去合併的,合併的時候,有相同key的鍵/值對會送到同一個Reducer那。哪個key到哪個Reducer的分配過程,是由Partitioner規定的。它只有一個方法, getPartition(Text key, Text value, int numPartitions)
          輸入是Map的結果對<key, value>和Reducer的數目,輸出則是分配的Reducer(整數編號)。就是指定Mappr輸出的鍵值對到哪一個reducer上去。系統缺省的Partitioner是HashPartitioner,它以key的Hash值對Reducer的數目取模,得到對應的Reducer。這樣保證如果有相同的key值,肯定被分配到同一個reducre上。如果有N個reducer,編號就0,1,2,3……(N-1)。
2)Partition的使用
          分區出現的必要性,如何使用Hadoop產生一個全局排序的文件?最簡單的方法就是使用一個分區,但是該方法在處理大型文件時效率極低,因爲一臺機器必須處理所有輸出文件,從而完全喪失了MapReduce所提供的並行架構的優勢。事實上我們可以這樣做,首先創建一系列排好序的文件;其次,串聯這些文件(類似於歸併排序);最後得到一個全局有序的文件。主要的思路是使用一個partitioner來描述全局排序的輸出。比方說我們有1000個1-10000的數據,跑10個ruduce任務, 如果我們運行進行partition的時候,能夠將在1-1000中數據的分配到第一個reduce中,1001-2000的數據分配到第二個reduce中,以此類推。即第n個reduce所分配到的數據全部大於第n-1個reduce中的數據。這樣,每個reduce出來之後都是有序的了,我們只要cat所有的輸出文件,變成一個大的文件,就都是有序的了.
          基本思路就是這樣,但是現在有一個問題,就是數據的區間如何劃分,在數據量大,還有我們並不清楚數據分佈的情況下。一個比較簡單的方法就是採樣,假如有一億的數據,我們可以對數據進行採樣,如取10000個數據採樣,然後對採樣數據分區間。在Hadoop中,patition我們可以用TotalOrderPartitioner替換默認的分區。然後將採樣的結果傳給他,就可以實現我們想要的分區。在採樣時,我們可以使用hadoop的幾種採樣工具,RandomSampler,     InputSampler,     IntervalSampler
          這樣,我們就可以對利用分佈式文件系統進行大數據量的排序了,我們也可以重寫Partitioner類中的compare函數,來定義比較的規則,從而可以實現字符串或其他非數字類型的排序,也可以實現二次排序乃至多次排序


3.MapReduce中分組的概念和使用
    分區的目的是根據Key值決定Mapper的輸出記錄被送到哪一個Reducer上去處理。而分組的就比較好理解了。筆者認爲,分組就是與記錄的Key相關。在同一個分區裏面,具有相同Key值的記錄是屬於同一個分組的。

每個分區映射到一個reducer。每個分區內又調用job.setSortComparatorClass設置的key比較函數類排序。可以看到,這本身就是一個二次排序。在reduce階段,reducer接收到所有映射到這個reducer的map輸出後,也是會調用job.setSortComparatorClass設置的key比較函數類對所有數據對排序。然後開始構造一個key對應的value迭代器。這時就要用到分組,使用job.setGroupingComparatorClass設置的分組函數類。只要這個比較器比較的兩個key相同,他們就屬於同一個組(它們的value放在一個value迭代器,而這個迭代器的key使用屬於同一個組的所有key的第一個key。最後就是進入Reducer的reduce方法,reduce方法的輸入是所有的key和它的value迭代器。同樣注意輸入與輸出的類型必須與自定義的Reducer中聲明的一致


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