流量統計
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