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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值