让类【TopNMapper】继承类Mapper同时指定需要的参数类型,根据业务逻辑修改map类的内容如下:
package com.simple.topn;
import java.io.IOException;
import java.util.Arrays;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class TopNMapper extends Mapper<LongWritable, Text, IntWritable, IntWritable> {
int len;
int[] top;
/*
cleanup(),此方法被MapReduce框架仅且执行一次,在执行完毕Map任务后,进行相关变量或资源的释放工作。若是将释放资源工作放入方法map()中,也会导致Mapper任务在解析、处理每一行文本后释放资源,而且在下一行文本解析前还要重复初始化,导致反复重复,程序运行效率不高!
/
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
for (int i = 1; i < len + 1; i++) {
context.write(new IntWritable(top[i]), new IntWritable(top[i]));
}
}
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String[] arr = value.toString().split(’,’, -1);
if (arr.length == 4) {
int x = Integer.valueOf(arr[2]);//获取第三个字段即金额
add(x);
}
}
private void add(int val) {
top[0] = val;// top[0]专门用来存放,刚放进来的数据
Arrays.sort(top);// 排序,从小到大顺序,top初始化值都是0
}
/
setup(),此方法被MapReduce框架仅且执行一次,在执行Map任务前,进行相关变量或者资源的集中初始化工作。若是将资源初始化工作放在方法map()中,导致Mapper任务在解析每一行输入时都会进行资源初始化工作,导致重复,程序运行效率不高!
/
@Override
protected void setup(Context context) throws IOException, InterruptedException {
/
context.getConfiguration().getInt(‘N’, 10)中getInt(String name,
int defaultValue)解释如下
Get the value of the name property as an int. If no such property exists, the provided default value is returned, or if the specified value is not a valid int, then an error is thrown.
即获取参数属性值为int,如果这个参数不存在,则返回提供的默认值,若提供的value不是int类型,则抛出异常
*/
len = context.getConfiguration().getInt(‘N’, 10);
top = new int[len + 1];
}
}
在项目src目录下指定的包名【com.simple.topn】下右键点击,新建一个类名为【TopNReducer】并继承Reducer类,然后添加该类中的代码内容如下所示:
package com.simple.topn;
import java.io.IOException;
import java.util.Arrays;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class TopNReducer extends Reducer<IntWritable, IntWritable, Text, Text> {
int len;
int[] top;
/*
cleanup(),此方法被MapReduce框架仅且执行一次,在执行完毕Map任务后,进行相关变量或资源的释放工作。若是将释放资源工作放入方法map()中,也会导致Mapper任务在解析、处理每一行文本后释放资源,而且在下一行文本解析前还要重复初始化,导致反复重复,程序运行效率不高!
/
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
for (int i = len; i > 0; i–) {
context.write(new Text(String.valueOf(len - i + 1)), new Text(String.valueOf(top[i])));
}
}
@Override
protected void reduce(IntWritable key, Iterable values, Context context)
throws IOException, InterruptedException {
for (IntWritable val : values) {
add(val.get());
}
}
private void add(int val) {
top[0] = val;
Arrays.sort(top);// 排序,从小到大顺序,top初始化值都是0
}
/
setup(),此方法被MapReduce框架仅且执行一次,在执行Map任务前,进行相关变量或者资源的集中初始化工作。若是将资源初始化工作放在方法map()中,导致Mapper任务在解析每一行输入时都会进行资源初始化工作,导致重复,程序运行效率不高!
*/
@Override
protected void setup(Context context) throws IOException, InterruptedException {
//获取参数属性值为int,如果这个参数不存在,则返回提供的默认值,若提供的value不是int类型,则抛出异常
len = context.getConfiguration().getInt(‘N’, 10);
top = new int[len + 1];// 这个数组要是TOP N+1
}
}
在项目src目录下指定的包名【com.simple.topn】下右键点击,新建一个测试主类名为【TopNJob】并指定main主方法,编写测试代码如下所示:
package com.simple.topn;
import java.net.URI;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
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 TopNJob {
public static void main(String[] args) throws Exception {
//路径相关参数
final String INPUT_PATHs = args[0];
final String OUT_PATHs = args[1];
//创建一个configuration并设置连接信息
Configuration conf = new Configuration();
conf.set(‘fs.defaultFS’, ‘hdfs://localhost:9000’);
//对输出目录预处理(当输出目录存在时,删除该目录,防止报错目录已存在)
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATHs), conf);
final Path outPath = new Path(OUT_PATHs);
if (fileSystem.exists(outPath)) {
fileSystem.delete(outPath, true);
}
// 获取作业对象
Job job = Job.getInstance(conf);
// 设置主类
job.setJarByClass(TopNJob.class);
// 设置job参数
job.setMapperClass(TopNMapper.class);
job.setReducerClass(TopNReducer.class);
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(IntWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
// 设置job输入输出
FileInputFormat.setInputPaths(job, new Path(INPUT_PATHs));
FileOutputFormat.setOutputPath(job, outPath);
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}