Hadoop 序列化案例
需求与分析
统计每一个手机号耗费的总上行流量、下行流量、总流量
(1)输入数据
1 13736230513 192.196.100.1 www.dev1.com 2481 24681 200
2 13846544121 192.196.100.2 264 0 200
3 13956435636 192.196.100.3 132 1512 200
4 13966251146 192.168.100.1 240 0 404
5 18271575951 192.168.100.2 www.dev1.com 1527 2106 200
6 84188413 192.168.100.3 www.dev1.com 4116 1432 200
(2)输入数据格式:
7 13560436666 120.196.100.99 1116 954 200
id 手机号码 网络ip 上行流量 下行流量 网络状态码
(3)期望输出数据格式
13560436666 1116 954 2070
手机号码 上行流量 下行流量 总流量
(4)Map阶段
4.1 读一行数据,切分字段
7 13560436666 120.196.100.99 1116 954 200
4.2 抽取手机号,上行流量,下行流量
13560436666 1116 954
4.3 以手机号为key,bean对象为value输出,即context.write(手机号,bean对象)
4.4 bean对象能传输必须实现序列化接口
(5)Reduce阶段
5.1 累加上行流量和下行流量的总和
13560436666 1116 + 954 =2070
手机号, 上行流量,下行流量
序列化案例实操
(1)编写流量统计的Bean对象
package com.dev1.FlowSum;
import org.apache.hadoop.io.Writable;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
//1.实现Writable接口
public class FlowBean implements Writable {
private Long upFlow;
private Long downFlow;
private Long sumFlow;
public Long getUpFlow() {
return upFlow;
}
public void setUpFlow(Long upFlow) {
this.upFlow = upFlow;
}
public Long getDownFlow() {
return downFlow;
}
public void setDownFlow(Long downFlow) {
this.downFlow = downFlow;
}
public Long getSumFlow() {
return sumFlow;
}
public void setSumFlow(Long sumFlow) {
this.sumFlow = sumFlow;
}
//2.反序列化时,需要反射调用空参构造函数,所以必须要有
public FlowBean() {
}
public FlowBean(Long upFlow, Long downFlow, Long sumFlow) {
this.upFlow = upFlow;
this.downFlow = downFlow;
this.sumFlow = sumFlow;
}
//3.写序列化方法
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeLong(upFlow);
dataOutput.writeLong(downFlow);
dataOutput.writeLong(sumFlow);
}
//4.反序列化方法
//5.反序列化方法的读顺序必须与序列化方法的