流量统计之自定义复杂数据类型(第一步)
1、需求分析
(1)自定义复杂类型
(2)access.log
正数第二字段:手机号
倒数第三字段:上行流量
倒数第二字段:下行流量
(3)需求:统计每个手机号的上行流量和、下行流量和、总流量和。
(4)Access.java
手机号、上行流量、下行流量、总流量
(5)要求和:根据手机号进行分组,然后把该手机号对应的上下行流量加起来。
(6)Mapper
把手机号、上行流量、下行流量 拆开
把手机号作为key,把Access作为value写出去
(7)Reducer
(13726238888, <Access, Access>)
2、Access.java
package com.imooc.bigdata.hadoop.mr.access; /* * 自定义复杂数据类型 * 1)按照Hadoop规范,实现Writable接口 * 2)按照Hadoop规范,实现write、readFields两个方法 * 3)定义默认的构造方法 */ import org.apache.hadoop.io.Writable; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; //自定义的复杂类型是有要求的 //需要实现一个Writable接口 //然后要不定义一个抽象类,要不实现write方法。在这里选择实现write方法 //具体方式:选择implements,选择Implement methods,生成write、readFields两个空方法 public class Access implements Writable { //4个字段 private String phone; //电话号码 private long up; //上行流量 private long down; //下行流量 private long sum; //总流量 //上述4个字段的4组get、set方法 //具体方式:右键--Generate-Getter and Setter public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public long getUp() { return up; } public void setUp(long up) { this.up = up; } public long getDown() { return down; } public void setDown(long down) { this.down = down; } public long getSum() { return sum; } public void setSum(long sum) { this.sum = sum; } @Override //最重要的实现write方法 //在Hadoop运行时,会自动调用write方法 public void write(DataOutput dataOutput) throws IOException { dataOutput.writeUTF(phone); dataOutput.writeLong(up); dataOutput.writeLong(down); dataOutput.writeLong(sum); } @Override //最重要的实现readFields方法 //在Hadoop运行时,会自动调用readFields方法 //注意:在write方法里,先写的参数,在readFields,就先读取 public void readFields(DataInput dataInput) throws IOException { this.phone = dataInput.readUTF(); this.up = dataInput.readLong(); this.down = dataInput.readLong(); this.sum = dataInput.readLong(); } @Override //为了后续使用方便,定义了一个toString //具体方式:右键-Generate-toString() public String toString() { return "Access{" + "phone='" + phone + '\'' + ", up=" + up + ", down=" + down + ", sum=" + sum + '}'; } //默认的构造方法 public Access(){} }