mapreduce实现流量汇总排序程序
来源:互联网 发布:淘宝挖掘冷门暴利行业 编辑:程序博客网 时间:2024/06/05 13:13
在流量汇总程序开发中已经写好了流量汇总程序(建议先看这篇),利用生成好的汇总过的文件接着来进行按照总流量由高到低排序。
因为maptask的最终生成文件中的数据是已经排序过的,默认就是按照key 归并排序,所以在传给reduce task的时候也就是排序过的。所以我们可以将输出bean作为key,电话号码作为value来输出。既然需要对bean根据总流量来进行排序,那么可以让FlowBean来实现WritableComparable接口而不是Writable接口,重写compareTo方法。
public class FlowBean implements WritableComparable<FlowBean>{ private long upFlow;//上行流量 private long downFlow;//下行流量 private long totalFlow;//总流量 //按照总流量倒序排 public int compareTo(FlowBean bean) { return bean.totalFlow>this.totalFlow?1:-1; } //序列化时需要无参构造方法 public FlowBean() { } public FlowBean(long upFlow, long downFlow) { this.upFlow = upFlow; this.downFlow = downFlow; this.totalFlow = upFlow + downFlow; } public void setFlowBean(long upFlow, long downFlow) { this.upFlow = upFlow; this.downFlow = downFlow; this.totalFlow = upFlow + downFlow; } //序列化方法 hadoop的序列化很简单,要传递的数据写出去即可 public void write(DataOutput out) throws IOException { out.writeLong(upFlow); out.writeLong(downFlow); out.writeLong(totalFlow); } //反序列化方法 注意:反序列化的顺序跟序列化的顺序完全一致 public void readFields(DataInput in) throws IOException { this.upFlow = in.readLong(); this.downFlow = in.readLong(); this.totalFlow = in.readLong(); } //重写toString以便展示 @Override public String toString() { return upFlow + "\t" + downFlow + "\t" + totalFlow; } get,set方法}
public class FlowCountSort { /** * KEYIN:默认情况下,是mr框架所读到的一行文本的起始偏移量,Long,但是在hadoop中有自己的 * 更精简的序列化接口(Seria会将类结构都序列化,而实际我们只需要序列化数据),所以不直接用Long,而用LongWritable * VALUEIN:默认情况下,是mr框架所读到的一行文本的内容,String,同上,用Text * KEYOUT:是用户自定义逻辑处理完成之后输出数据中的key * VALUEOUT:是用户自定义逻辑处理完成之后输出数据中的value * @author 12706 * */ static class FlowCountSortMapper extends Mapper<LongWritable, Text, FlowBean, Text>{ FlowBean flowBean = new FlowBean(); Text text = new Text(); @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String line = value.toString(); String[] infos = line.split("\t"); //获取手机号 String phoneNum = infos[0]; //获取上行流量,下行流量 String upFlow = infos[1]; String downFlow = infos[2]; //设置总流量 text.set(phoneNum); flowBean.setFlowBean(new Long(upFlow), new Long(downFlow)); //根据key进行了排序,所以需要FlowBean实现WritableComparable接口 context.write(flowBean, text); } } /** * KEYIN VALUEIN对应mapper输出的KEYOUT KEYOUT类型对应 * KEYOUT,VALUEOUT:是自定义reduce逻辑处理结果的输出数据类型 * KEYOUT * VALUEOUT * @author 12706 * */ static class FlowCountSortReducer extends Reducer<FlowBean, Text, Text, FlowBean>{ @Override protected void reduce(FlowBean key, Iterable<Text> values, Context context) throws IOException, InterruptedException { //直接写出去 context.write(values.iterator().next(), key); } } /** * 相当于一个yarn集群的客户端 * 需要在此封装mr程序的相关运行参数,指定jar包 * 最后提交给yarn * @author 12706 * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf); job.setJarByClass(FlowCountSort.class); //指定本业务job要使用的mapper,reducer业务类 job.setMapperClass(FlowCountSortMapper.class); job.setReducerClass(FlowCountSortReducer.class); //虽然指定了泛型,以防框架使用第三方的类型 //指定mapper输出数据的kv类型 job.setMapOutputKeyClass(FlowBean.class); job.setMapOutputValueClass(Text.class); //指定最终输出的数据的kv类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(FlowBean.class); //指定job输入原始文件所在位置 FileInputFormat.setInputPaths(job, new Path(args[0])); //指定job输入原始文件所在位置 FileOutputFormat.setOutputPath(job,new Path(args[1])); //将job中配置的相关参数以及job所用的java类所在的jar包,提交给yarn去运行 boolean b = job.waitForCompletion(true); System.exit(b?0:1); }}
测试:
将工程打成jar包(flowcount.jar)上传到linux,启动hadoop集群。
在/flowcount/output下有汇总过的文件
[root@mini2 ~]# hadoop fs -cat /flowcount/output/part-r-0000013480253104 180 180 36013502468823 7335 110349 11768413560436666 1116 954 207013560439658 2034 5892 792613602846565 1938 2910 484813660577991 6960 690 765013719199419 240 0 24013726230503 2481 24681 2716213726238888 2481 24681 2716213760778710 120 120 24013826544101 264 0 26413922314466 3008 3720 672813925057413 11058 48243 5930113926251106 240 0 24013926435656 132 1512 164415013685858 3659 3538 719715920133257 3156 2936 609215989002119 1938 180 211818211575961 1527 2106 363318320173382 9531 2412 1194384138413 4116 1432 5548
[root@mini2 ~]# hadoop jar flowcount.jar com.scu.hadoop.mr.FlowCountSort /flowcount/output /flowcount/sortoutput...[root@mini2 ~]# hadoop fs -ls /flowcount/sortoutputFound 2 items-rw-r--r-- 2 root supergroup 0 2017-10-13 04:45 /flowcount/sortoutput/_SUCCESS-rw-r--r-- 2 root supergroup 551 2017-10-13 04:45 /flowcount/sortoutput/part-r-00000[root@mini2 ~]# hadoop fs -cat /flowcount/sortoutput/part-r-0000013502468823 7335 110349 11768413925057413 11058 48243 5930113726230503 2481 24681 2716213726238888 2481 24681 2716218320173382 9531 2412 1194313560439658 2034 5892 792613660577991 6960 690 765015013685858 3659 3538 719713922314466 3008 3720 672815920133257 3156 2936 609284138413 4116 1432 554813602846565 1938 2910 484818211575961 1527 2106 363315989002119 1938 180 211813560436666 1116 954 207013926435656 132 1512 164413480253104 180 180 36013826544101 264 0 26413719199419 240 0 24013760778710 120 120 24013926251106 240 0 240
输出文件/flowcount/sortoutput/part-r-00000中看到了记录就是按照总流量由高到低排序。
阅读全文
0 0
- mapreduce实现流量汇总排序程序
- mapreduce流量汇总程序
- 使用mapreduce进行流量汇总程序开发
- Mapreduce实例---流量汇总并按流量大小倒序排序
- mapreduce程序实现排序
- 流量汇总mapreduce
- 分区汇总流量MapReduce
- Mapreduce实例---分区流量汇总
- mapreduce的任务切片规划机制、job提交流程、Mapreduce中的分区Partitioner与流量汇总程序开发
- Mapreduce实例---流量汇总(自定义类)
- 第二个MapReduce程序----flowcount(流量统计,自定义排序,自定义分区)
- mapreduce(JAVA)实现(大数据)电话号码对应的流量排序(倒序)
- 编写mapreduce统计数据流量的小程序
- MapReduce排序程序
- Hadoop MapReduce排序程序
- MapReduce实现手机上网流量统计
- mapreduce实现简单的流量统计功能
- mapreduce对日志数据上下行流量汇总
- [LeetCode-Algorithms-26] "Remove Duplicates from Sorted Array" (2017.10.12-WEEK6)
- AngularJS基础练习(2)
- java复习(一)
- Mybatis学习笔记-关联表查询的问题
- 深入理解JVM之垃圾收集器与内存分配策略
- mapreduce实现流量汇总排序程序
- python_>>_<<
- 【USACO月赛】贪心
- 插入排序
- axios发送post请求后台接受不到问题
- css3
- Unable to locate any of the following operational binaries 解决方法
- unity_NGUI系统学习(十四)_游戏界面滑动切换的效果实现(无代码实现)
- HTML元素——语义相关元素