MapReduce统计每个用户的使用总流量
1、原始数据

2、使用java程序
1)新建项目
2)导包
hadoop-2.7.3\share\hadoop\mapreduce
+hsfs的那些包
+common
3、写项目
1)实体类
注:属性直接定义为String和 Long定义更方便
package com.zy.flow; import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.io.Writable; public class Flow implements Writable{//Writable可序列化的(序列化:把对象变成二进制流 反序列化:把二进制流变成对象)
//包含 电话 上行流量 下行流量 总流量
private Text phone;
private LongWritable upflow;//上行
private LongWritable downflow;//下行
private LongWritable sumflow;//总流量
//这个对象以后要在集群中传输,所以要可序列化 //序列化反序列化顺序要一致
@Override//反序列化时会调用该方法
public void readFields(DataInput in) throws IOException {
phone=new Text(in.readUTF());
upflow=new LongWritable(in.readLong());
downflow=new LongWritable(in.readLong());
sumflow=new LongWritable(in.readLong());
} @Override//序列化时会调用该方法
public void write(DataOutput out) throws IOException {
out.writeUTF(phone.toString());
out.writeLong(upflow.get());
out.writeLong(downflow.get());
out.writeLong(sumflow.get()); }
public Text getPhone() {
return phone;
}
public void setPhone(Text phone) {
this.phone = phone;
}
public LongWritable getUpflow() {
return upflow;
}
public void setUpflow(LongWritable upflow) {
this.upflow = upflow;
}
public LongWritable getDownflow() {
return downflow;
}
public void setDownflow(LongWritable downflow) {
this.downflow = downflow;
}
public LongWritable getSumflow() {
return sumflow;
}
public void setSumflow(LongWritable sumflow) {
this.sumflow = sumflow;
}
public Flow() { }
public Flow(Text phone, LongWritable upflow, LongWritable downflow, LongWritable sumflow) {
super();
this.phone = phone;
this.upflow = upflow;
this.downflow = downflow;
this.sumflow = sumflow;
}
public Flow(LongWritable upflow, LongWritable downflow, LongWritable sumflow) {
super();
this.upflow = upflow;
this.downflow = downflow;
this.sumflow = sumflow;
} @Override//toString最后就是reduce中输出值的样式
public String toString() {
//输出样式
return upflow+"\t"+downflow+"\t"+sumflow;
} }
2)FlowMap类
package com.zy.flow; import java.io.IOException; import javax.security.auth.callback.LanguageCallback; import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class FlowMap extends Mapper<LongWritable, Text, Text, Flow>{ @Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Flow>.Context context)
throws IOException, InterruptedException {
//输入的值 value
//切分value 寻找有价值的列
String[] split = value.toString().split("\t");
int length=split.length;
//取哪几列split[1] split[length-3] split[length-2]
String phone=split[1];
Long upflow=Long.parseLong(split[length-3]);
Long downflow=Long.parseLong(split[length-2]);
Long sumflow=upflow+downflow;
//输出
context.write(new Text(phone), new Flow(new Text(phone), new LongWritable(upflow), new LongWritable(downflow),new LongWritable(sumflow)));
//对象里虽然用不到phone但是要给它赋值,不然序列化时会报空指针异常
}
}
3)Part(分区)类
package com.zy.flow;
import java.util.HashMap;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Partitioner;
// map的输出是suffer的输入
public class Part extends Partitioner<Text, Flow> {//分区
//逻辑自己写 HashMap<String,Integer> map = new HashMap(); public void setMap(){
map.put("135",0);
map.put("136", 1);
map.put("137",2);
map.put("138", 3);
map.put("139",4);
}
// 生成的文件 part-00000 part的编号的结尾就是这个int类型的返回值;
@Override
public int getPartition(Text key, Flow value, int arg2) { setMap();
//从输入的数据中获得电话的前三位跟map对比。决定分到哪个区中
String substring = key.toString().substring(0, 3);//例如截取135 return map.get(substring)==null?5:map.get(substring);//根据键取值 键135 取出0
//其他号码分到(编号为5)第6个区中
}
//在这个逻辑下partition分了6个区,所以以后要指定6个reducetask }
4)FlowReduce类
package com.zy.flow; import java.io.IOException; import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; public class FlowReduce extends Reducer<Text, Flow, Text, Flow>{
@Override
protected void reduce(Text key, Iterable<Flow> value, Reducer<Text, Flow, Text, Flow>.Context context)
throws IOException, InterruptedException {
//累加
long allup=0;
long alldown=0;
for (Flow flow : value) {
allup+=Long.parseLong(flow.getUpflow().toString());//同一个电话的上行流量累加
alldown+=Long.parseLong(flow.getDownflow().toString());//同一个电话的下行流量累加 }
long allsum=allup+alldown;
context.write(key, new Flow(new Text(key), new LongWritable(allup), new LongWritable(alldown), new LongWritable(allsum)));
} }
5)FlowApp类
package com.zy.flow; import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; public class FlowApp { public static void main(String[] args) throws Exception {
//创建配置对象
Configuration configuration = new Configuration();
//得到job实例
Job job = Job.getInstance(configuration);
//指定job运行类
job.setJarByClass(FlowApp.class); //指定job中的mapper
job.setMapperClass(FlowMap.class);
//指定mapper中的输出键和值类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Flow.class); //指定job中的reducer
job.setReducerClass(FlowReduce.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Flow.class); //-----
//指定Partitioner使用的类
job.setPartitionerClass(Part.class);
//指定ReduceTask数量
job.setNumReduceTasks(6);
//----- //指定输入文件
FileInputFormat.setInputPaths(job, new Path(args[0]));//运行时填入参数
//指定输出文件
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//提交作业
job.waitForCompletion(true); } }
4、运行
1)打包



2)上传到linux

3)运行


MapReduce统计每个用户的使用总流量的更多相关文章
- MongoDb 用 mapreduce 统计留存率
MongoDb 用 mapreduce 统计留存率(金庆的专栏)留存的定义采用的是新增账号第X日:某日新增的账号中,在新增日后第X日有登录行为记为留存 输出如下:(类同友盟的留存率显示)留存用户注册时 ...
- 使用 Redis 统计在线用户人数
在构建应用的时候, 我们经常需要对用户的一举一动进行记录, 而其中一个比较重要的操作, 就是对在线的用户进行记录. 本文将介绍四种使用 Redis 对在线用户进行记录的方案, 这些方案虽然都可以对在线 ...
- Hadoop基础-Map端链式编程之MapReduce统计TopN示例
Hadoop基础-Map端链式编程之MapReduce统计TopN示例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.项目需求 对“temp.txt”中的数据进行分析,统计出各 ...
- Tomcat集群下获取memcached缓存对象数量,统计在线用户数据量
项目需要统计在线用户数量,系统部署在集群环境下,使用会话粘贴的方式解决Session问题.要想得到真实在线用户数,必须是所有节点的总和. 这里考虑使用memcached存放用户登录数据,key为use ...
- 用HttpSessionListener统计在线用户或做账号在线人数管理
使用HttpSessionListener接口可监听session的创建和失效 session是在用户第一次访问页面时创建 在session超时或调用request.getSession().inva ...
- 拼多多后台开发面试真题:如何用Redis统计独立用户访问量
众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作3年的开发,稍微优秀一点的,都给到30K的Offer,当然,拼多多加班也是出名的,一周上6天班是常态,每天工作时间基本都是超过1 ...
- 拼多多面试真题:如何用 Redis 统计独立用户访问量!
阅读本文大概需要 2.8 分钟. 作者:沙茶敏碎碎念 众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作 3 年的开发,稍微优秀一点的,都给到 30K 的 Offer. 当然,拼 ...
- 从GoogleClusterData统计每个用户的使用率、平均每次出价
之前将google cluster data导入了Azure上的MySQL数据库,下一步就是对这些数据进行分析, 挖掘用户的使用规律了. 首先,为了加快执行速度,对user,time等加入索引. 然后 ...
- 如何用 Redis 统计独立用户访问量
众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作3年的开发,稍微优秀一点的,都给到30K的Offer,当然,拼多多加班也是出名的,一周上6天班是常态,每天工作时间基本都是超过1 ...
随机推荐
- Windows下使用Graalvm将Javafx应用编译成exe
1 背景 Graalvm是Oracle推出的一款新型虚拟机,其中一个吸引人的功能是:它可以将Java代码编译成各个平台的本地代码,这些平台包括:linux.macOS.windows.iOS.andr ...
- Java基础学习总结笔记
Java基础 Java常用内存区域 栈内存空间:存储引用堆内存空间的地址 堆内存空间:保存每个对象的具体属性内容 全局数据区:保存static类型的属性 全局代码区:保存所有的方法定义 修饰符 权限修 ...
- appium识别工具介绍
- Getshell
GetShell 常用免杀大法 一.编码大法 (1).一句话马子本身采用编码 原文:<?php @eval($_GET(a)):?> 转码后:在提交的post的时候可以直接使用\u0026 ...
- 单元测试:单元测试中的mock
公司要求提升单元测试的质量,提高代码的分支覆盖率和行覆盖率,安排我研究单元测试,指定方案分享并在开发部普及开.整理完资料后,同步一下到博客. 单元测试中的mock的目的 mock的主要目的是让单元测试 ...
- 未使用绑定变量对share_pool的影响
oracle SGA中包含数据高速缓冲,重做日志缓冲,以及共享池(share_pool).共享池中包含库高速缓冲(所有的SQL,执行计划等)和数据字典缓冲(对象的定义,权限等). 所以,如果SQL中没 ...
- STM32F207时钟系统解析
在前几天的文章<晶振原理解析>中介绍了晶振如何产生时钟的,板子使用的是25M无源晶振,下文将介绍STM32F207的时钟系统如何将25M晶振时钟转换为120M系统主频时钟的. 01.时钟系 ...
- redis 主从复制(一主两从)
一.环境基本信息 系统 centos7 版本 redis 5.0.7 只用了一台机器,ip:192.168.64.123 master端口 6379,从机 端口 6380.6381 二.redis目录 ...
- C#从入门到放弃治疗一:初探C#世界
C#是一款高级的面向对象语言,运行于.NET framework之上的高级程序设计语言.其语言规范和,语法和java有着惊人的类似之处.所以如果你在学习C#之前有着java的基础,你将快速地入门.当然 ...
- MySQL 5.6.35 索引优化导致的死锁案例解析
一.背景 随着公司业务的发展,商品库存从商品中心独立出来成为一个独立的系统,承接主站商品库存校验.订单库存扣减.售后库存释放等业务.在上线之前我们对于核心接口进行了压测,压测过程中出现了 MySQL ...