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 ...
随机推荐
- Bigtable:A Distributed Storage System for Strctured Data
2006 年10 月Google 发布三架马车之一的<Bigtable:A Distributed Storage System for Strctured Data>论文之后,Power ...
- jdk8在windows及linux环境下安装
jdk下载 下载地址:https://www.oracle.com/technetwork/java/javase/downloads/index.html 目前大部分公司内部使用的还是jdk8,大部 ...
- Stanford Local 2016 E "Election of Evil"(搜索(正解)或并查集(划掉))
传送门 题意: 给出集合U,V,集合U有n个元素,集合V有m个元素: 有 m 个操作,mi : s1 s2 有一条s1指向s2的边(s1,s2可能属于第三个集合,暂且称之为K集合): 指向边具有传递性 ...
- 时间函数(1):time,ctime,gmtime,localtime
asctime(将时间和日期以字符串格式表示) #include<time.h> 定义函数 char * asctime(const struct tm * timeptr); 函数说明 ...
- JProfiler性能分析工具
1.简介 JProfiler是一个商业授权的Java剖析工具,用于分析Java EE和Java SE应用程序. 2.JVMTI JDK本身定义了目标明确并功能完善的JNI(Java Native In ...
- Dubbo学习笔记8:Dubbo的线程模型与线程池策略
Dubbo默认的底层网络通讯使用的是Netty,服务提供方NettyServer使用两级线程池,其中 EventLoopGroup(boss) 主要用来接受客户端的链接请求,并把接受的请求分发给 Ev ...
- Docker下安装GitLab
1.需要先安装Docker和Docker Compose,参考:https://www.cnblogs.com/hackyo/p/9280042.html 2.配置GitLab SSL(可跳过): m ...
- 利用div绘制细线居中
利用div配合css代码实现细线方式: 块级元素水平居中步骤: 设置宽度width 设置margin-left:auto; 设置margin-right:auto; 实现方法是,让其左右两边的外边距自 ...
- JDK8- interface接口可以写方法体了-- 惊 dt.jar包等
基本上所有的Java教程都会告诉我们Java接口的方法都是public.abstract类型的,没有方法体的. 但是在JDK8里面,你是可以突破这个界限的哦. == 一个类实现某个接口,必须重写接口中 ...
- hiho 1097 最小生成树一·Prim算法 (最小生成树)
题目: 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 最近,小Hi很喜欢玩的一款游戏模拟城市开放出了新Mod,在这个Mod中,玩家可以拥有不止一个城市了! 但是,问 ...