一、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. 1 weekend110的复习 + hadoop中的序列化机制 + 流量求和mr程序开发

    以上是,weekend110的yarn的job提交流程源码分析的复习总结 下面呢,来讲weekend110的hadoop中的序列化机制 1363157985066      13726230503  ...

  2. spark之scala程序开发(集群运行模式):单词出现次数统计

    准备工作: 将运行Scala-Eclipse的机器节点(CloudDeskTop)内存调整至4G,因为需要在该节点上跑本地(local)Spark程序,本地Spark程序会启动Worker进程耗用大量 ...

  3. CodeIgniter框架开发的统计程序源代码开放

    文章来源: PHP开发学习门户 自己初学php时,用CodeIgniter框架开发的后台统计程序源代码 程序部分页面如图: 具体配置及下载源代码:http://bbs.phpthinking.com/ ...

  4. 基于HBase Hadoop 分布式集群环境下的MapReduce程序开发

    HBase分布式集群环境搭建成功后,连续4.5天实验客户端Map/Reduce程序开发,这方面的代码网上多得是,写个测试代码非常容易,可是真正运行起来可说是历经挫折.下面就是我最终调通并让程序在集群上 ...

  5. mpvue 小程序开发之 数据埋点统计

    mpvue 小程序开发之 数据埋点统计 在开发过程中,有数据统计的需求,需要获取小程序当前页面和来源页面的数据,以及页面的停留时间 在对小程序api进行了一番研究之后,发现获取这些数据其实并不难 当前 ...

  6. 【Cloud Computing】Hadoop环境安装、基本命令及MapReduce字数统计程序

    [Cloud Computing]Hadoop环境安装.基本命令及MapReduce字数统计程序 1.虚拟机准备 1.1 模板机器配置 1.1.1 主机配置 IP地址:在学校校园网Wifi下连接下 V ...

  7. Android开发——流量统计

    1. 获取应用UID 在设备的proc目录下我们可以看到一些比较熟悉的目录/文件,比如data,system,cpuinfo(获取CPU信息)等,其中uid_stat的各个以应用Uid命名的目录下,便 ...

  8. Hadoop_17_MapRduce_案例2_实现用户手机流量统计(ReduceTask并行度控制)

    需求:1.统计每一个用户(手机号)所耗费的总上行流量.下行流量,总流量 1.数据如下:保存为.dat文件(因为以\t切分数据,文件格式必须合适) 1363157985066 13726230503 0 ...

  9. 零基础入门微信小程序开发

    注:本文来源于:<零基础入门微信小程序开发> 课程介绍 本达人课是一个系列入门教程,目标是从 0 开始带领读者上手实战,课程以微信小程序的核心概念作为主线,介绍配置文件.页面样式文件.Ja ...

随机推荐

  1. node安装express-generator脚手架

    参考网址:https://www.jianshu.com/p/b555ba6f4067 全局安装: npm install express-generator -g 创建项目pro_test expr ...

  2. 机器学习 - 正则化L1 L2

    L1 L2 Regularization 表示方式: $L_2\text{ regularization term} = ||\boldsymbol w||_2^2 = {w_1^2 + w_2^2 ...

  3. Docker:网络及数据卷设置 [四]

    一.Docker网络设置 默认情况下,docker会创建一个桥接网卡[docker 0],docker有2种映射方式,一种是随机映射,一种是指定映射 提示:生产场景一般不使用随机映射,但是随机映射的好 ...

  4. MapReduce-序列化(Writable)

    Hadoop 序列化特点 Java 的序列化是一个重量级序列化框架(Serializable),一个对象被序列化后,会附带很多额外的信息(各种校验信息,Header,继承体系等),不便于在网络中高效传 ...

  5. 模板方法模式-Template Method(Java实现)

    模板方法模式-Template Method 在模板模式中, 处理的流程被定义在父类中, 而具体的处理则交给了子类. 类关系图很简单: Template接口 这里定义了子类需要实现的方法(before ...

  6. IE提示“Internet Explorer已限制此网页运行脚本或ActiveX控件”的解决办法

    在页面html开始标签和head开始标签中间新增一行,添加以下代码: <!-- saved from url=(0014)about:internet --> 或者 直接设置IE浏览器 工 ...

  7. 第十一节:基于MVC5+Spring.Net+EF+Log4net 传统的一种搭建模式

  8. Flink学习(二)Flink中的时间

    摘自Apache Flink官网 最早的streaming 架构是storm的lambda架构 分为三个layer batch layer serving layer speed layer 一.在s ...

  9. XL4001 典型应用电路

    典型的应用电路如下: 中文数据手册:https://wenku.baidu.com/view/98ad2ed86f1aff00bed51ec7.html 在做毕设的时候用到的一款350ma的DC/DC ...

  10. 关于sniff函数的一个小坑

    最近在用scapy模块写一个关于WiFi的脚本时用到sniff函数,其中遇到了一个小坑,记录如下: sniff函数是在指定网卡上每次嗅探到一个数据包后然后将它传给prn指定的函数.