18mapreduce的案例加強——好程序

流量統計

1363157985066     13726230503    00-FD-07-A4-72-B8:CMCC    120.196.100.82    i02.c.aliimg.com      24    27    2481    24681    200
1363157995052     13826544101    5C-0E-8B-C7-F1-E0:CMCC    120.197.40.4            4   0    264    0    200

1、對流量日誌中的用戶統計總上、下行、總流量

 

主要考慮的是map和reduce。
map端的輸入是不用考慮的,都是以文本的形式輸入行。map考慮的是輸出,數據以什麼樣去處理比較好。

reduce端的輸入是迭代器,要知道輸入的迭代器是什麼,數據還是要考慮的,以什麼樣的規則將數據傳遞給reduce,這是reduce調用的規則,要考慮框架的規則。輸出的key是什麼,輸出的value是什麼

因爲一個手機號表示一個用戶,所以key就是手機號。先考慮Reduce的輸入,在考慮map的輸出,總上、下行、總流量則爲value,包含那麼多字符串,可以封裝爲一個對象。整成了自定義類

 

mapreduce
map
輸入
-------------------------------------------------------
輸出:
key:phonenum
value:flowBean(上、下行、總流量) 作爲一個整體
數據:(用什麼樣的數據進行處理)
=======================================================
reduce
輸入:
key:phonenum
value:flowBean(上、下行、總流量)作爲一個整體
-------------------------------------------------------
輸出:
key:phonenum
value:flowBean(上、下行、總流量)作爲一個整體
up:down:total
                   


在這裏是不需要排序的,因爲排序是基於key的,而這裏的key只有一個                    

1、定義一個自定義類,然後類裏面包含所需要的屬性

2、map端輸出,Reduce要拉取數據,所以數據都是需要可序列化的,所以要實現可序列化接口。並且實現它的方法

 

要有兩個構造方法,一個是無參構造,一個是有參構造。有參構造返回的是兩個相加

 

對屬性添加get,set的方法

 

實現序列化的方法(序列化和反序列化的順序要一致)

 

實現tostring方法

到此,JavaBean就OK了。

 

接下來就要寫MapReduce(map端一次只處理一行數據

定義一個類flowCount,而且要繼承Mapper,Reduce

1、先將value轉爲字符串,2、通過空格tab進行切割,3、獲取數值,4、調用參數方法計算,5、獲取到的k,v放到上下文

 

實現Reduce方法

1、同一個手機號的values循環,2將值進行統計累加,3、傳給參數方法,4、返回的信息給到上下文

 

 

驅動方法

 

 

13480253104    180    180    360
13502468823    7335    110349    117684
13560436666    1116    954    2070
13560439658    2034    5892    7926
13602846565    1938    2910    4848

最終是要排倒敘的,reduce端的輸入是要什麼數據,才能得出reduce端所要輸出的內容

統計流量且按照流量大小倒序排序(總量倒序、下行、上行倒序,phoneNum正序)  要統計還要倒敘

其實上面第一個Reduce輸出的時候,已經是統計完了,現在這個Reduce要對他們進行排序,而排序只是對key進行排序

所以,Reduce的輸入就是類,flowBean,則也就是將第一個Reduce的輸出的k,v調換爲第二個map的輸出。

mapreduce
map
輸入
key:phonenum
value:13480253104    180    180    360    flowBean
----------------------------------------------------
輸出: 
key:flowBean
value:phonenum
數據:


=====================================================
reduce
輸入:
key:flowBean
value:phonenum

這個是Reduce調用後的,傳給Reduce方法(倒敘排序)


------------------------------------------------------
輸出:
key:phonenum
value:flowBean(上、下行、總流量)
up:down:total

結果如圖


     

具體代碼分析如下              

要做比較,所以繼承比較的接口,比較flowBean這個類

返回比較的順序(內部用的是分區加排序)自定義比較

到此flowBean改完了

到此map端改完了

驅動方法的輸入輸出修改一下

 

 

自定義分區

3、統計流量且按照手機號的歸屬地,將結果數據輸出到不同的省份文件中
134 江西0
135 北京1
136 上海2
137 天津3
138 重慶4
139 深圳5
其他  其他


map階段
輸出:
key:
value:
===========================
reducetask:7      7個分區,設置7個reducetask
===========================
reduce階段
輸入:
key:
value:
----------------------------
輸出:
key:phonenum (按照號碼段輸出)
value:flowBean

 

要自定義Patition類分區,要實現partitioner方法,按照省份進行分區

patitioner是在map端的輸出之後,進行分區,patitioner要獲取到k值,則需要對key進行分區

數據類型要和map端的輸出一樣

進行分區

 

在flowCount類裏面修改,將自定義的分區加入。已經設置Reduce的接收的參數

在客戶端指定分區數

修改下面的hash取模的分區數

這個是源碼的寫法

這個是自定義的寫法

 

 

 

分組Top1的實現

top-1的value可以不要,top-n的value是要的

map端輸出的是類,shuffle的過程就是要進行分區,還有金額倒序,

Reduce端要將shuffle後端 合併成一個文件,合併過程中也是要排序的,用comparTo排序(比較大小而已)

循環迭代,就是比較key是否相等,而用groupingcomparator欺騙迭代器,也就是實現了同一個訂單號調用一次Reduce方法

 


TOP 1

<Order_0000001,Pdt_01,222.8>
<Order_0000001,Pdt_05,25.8 >
<Order_0000002,Pdt_05,325.8>
<Order_0000002,Pdt_03,522.8>
<Order_0000002,Pdt_04,122.4>
<Order_0000003,Pdt_01,222.8>

先寫一個類OrderBean,而且需要實現比較的接口,而且需要序列化

到此Javabean實現了。比普通類多實現序列化方法,和比較方法。

自定義partitioner,將訂單號相同的orderBean發到一個Reduce,按訂單號進行分區,訂單號相同作爲一個分區

按照訂單號進行分組,功能就是用於欺騙迭代器,

先要實現一個無參構造,而且實現一個比較方法

最後要實現TopN

寫一個驅動方法

在Reduce輸出之前呢,將自定義分區,和分組比較的功能加上

 

 

 

top3是三次輸出,但是這個是固定寫死的

初始化和清空資源,通過context去獲取資源,默認設置一個3的參數

方法一:topn的設置,可以動態設置top個數,可以作爲參數進行傳參

 

方法二:如果將上面這個注掉,將xml文件引入進來

context是全局性的,每一個參數都可以拿得到

 

 

初始化清空資源
setup

reduce
reduce
reduce
.....

cleanup

 

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