流量统计项目案例

样本示例

需求

1、 统计每一个用户(手机号)所耗费的总上行流量、总下行流量,总流量

2、 得出上题结果的基础之上再加一个需求:将统计结果按照总流量倒序排序

3、 将流量汇总统计结果按照手机归属地不同省份输出到不同文件中

第一题

  1. import java.io.IOException;
  2.  
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.fs.Path;
  5. import org.apache.hadoop.io.LongWritable;
  6. import org.apache.hadoop.io.Text;
  7. import org.apache.hadoop.mapreduce.Job;
  8. import org.apache.hadoop.mapreduce.Mapper;
  9. import org.apache.hadoop.mapreduce.Reducer;
  10. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  11. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  12.  
  13. /**
  14. * 第一题:统计每一个用户(手机号)所耗费的总上行流量、总下行流量,总流量
  15. */
  16.  
  17. public class FlowSumMR {
  18.  
  19. public static void main(String[] args) throws Exception {
  20.  
  21. Configuration conf = new Configuration();
  22. Job job = Job.getInstance(conf, "FlowSumMR");
  23. job.setJarByClass(FlowSumMR.class);
  24.  
  25. job.setMapperClass(FlowSumMRMapper.class);
  26. job.setReducerClass(FlowSumMRReducer.class);
  27.  
  28. job.setOutputKeyClass(Text.class);
  29. job.setOutputValueClass(Text.class);
  30.  
  31. FileInputFormat.setInputPaths(job, new Path("E:/bigdata/flow/input/"));
  32. FileOutputFormat.setOutputPath(job, new Path("E:/bigdata/flow/output_sum"));
  33.  
  34. boolean isDone = job.waitForCompletion(true);
  35. System.exit(isDone ? 0 : 1);
  36. }
  37.  
  38. public static class FlowSumMRMapper extends Mapper<LongWritable, Text, Text, Text>{
  39.  
  40. /**
  41. * value = 1363157993044 18211575961 94-71-AC-CD-E6-18:CMCC-EASY 120.196.100.99
  42. * iface.qiyi.com 视频网站 15 12 1527 2106 200
  43. */
  44. @Override
  45. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  46.  
  47. String[] split = value.toString().split("\t");
  48.  
  49. String outkey = split[1];
  50.  
  51. String outValue = split[8] + "\t" + split[9];
  52.  
  53. context.write(new Text(outkey), new Text(outValue));
  54.  
  55. }
  56. }
  57.  
  58. public static class FlowSumMRReducer extends Reducer<Text, Text, Text, Text>{
  59.  
  60. @Override
  61. protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
  62.  
  63. int upFlow = 0;
  64. int downFlow = 0;
  65. int sumFlow = 0;
  66.  
  67. for(Text t : values){
  68. String[] split = t.toString().split("\t");
  69.  
  70. int upTempFlow = Integer.parseInt(split[0]);
  71. int downTempFlow = Integer.parseInt(split[1]);
  72.  
  73. upFlow+=upTempFlow;
  74. downFlow += downTempFlow;
  75. }
  76.  
  77. sumFlow = upFlow + downFlow;
  78.  
  79. context.write(key, new Text(upFlow + "\t" + downFlow + "\t" + sumFlow));
  80. }
  81. }
  82. }

第二题

  1. import java.io.IOException;
  2.  
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.fs.Path;
  5. import org.apache.hadoop.io.LongWritable;
  6. import org.apache.hadoop.io.NullWritable;
  7. import org.apache.hadoop.io.Text;
  8. import org.apache.hadoop.mapreduce.Job;
  9. import org.apache.hadoop.mapreduce.Mapper;
  10. import org.apache.hadoop.mapreduce.Reducer;
  11. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  12. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  13.  
  14. import comg.ghgj.mr.pojo.FlowBean;
  15.  
  16. /**
  17. * 需求: 第二个题目,就是对第一个题目的结果数据,进行按照总流量倒叙排序
  18. *
  19. *
  20. */
  21. public class FlowSortMR {
  22.  
  23. public static void main(String[] args) throws Exception {
  24.  
  25. Configuration conf = new Configuration();
  26. Job job = Job.getInstance(conf, "FlowSumMR");
  27. job.setJarByClass(FlowSortMR.class);
  28.  
  29. job.setMapperClass(FlowSortMRMapper.class);
  30. job.setReducerClass(FlowSortMRReducer.class);
  31.  
  32. job.setOutputKeyClass(FlowBean.class);
  33. job.setOutputValueClass(NullWritable.class);
  34.  
  35. FileInputFormat.setInputPaths(job, new Path("E:/bigdata/flow/output_sum"));
  36. FileOutputFormat.setOutputPath(job, new Path("E:/bigdata/flow/output_sort_777"));
  37.  
  38. boolean isDone = job.waitForCompletion(true);
  39. System.exit(isDone ? 0 : 1);
  40.  
  41. }
  42.  
  43. public static class FlowSortMRMapper extends Mapper<LongWritable, Text, FlowBean, NullWritable>{
  44.  
  45. /**
  46. * value = 13602846565 26860680 40332600 67193280
  47. */
  48. @Override
  49. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  50.  
  51. String[] split = value.toString().split("\t");
  52.  
  53. FlowBean fb = new FlowBean(split[0], Long.parseLong(split[1]), Long.parseLong(split[2]));
  54.  
  55. context.write(fb, NullWritable.get());
  56. }
  57.  
  58. }
  59.  
  60. public static class FlowSortMRReducer extends Reducer<FlowBean, NullWritable, FlowBean, NullWritable>{
  61.  
  62. @Override
  63. protected void reduce(FlowBean key, Iterable<NullWritable> values, Context context)
  64. throws IOException, InterruptedException {
  65.  
  66. for(NullWritable nvl : values){
  67. context.write(key, nvl);
  68. }
  69.  
  70. }
  71.  
  72. }
  73. }

FlowBean.java

  1. import java.io.DataInput;
  2. import java.io.DataOutput;
  3. import java.io.IOException;
  4.  
  5. import org.apache.hadoop.io.WritableComparable;
  6.  
  7. /**
  8. * 第一,定义好属性
  9. * 第二,定义好属性的getter 和 setter方法
  10. * 第三,定义好构造方法(有参,无参)
  11. * 第四:定义好toString();
  12. *
  13. *
  14. * 详细解释:
  15. *
  16. * 如果一个自定义对象要作为key 必须要实现 WritableComparable 接口, 而不能实现 Writable, Comparable
  17. *
  18. * 如果一个自定义对象要作为value,那么只需要实现Writable接口即可
  19. */
  20. public class FlowBean implements WritableComparable<FlowBean>{
  21. //public class FlowBean implements Comparable<FlowBean>{
  22.  
  23. private String phone;
  24. private long upFlow;
  25. private long downFlow;
  26. private long sumFlow;
  27. public String getPhone() {
  28. return phone;
  29. }
  30. public void setPhone(String phone) {
  31. this.phone = phone;
  32. }
  33. public long getUpFlow() {
  34. return upFlow;
  35. }
  36. public void setUpFlow(long upFlow) {
  37. this.upFlow = upFlow;
  38. }
  39. public long getDownFlow() {
  40. return downFlow;
  41. }
  42. public void setDownFlow(long downFlow) {
  43. this.downFlow = downFlow;
  44. }
  45. public long getSumFlow() {
  46. return sumFlow;
  47. }
  48. public void setSumFlow(long sumFlow) {
  49. this.sumFlow = sumFlow;
  50. }
  51. public FlowBean(String phone, long upFlow, long downFlow, long sumFlow) {
  52. super();
  53. this.phone = phone;
  54. this.upFlow = upFlow;
  55. this.downFlow = downFlow;
  56. this.sumFlow = sumFlow;
  57. }
  58. public FlowBean(String phone, long upFlow, long downFlow) {
  59. super();
  60. this.phone = phone;
  61. this.upFlow = upFlow;
  62. this.downFlow = downFlow;
  63. this.sumFlow = upFlow + downFlow;
  64. }
  65. public FlowBean() {
  66. super();
  67. // TODO Auto-generated constructor stub
  68. }
  69. @Override
  70. public String toString() {
  71. return phone + "\t" + upFlow + "\t" + downFlow + "\t" + sumFlow;
  72. }
  73.  
  74. /**
  75. * 把当前这个对象 --- 谁掉用这个write方法,谁就是当前对象
  76. *
  77. * FlowBean bean = new FlowBean();
  78. *
  79. * bean.write(out) 把bean这个对象的四个属性序列化出去
  80. *
  81. * this = bean
  82. */
  83. @Override
  84. public void write(DataOutput out) throws IOException {
  85. // TODO Auto-generated method stub
  86.  
  87. out.writeUTF(phone);
  88. out.writeLong(upFlow);
  89. out.writeLong(downFlow);
  90. out.writeLong(sumFlow);
  91.  
  92. }
  93.  
  94. // 序列化方法中的写出的字段顺序, 一定一定一定要和 反序列化中的 接收顺序一致。 类型也一定要一致
  95.  
  96. /**
  97. * bean.readField();
  98. *
  99. * upFlow =
  100. */
  101. @Override
  102. public void readFields(DataInput in) throws IOException {
  103. // TODO Auto-generated method stub
  104.  
  105. phone = in.readUTF();
  106. upFlow = in.readLong();
  107. downFlow = in.readLong();
  108. sumFlow = in.readLong();
  109.  
  110. }
  111.  
  112. /**
  113. * Hadoop的序列化机制为什么不用 java自带的实现 Serializable这种方式?
  114. *
  115. * 本身Hadoop就是用来解决大数据问题的。
  116. *
  117. * 那么实现Serializable接口这种方式,在进行序列化的时候。除了会序列化属性值之外,还会携带很多跟当前这个对象的类相关的各种信息
  118. *
  119. * Hadoop采取了一种全新的序列化机制;只需要序列化 每个对象的属性值即可。
  120. */
  121.  
  122. /*@Override
  123. public void readFields(DataInput in) throws IOException {
  124. value = in.readLong();
  125. }
  126.  
  127. @Override
  128. public void write(DataOutput out) throws IOException {
  129. out.writeLong(value);
  130. }*/
  131.  
  132. /**
  133. * 用来指定排序规则
  134. */
  135. @Override
  136. public int compareTo(FlowBean fb) {
  137.  
  138. long diff = this.getSumFlow() - fb.getSumFlow();
  139.  
  140. if(diff == 0){
  141. return 0;
  142. }else{
  143. return diff > 0 ? -1 : 1;
  144. }
  145.  
  146. }
  147. }

第三题

  1. package comg.ghgj.mr.flow;
  2.  
  3. import java.io.IOException;
  4.  
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.FileSystem;
  7. import org.apache.hadoop.fs.Path;
  8. import org.apache.hadoop.io.LongWritable;
  9. import org.apache.hadoop.io.Text;
  10. import org.apache.hadoop.mapreduce.Job;
  11. import org.apache.hadoop.mapreduce.Mapper;
  12. import org.apache.hadoop.mapreduce.Reducer;
  13. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  14. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  15. import org.apache.hadoop.mapreduce.lib.partition.ProvincePartitioner;
  16.  
  17. public class FlowPartitionerMR {
  18.  
  19. public static void main(String[] args) throws Exception {
  20.  
  21. Configuration conf = new Configuration();
  22. FileSystem fs = FileSystem.get(conf);
  23. Job job = Job.getInstance(conf, "FlowSumMR");
  24. job.setJarByClass(FlowPartitionerMR.class);
  25.  
  26. job.setMapperClass(FlowPartitionerMRMapper.class);
  27. job.setReducerClass(FlowPartitionerMRReducer.class);
  28. job.setOutputKeyClass(Text.class);
  29. job.setOutputValueClass(Text.class);
  30.  
  31. /**
  32. * 非常重要的两句代码
  33. */
  34. job.setPartitionerClass(ProvincePartitioner.class);
  35. job.setNumReduceTasks(10);
  36.  
  37. FileInputFormat.setInputPaths(job, new Path("E:\\bigdata\\flow\\input"));
  38. Path outputPath = new Path("E:\\bigdata\\flow\\output_ptn2");
  39. if(fs.exists(outputPath)){
  40. fs.delete(outputPath, true);
  41. }
  42. FileOutputFormat.setOutputPath(job, outputPath);
  43.  
  44. boolean isDone = job.waitForCompletion(true);
  45. System.exit(isDone ? 0 : 1);
  46. }
  47.  
  48. public static class FlowPartitionerMRMapper extends Mapper<LongWritable, Text, Text, Text>{
  49.  
  50. /**
  51. * value = 13502468823 101663100 1529437140 1631100240
  52. */
  53. @Override
  54. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  55.  
  56. String[] split = value.toString().split("\t");
  57.  
  58. String outkey = split[1];
  59. String outValue = split[8] + "\t" + split[9];
  60.  
  61. context.write(new Text(outkey), new Text(outValue));
  62.  
  63. }
  64. }
  65.  
  66. public static class FlowPartitionerMRReducer extends Reducer<Text, Text, Text, Text>{
  67.  
  68. @Override
  69. protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
  70.  
  71. int upFlow = 0;
  72. int downFlow = 0;
  73. int sumFlow = 0;
  74.  
  75. for(Text t : values){
  76. String[] split = t.toString().split("\t");
  77.  
  78. int upTempFlow = Integer.parseInt(split[0]);
  79. int downTempFlow = Integer.parseInt(split[1]);
  80.  
  81. upFlow+=upTempFlow;
  82. downFlow += downTempFlow;
  83. }
  84.  
  85. sumFlow = upFlow + downFlow;
  86.  
  87. context.write(key, new Text(upFlow + "\t" + downFlow + "\t" + sumFlow));
  88. }
  89. }
  90. }

Hadoop学习之路(十九)MapReduce框架排序的更多相关文章

  1. Hadoop 学习笔记 (十) MapReduce实现排序 全局变量

    一些疑问:1 全排序的话,最后的应该sortJob.setNumReduceTasks(1);2 如果多个reduce task都去修改 一个静态的 IntWritable ,IntWritable会 ...

  2. Hadoop学习之路(九)HDFS深入理解

    HDFS的优点和缺点 HDFS的优点 1.可构建在廉价机器上 通过多副本提高可靠性,提供了容错和恢复机制 服务器节点的宕机是常态   必须理性对象 2.高容错性 数据自动保存多个副本,副本丢失后,自动 ...

  3. 嵌入式Linux驱动学习之路(十九)触摸屏驱动、tslib测试

    触摸屏使用流程: 1. 按下产生中断. 2.在中断处理程序中启动AD转换XY坐标. 3.AD转换结束并产生AD中断. 4. 在AD的中断处理函数中上报信息,启动定时器. 5. 定时器时间到后进入中断, ...

  4. IOS学习之路十九(JSON与Arrays 或者 Dictionaries相互转换)

    今天写了个json与Arrays 或者 Dictionaries相互转换的例子很简单: 通过 NSJSONSerialization 这个类的 dataWithJSONObject: options: ...

  5. salesforce零基础学习(七十九)简单排序浅谈 篇一

    我们在程序中经常需要对数据列表进行排序,有时候使用SOQL的order by 不一定能完全符合需求,需要对数据进行排序,排序可以有多种方式,不同的方式针对不同的场景.篇一只是简单的描述一下选择排序,插 ...

  6. 阿里封神谈hadoop学习之路

    阿里封神谈hadoop学习之路   封神 2016-04-14 16:03:51 浏览3283 评论3 发表于: 阿里云E-MapReduce >> 开源大数据周刊 hadoop 学生 s ...

  7. 《Hadoop学习之路》学习实践

    (实践机器:blog-bench) 本文用作博文<Hadoop学习之路>实践过程中遇到的问题记录. 本文所学习的博文为博主“扎心了,老铁” 博文记录.参考链接https://www.cnb ...

  8. Hadoop学习之路(十五)MapReduce的多Job串联和全局计数器

    MapReduce 多 Job 串联 需求 一个稍复杂点的处理逻辑往往需要多个 MapReduce 程序串联处理,多 job 的串联可以借助 MapReduce 框架的 JobControl 实现 实 ...

  9. Hadoop学习之路(二十)MapReduce求TopN

    前言 在Hadoop中,排序是MapReduce的灵魂,MapTask和ReduceTask均会对数据按Key排序,这个操作是MR框架的默认行为,不管你的业务逻辑上是否需要这一操作. 技术点 MapR ...

  10. Hadoop 学习之路(三)—— 分布式计算框架 MapReduce

    一.MapReduce概述 Hadoop MapReduce是一个分布式计算框架,用于编写批处理应用程序.编写好的程序可以提交到Hadoop集群上用于并行处理大规模的数据集. MapReduce作业通 ...

随机推荐

  1. Winform截图小程序

    今天闲时做的一个Demo,做得并不好,只是实现了最基本的截图功能 主要的思路就是 先打开一个主窗体,点击"截图按钮" 会出现一个半透明的小窗体(可以拉伸放大缩小) 然后利用Grap ...

  2. Spring Boot学习笔记(三)实现热部署

    pom文件中添加如下依赖即可 <dependency> <groupId>org.springframework.boot</groupId> <artifa ...

  3. java 通用对象排序

    一个排序类,一个排序util? no.no.no…… 使用反射机制,写了一个通用的对象排序util,欢迎指正. 实体类: package entity; public class BaseTypeEn ...

  4. spss C# 二次开发 学习笔记(三)——Spss .Net 开发

    Spss .Net 二次开发的学习过程暂停了一段时间,今天开始重启. 之前脑残的不得了,本想从网上下载一个Spss的安装包,然后安装学习.于是百度搜索Spss,在百度搜索框的列表中看到Spss17.S ...

  5. eclipse中编写运行c/c++

    注意:此过程有点复杂 准备:1.MinGW:c/c++运行环境: 2.CDT 1.MinGW:安装程序:http://sourceforge.net/projects/mingw/?source=ty ...

  6. PHP 经典算法

    <?  //--------------------  // 基本数据结构算法 //--------------------  //二分查找(数组里查找某个元素)  function bin_s ...

  7. BZOJ P1212 [HNOI2004] L语言

    标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的集合. 我 ...

  8. 13 Reasons Why You Should Pay Attention to Mobile Web Performance

    Mobile is no longer on the sidelines. If you’re not already thinking mobile first, you should at lea ...

  9. 【数据库】10.0 MySQL常用语句(一)

    显示数据库语句: SHOW DATABASES    只是显示数据库的名字 显示数据库创建语句: SHOW CREATE DATABASE db_name 数据库删除语句: DROP DATABASE ...

  10. 四元数(Quaternion)和旋转 +欧拉角

    四元数介绍 旋转,应该是三种坐标变换--缩放.旋转和平移,中最复杂的一种了.大家应该都听过,有一种旋转的表示方法叫四元数.按照我们的习惯,我们更加熟悉的是另外两种旋转的表示方法--矩阵旋转和欧拉旋转. ...