Mapreduce的序列化和流量统计程序开发
一、Hadoop数据序列化的数据类型
Java数据类型 => Hadoop数据类型
int IntWritable
float FloatWritable
long LongWritable
double DoubleWritable
String Text
boolean BooleanWritable
byte ByteWritable
map MapWritable
array ArrayWritable
二、Hadoop的序列化
1.什么是序列化?
在java中,序列化接口是Serializable,它下面又实现了很多的序列化接口,所以java的序列化是一个重量级的序列化框架,一个对象被java序列化之后会附带很多额外的信息(校验信息、header、继承体系等),不便于在网络中进行高效的传输,所以Hadoop开发了一套自己的序列化框架——Writable。
序列化就是把内存当中的对象,转化为字节序列以便于存储和网络传输;
反序列化是将收到的字节序列或硬盘当中的持续化数据,转换成内存中的对象。
2.序列化的理解方法(自己悟的,不对勿喷~~)
比如下面流量统计案例中,流量的封装类FlowBean实现了Writable接口,其中定义了变量upFlow、dwFlow、flowSum;
在Mapper和Reducer类中初始化封装类FlowBean时,内存会分配空间加载这些对象,而这些对象不便于在网络中高效的传输,这是封装类FlowBean中的序列化方法将这些对象转换为字节序列,方便了存储和传输;
当Mapper或Reducer需要将这些对象的字节序列写出到磁盘时,封装类FlowBean中的反序列化方法将字节序列转换为对象,然后写道磁盘中。
3.序列化特点
序列化与反序列化时分布式数据处理当中经常会出现的,比如hadoop通信是通过远程调用(rpc)实现的,这个过程就需要序列化。
特点:1)紧凑;
2)快速
3)可扩展
4)可互操作
三、Mapreduce的流量统计程序案例
1.代码
/**
* @author: PrincessHug
* @date: 2019/3/23, 23:38
* @Blog: https://www.cnblogs.com/HelloBigTable/
*/
public class FlowBean implements Writable {
private long upFlow;
private long dwFlow;
private long flowSum; public long getUpFlow() {
return upFlow;
} public void setUpFlow(long upFlow) {
this.upFlow = upFlow;
} public long getDwFlow() {
return dwFlow;
} public void setDwFlow(long dwFlow) {
this.dwFlow = dwFlow;
} public long getFlowSum() {
return flowSum;
} public void setFlowSum(long flowSum) {
this.flowSum = flowSum;
} public FlowBean() {
} public FlowBean(long upFlow, long dwFlow) {
this.upFlow = upFlow;
this.dwFlow = dwFlow;
this.flowSum = upFlow + dwFlow;
} /**
* 序列化
* @param out 输出流
* @throws IOException
*/
@Override
public void write(DataOutput out) throws IOException {
out.writeLong(upFlow);
out.writeLong(dwFlow);
out.writeLong(flowSum);
} /**
* 反序列化
* @param in
* @throws IOException
*/
@Override
public void readFields(DataInput in) throws IOException {
upFlow = in.readLong();
dwFlow = in.readLong();
flowSum = in.readLong();
} @Override
public String toString() {
return upFlow + "\t" + dwFlow + "\t" + flowSum;
}
} public class FlowCountMapper extends Mapper<LongWritable, Text,Text,FlowBean> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//获取数据
String line = value.toString(); //切分数据
String[] fields = line.split("\t"); //封装数据
String phoneNum = fields[1];
long upFlow = Long.parseLong(fields[fields.length - 3]);
long dwFlow = Long.parseLong(fields[fields.length - 2]); //发送数据
context.write(new Text(phoneNum),new FlowBean(upFlow,dwFlow));
}
} public class FlowCountReducer extends Reducer<Text,FlowBean,Text,FlowBean> {
@Override
protected void reduce(Text key, Iterable<FlowBean> values, Context context) throws IOException, InterruptedException {
//聚合数据
long upFlow_sum = 0;
long dwFlow_sum = 0;
for (FlowBean f:values){
upFlow_sum += f.getUpFlow();
dwFlow_sum += f.getDwFlow();
}
//发送数据
context.write(key,new FlowBean(upFlow_sum,dwFlow_sum));
}
} public class FlowPartitioner extends Partitioner<Text,FlowBean> {
@Override
public int getPartition(Text key, FlowBean value, int i) {
//获取用来分区的电话号码前三位
String phoneNum = key.toString().substring(0, 3);
//设置分区逻辑
int partitionNum = 4;
if ("135".equals(phoneNum)){
return 0;
}else if ("137".equals(phoneNum)){
return 1;
}else if ("138".equals(phoneNum)){
return 2;
}else if ("139".equals(phoneNum)){
return 3;
}
return partitionNum;
}
}
public class FlowCountDriver {
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//获取配置,定义工具
Configuration conf = new Configuration();
Job job = Job.getInstance(); //设置运行类
job.setJarByClass(FlowCountDriver.class); //设置Mapper类及Mapper输出数据类型
job.setMapperClass(FlowCountMapper.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(FlowBean.class); //设置Reducer类及其输出数据类型
job.setReducerClass(FlowCountReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(FlowBean.class); //设置自定义分区
job.setPartitionerClass(FlowPartitioner.class);
job.setNumReduceTasks(5); //设置文件输入输出流
FileInputFormat.setInputPaths(job,new Path("G:\\mapreduce\\flow\\in"));
FileOutputFormat.setOutputPath(job,new Path("G:\\mapreduce\\flow\\inpartitionout")); //返回运行完成
if (job.waitForCompletion(true)){
System.out.println("运行完毕!");
}else {
System.out.println("运行出错!");
}
}
}
Mapreduce的序列化和流量统计程序开发的更多相关文章
- 1 weekend110的复习 + hadoop中的序列化机制 + 流量求和mr程序开发
以上是,weekend110的yarn的job提交流程源码分析的复习总结 下面呢,来讲weekend110的hadoop中的序列化机制 1363157985066 13726230503 ...
- spark之scala程序开发(集群运行模式):单词出现次数统计
准备工作: 将运行Scala-Eclipse的机器节点(CloudDeskTop)内存调整至4G,因为需要在该节点上跑本地(local)Spark程序,本地Spark程序会启动Worker进程耗用大量 ...
- CodeIgniter框架开发的统计程序源代码开放
文章来源: PHP开发学习门户 自己初学php时,用CodeIgniter框架开发的后台统计程序源代码 程序部分页面如图: 具体配置及下载源代码:http://bbs.phpthinking.com/ ...
- 基于HBase Hadoop 分布式集群环境下的MapReduce程序开发
HBase分布式集群环境搭建成功后,连续4.5天实验客户端Map/Reduce程序开发,这方面的代码网上多得是,写个测试代码非常容易,可是真正运行起来可说是历经挫折.下面就是我最终调通并让程序在集群上 ...
- mpvue 小程序开发之 数据埋点统计
mpvue 小程序开发之 数据埋点统计 在开发过程中,有数据统计的需求,需要获取小程序当前页面和来源页面的数据,以及页面的停留时间 在对小程序api进行了一番研究之后,发现获取这些数据其实并不难 当前 ...
- 【Cloud Computing】Hadoop环境安装、基本命令及MapReduce字数统计程序
[Cloud Computing]Hadoop环境安装.基本命令及MapReduce字数统计程序 1.虚拟机准备 1.1 模板机器配置 1.1.1 主机配置 IP地址:在学校校园网Wifi下连接下 V ...
- Android开发——流量统计
1. 获取应用UID 在设备的proc目录下我们可以看到一些比较熟悉的目录/文件,比如data,system,cpuinfo(获取CPU信息)等,其中uid_stat的各个以应用Uid命名的目录下,便 ...
- Hadoop_17_MapRduce_案例2_实现用户手机流量统计(ReduceTask并行度控制)
需求:1.统计每一个用户(手机号)所耗费的总上行流量.下行流量,总流量 1.数据如下:保存为.dat文件(因为以\t切分数据,文件格式必须合适) 1363157985066 13726230503 0 ...
- 零基础入门微信小程序开发
注:本文来源于:<零基础入门微信小程序开发> 课程介绍 本达人课是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件.页面样式文件.Ja ...
随机推荐
- 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)
[HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...
- docker-跨主机存储
容器分类 从业务数据的角度看,容器可以分为两类:无状态(stateless)容器和有状态(stateful)容器. 无状态是指容器在运行过程中不需要保存数据,每次访问的结果不依赖上一次访问,比如提供静 ...
- Python【第五篇】模块、包、常用模块
一.模块(Module) 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文 ...
- virtual-dom
virtual-dom的历史 react最早研究virtual-dom,后来react火了之后,大家纷纷研究react的高性能实现,出现了2个流派,一是研究react算法的算法派,(virtual-d ...
- django系列5:视图
在Django中,网页和其他内容由视图提供.每个视图都由一个简单的Python函数(或基于类的视图的方法)表示.Django将通过检查所请求的URL(确切地说,是域名后面的URL部分)来选择视图. 在 ...
- 关于Java____________Object类
一说Java 不聊聊Object 如何说你了解Java 不多说 具体看源码去 下面是Object的方法 以及方法的作用如下 protected Object clone () ...
- js的几大重点
闭包,:作用域(函数创建),上下文环境(函数执行,会销毁) 匿名函数,:没有函数名的函数,function(){} 自执行函数,:立即调用的匿名函数,(function(){})() 原型链,:继承的 ...
- 深入浅出mybatis之启动详解
深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...
- How to learn PDE (怎么学偏微分方程)
To learn PDE, you need some knowledge of physics (to build up the intuition), solid training of anal ...
- Collections.unmodifiableMap(Map map)
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)返回指定映射 ...