1. 程式人生 > >關於MapReduce二次排序的一點解答

關於MapReduce二次排序的一點解答

網上 hash 使用 table 為什麽 exti 而且 分區 ret

上一篇博客說明了怎麽自定義Key,而且用了二次排序的例子來做測試,但沒有詳細的說明二次排序,這一篇說詳細的說明二次排序,為了說明曾經一個思想的誤區,特地做了一個3個字段的二次排序來說明。後面稱其為“三次排序”。
測試數據:
a1,b2,c5
a4,b1,c3
a1,b2,c4
a2,b2,c4
a2,b1,c4
a4,b1,c2
測試目的:輸出以下結果首先根據第一個自段排序,如果第一個字段排好後再根據第二個字段的升序排序最後在根據第三個字段進行排序,得到以下結果。
a1 b2,c4
a1 b2,c5
a2 b1,c4
a2 b2,c4
a4 b1,c2
a4 b1,c3
之所以會設置三個字段,是想說明一個曾經困擾我很久的問題,問題大概描述如下:以下網上學習某大神講的mapreduce時他對二次排序原理的一段描述
二次排序原理
在map階段,使用job.setInputFormatClass定義的InputFormat將輸入的數據集分割成小數據塊splites,同時InputFormat提供一個RecordReder的實現。本例子中使用的是TextInputFormat,他提供的RecordReader會將文本的字節偏移量作為key,這一行的文本作為value。這就是自定義Map的輸入是<LongWritable, Text>的原因。然後調用自定義Map的map方法,將一個個<LongWritable, Text>對輸入給Map的map方法。註意輸出應該符合自定義Map中定義的輸出<IntPair, IntWritable>。最終是生成一個List<IntPair, IntWritable>。
排序的過程:(當時理解的第一次排序,只排序自定義類型中的第一個字段)
在map階段的最後,會先調用job.setPartitionerClass對這個List進行分區,每個分區映射到一個reducer。每個分區內又調用job.setSortComparatorClass設置的key比較函數類排序。可以看到,這本身就是一個二次排序。 如果沒有通過job.setSortComparatorClass設置key比較函數類,則使用key的實現的compareTo方法。
排序的過程:(當時理解的第二次排序,排序自定義類型中的第二個字段)
在reduce階段,reducer接收到所有映射到這個reducer的map輸出後,也是會調用job.setSortComparatorClass設置的key比較函數類對所有數據對排序。然後開始構造一個key對應的value叠代器。這時就要用到分組,使用job.setGroupingComparatorClass設置的分組函數類(如果沒設置則會判斷是否Key中所有的字段是否都相同,比較整個對象流的字節)。只要這個比較器比較的兩個key相同,他們就屬於同一個組,它們的value放在一個value叠代器,而這個叠代器的key使用屬於同一個組的所有key的第一個key。最後就是進入Reducer的reduce方法,reduce方法的輸入是所有的(key和它的value叠代器)。同樣註意輸入與輸出的類型必須與自定義的Reducer中聲明的一致。
核心總結:
1、map最後階段進行partition分區,一般使用job.setPartitionerClass設置的類,如果沒有自定義Key的hashCode()方法進行分區。
2、每個分區內部調用job.setSortComparatorClass設置的key的比較函數類進行排序,如果沒有則使用Key的實現的compareTo方法。
3、當reduce接收到所有map傳輸過來的數據之後,調用job.setSortComparatorClass設置的key比較函數類對所有數據對排序,如果沒有則使用Key的實現的compareTo方法。
4、緊接著使用job.setGroupingComparatorClass設置的分組函數類,進行分組,同一個Key的value放在一個叠代器裏面。如果未指定GroupingComparatorClass則則使用Key的實現的compareTo方法來對其分組。
以下是我剛開始思考的二次排序的數據流時的錯誤的想法:如果是多個map對同一個reduce發數據:數據流不就成為下面這樣了
a4,b4 a3,b3
a3,b3 a4,b4
---------------------->
a2,b1 a1,b2
a1,b2 a2,b1
如果reduce 接收到上一整塊數據,那麽hadoop框架便會在對第一個字段排序,什麽時候對第二個字段排的序呢,但為什麽結果又是排過序的呢
所以我做了本例的實驗,用三個字段來排序,實驗的結果就是本例的結果,最後還是感嘆自己學藝不精啊,排序的本質不就是根據compareTo做完整的比做嗎
所以從map端到reduce端的數據應該是這樣的:已經做一次完整的排序了
a4,b4 a3,b3
a3,b3 a4,b4
---------------------->
a2,b1 a1,b1
a1,b2 a2,b2
---------------------
作者:doegoo
來源:CSDN
原文:https://blog.csdn.net/doegoo/article/details/50377752
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!

關於MapReduce二次排序的一點解答