Map阶段读取一行数据需要记录’上行流量’,‘下行流量’以及’总流量’,单个基本数据类型不方便保存,引入自定义对象保存,但需要序列化.
3.1创建自定义对象
注意需要实现序列化,此处我们实现Writable接口,重写相关的方法
package com.sxt.mr.flow;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import org.apache.hadoop.io.Writable;
/**
-
存储流量相关数据
-
@author 波波烤鸭
*/
public class Flow 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 Flow(long upFlow, long downFlow) {
super();
this.upFlow = upFlow;
this.downFlow = downFlow;
this.sumFlow = upFlow + downFlow;
}
/**
- 无参构造方法必须要有 反射的时候需要用到
*/
public Flow() {
super();
}
/**
- 序列化方法
*/
@Override
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
out.writeLong(upFlow);
out.writeLong(downFlow);
out.writeLong(sumFlow);
}
@Override
public String toString() {
return upFlow + “\t” + downFlow + “\t” + sumFlow;
}
/**
- 反序列化 反序列化的顺序和序列化的顺序一致
*/
@Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
upFlow = in.readLong();
downFlow = in.readLong();
sumFlow = in.readLong();
}
public long getSumFlow() {
return sumFlow;
}
public void setSumFlow(long sumFlow) {
this.sumFlow = sumFlow;
}
}
3.2 自定义MapTask
注意输出的value就是我们自定义的类型
public class MyMapTask extends Mapper<LongWritable, Text, Text, Flow>{
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException {
// 将一行数据转换为String
String line = value.toString();
// 切分字段
String[] fields = line.split(“\t”);
// 取出手机号
String phoneNum = fields[1];
// 取出上行流量下行流量
long upFlow = Long.parseLong(fields[fields.length-3]);
long downFlow = Long.parseLong(fields[fields.length-2]);
Flow flow = new Flow(upFlow,downFlow);
context.write(new Text(phoneNum), flow);
}
}
3.3 自定义ReduceTask
public class MyReduceTask extends Reducer<Text, Flow, Text, Flow>{
@Override
protected void reduce(Text key, Iterable values, Context context)
throws IOException, InterruptedException {
long sum_upflow = 0;
long sum_downflow = 0;
for (Flow flow : values) {
sum_upflow += flow.getUpFlow();
sum_downflow += flow.getDownFlow();
}
Flow f = new Flow(sum_upflow,sum_downflow);
// 必须重写Flow的toString方法
context.write(new Text(key), f);
}
}
3.4 启动类测试
采用本地模式运行
package com.sxt.mr.flow;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class FlowTest {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration(true);
conf.set(“mapreduce.framework.name”, “local”);
// 输出到HDFS文件系统中
// conf.set(“fs.defaultFS”, “hdfs://hadoop-node01:9000”);
// 输出到本地文件系统
conf.set(“fs.defaultFS”, “file:///”);
Job job = Job.getInstance(conf);
job.setJarByClass(FlowTest.class);
// 指定本job要使用的map/reduce的工具类
job.setMapperClass(MyMapTask.class);
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
15827310655)]
[外链图片转存中…(img-2on2VCAT-1715827310656)]
[外链图片转存中…(img-6SvejoWL-1715827310656)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!