MapReduce实例编程之求平均数(不用eclipse插件详解)
由于本人的环境有点问题,无法正常使用hadoop的eclipse的插件,所以在导入jar包到eclipse的过程中遇到了很多坑,这里想给大家分享一下经验,让跟我同样境遇的人少踩坑,以快速上手自己的第一个MapReduce程序。
一、导入hadoop的jar包到eclipse中
1、新建java project(这个很容易,就不赘述了)
2、准入导入jar包:右击新建的项目,点Build Path,再点Configure Build Path。
3、找到libraries:点击Add External JARs,找到所在的目录,进入share->hadoop目录
4、导入的jar包:common目录下的hadoop-common-2.9.1.jar(根据自己的版本来)、MapReduce目录下的所有jar包、yarn目录下的所有jar包、tools目录的子目录lib中的所有jar包。
到这里,第一步导入jar包就结束了
二、开始编写代码
代码一共分三部分,主函数,重写map函数,重写reduce函数
实现思路:首先在map中读取数据并进行切割,定义一个递增的数字作key,切下来的数字作为value.在reduce中遍历value,计算数量并求和同时比较大小获取最大最小值,最后求其平均数
测试输入1:
1 1 1 1 1 1 1 1 1 1
5 5 5 5 5 5 5 5 5 5
测试输入2:
5 8 10 17 32
8 9 13 32 21
预测结果:
平均数 7
最大值 32
最小值 1
实现过程图:
下面贴上完整代码:
package train;
import java.io.IOException;
import java.util.StringTokenizer;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
/**
* 计算平均数
* @author jiege
*
*/
public class Average{
public static class Map extends Mapper<Object,Text,IntWritable,IntWritable>{
private static IntWritable no = new IntWritable(1); //计数作为key
private Text number = new Text(); //存储切下的数字
public void map(Object key,Text value,Context context) throws IOException, InterruptedException{
StringTokenizer st = new StringTokenizer(value.toString());
while(st.hasMoreTokens()){
number.set(st.nextToken());
context.write(no, new IntWritable(Integer.parseInt(number.toString())));
}
}
}
public static class Reduce extends Reducer<IntWritable,IntWritable,Text,IntWritable>{
//定义全局变量
int count = 0;
//数字的数量
int sum = 0;
//数字的总和
int max = -2147483648; int min = 2147483647;
public void reduce(IntWritable key,Iterable<IntWritable> values,Context context) throws IOException, InterruptedException{
for(IntWritable val:values){
if(val.get()>max){ max = val.get();
}
if(val.get()<min){
min = val.get();
}
count++; sum+=val.get();
} int average = (int)sum/count;
//计算平均数 //
System.out.println(sum+"--"+count+"--"+average);
context.write(new Text("平均数"), new IntWritable(average));
context.write(new Text("最大值"), new IntWritable(max));
context.write(new Text("最小值"), new IntWritable(min));
}
}
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
// TODO Auto-generated method stub
Configuration conf = new Configuration();
//conf.set("mapred.job.tracker", "master:9001");
conf.addResource("config.xml");
args = new String[]{"hdfs://master:9000/user/input","hdfs://master:9000/user/output"};
//检查运行命令
String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
if(otherArgs.length != 2){
System.err.println("Usage WordCount <int> <out>");
System.exit(2);
}
//配置作业名
Job job = Job.getInstance(conf,"average1");
//配置作业各个类
job.setJarByClass(Average.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class);
//Mapper的输出类型 *强调内容*
job.setOutputKeyClass(IntWritable.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
三、打包成jar并在hadoop集群上运行
1、在写好的class文件上右击,然后点Export,选择java->JAR file,点击next,再点击Browse,选择你要放置的路径,再给jar包取个名字,然后点finish就可以了
2、在hadoop集群上创建上面提到的两个文件,并把测试数据写进去。注意:这里你上传到HDFS的路径应该和MapReduce代码中的路径是一样的。然后运行刚刚导出的jar包。
start-all.sh //启动集群
vim in1.txt //写入第一个测试数据
vim in2.txt //写入第二个测试数据
hdfs dfs -mkdir /user/input //创建输入文件夹
hdfs dfs -copyFromLocal in1.txt /user/input //上传本地文件
hdfs dfs -copyFromLocal in2.txt /user/input
hadoop jar caculate.jar(你导出的jar) train(java代码的包名).Average(class名) /user/input(输入文件夹) /user/output(输出文件夹)
如果运行成功,那么咱们这个编程实例就完成了(代码不懂的话自己去慢慢啃)。
最后强烈吐槽一下这个富文本编辑器,第一次用,给我的印象很不好。不能直接粘贴图片(粘贴后写不了文字)!!还有写文字什么的超级麻烦,希望****能改进一下。不过DIY效果的确强于Markdown!