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

实现过程图:

MapReduce实例编程之求平均数(不用eclipse插件详解)

下面贴上完整代码:

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!