一、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. mongoDB 文档操作_删

    mongoDB 文档删除 MySQL对比 mysql delete from table where ... mongo db.collection.deleteOne(query) 删除函数 del ...

  2. LOJ #6285 分块入门9

    题意:区间众数,不带修改,带修改刚看了一眼没看懂cls在讲啥QAQ. 题解:按照代码中那个sqrt(n/2/log2(n))大小分块,可以用均值不等式证明的,就是假设查询和n同级,然后一通爆算就可以得 ...

  3. bootstrap学习: 基本组件以及布局;

    1.下拉菜单: <div class="btn-group"> <button type="button" class="btn b ...

  4. LeetCode刷题(Java)

    第一题 class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer, Integer> map = ...

  5. windows telnet 模拟 http请求

    1. 开启windows自带的telnet客户端(控制面板 --> 程序 --> 启用或关闭windows功能 --> ) 2. 打开cmd,使用Telnet客户端 3. 按ctrl ...

  6. 微服务之路由网关—zuul

    Zuul 简介Zuul 是 Netflix 公司开发的一个开源 APIGateway,其本质上是一个 WebServlet 应用.Zuul 的核心是一系列的 Filter. 为什么要使用 Zuul微服 ...

  7. Centos 7最小化redis部署

    配置源 [GuGe] name=GuGe baseurl=ftp://192.168.1.82 gpgcheck= enable= 安装 sh-4.2# yum -y install gcc gcc- ...

  8. Groovy 设计模式 -- 迭代器模式

    Iterator Pattern http://groovy-lang.org/design-patterns.html#_flyweight_pattern 迭代器模式,允许顺序访问 聚集对象中的中 ...

  9. python Flask web框架

    目录: --> Flask --> 配置文件 --> 配置文件解析 --> 配置文件导入 --> 路由 --> 路由参数 --> 常用路由匹配 --> ...

  10. 什么是DAPP

    DAPP(Decentralized Application)去中心化的应用 DAPP可以是网站,也可以是手机app,只要主要逻辑和数据在区块链上就可以 在以太坊平台上,一个DAPP肯定基于一个或多个 ...