eclipse编译运行MapReduce程序
一、环境
Ubuntu16,Hadoop2.7.1
二、安装eclipse
你可以直接在Ubuntu的Ubuntu软件中心直接搜索安装Eclipse,在桌面左侧任务栏,不过我用这种方法安装之后Eclipse打不开,就参照了下面这个网站的安装步骤:
Eclipse安装步骤
jdk安装可以参考这个网站的安装JAVA环境
三、安装配置Hadoop-Eclipse-Plugin
要在 Eclipse 上编译和运行 MapReduce 程序,需要安装 hadoop-eclipse-plugin,可下载 Github 上的 hadoop2x-eclipse-plugin(备用下载地址:http://pan.baidu.com/s/1i4ikIoP)。
下载后,将 release 中的 hadoop-eclipse-kepler-plugin-2.6.0.jar (还提供了 2.2.0 和 2.4.1 版本)复制到 Eclipse 安装目录的 plugins 文件夹中,运行 eclipse -clean 重启 Eclipse 即可(添加插件后只需要运行一次该命令,以后按照正常方式启动就行了)。
unzip -qo ~/下载/hadoop2x-eclipse-plugin-master.zip -d ~/下载
sudo cp ~/下载/hadoop2x-eclipse-plugin-master/release/hadoop-eclipse-plugin-2.6.0.jar /usr/lib/eclipse/plugins/
/usr/lib/eclipse/eclipse -clean
在继续配置前请确认打开Hadoop
启动eclipse,选择Window菜单下的Preferences,此时会弹出一个窗体,窗体的左侧会多出 Hadoop Map/Reduce 选项,点击此选项,选择 Hadoop 的安装目录(如/usr/local/hadoop,Ubuntu不好选择目录,直接输入就行)。
切换 Map/Reduce 开发视图,选择 Window 菜单下选择 Open Perspective -> Other,弹出一个窗体,从中选择 Map/Reduce 选项即可进行切换。
建立与 Hadoop 集群的连接,点击 Eclipse软件右下角的 Map/Reduce Locations 面板,在面板中单击右键,选择 New Hadoop Location。
在弹出来的 General 选项面板中,General 的设置要与 Hadoop 的配置一致。一般两个 Host 值是一样的,如果是伪分布式,填写 localhost 即可,另外我使用的Hadoop伪分布式配置,设置 fs.defaultFS 为 hdfs://localhost:9000,则 DFS Master 的 Port 要改为 9000。Map/Reduce(V2) Master 的 Port 用默认的即可,Location Name 随意填写。
Advanced parameters 选项面板是对 Hadoop 参数进行配置,实际上就是填写 Hadoop 的配置项(/usr/local/hadoop/etc/hadoop中的配置文件),如我配置了 hadoop.tmp.dir ,就要进行相应的修改。但修改起来会比较繁琐,我们可以通过复制配置文件的方式解决(下面会说到)。
总之,我们只要配置 General 就行了,点击 finish,Map/Reduce Location 就创建好了。
四、在Eclipse中创建MapReduce项目
点击 File 菜单,选择 New -> Project…,选择 Map/Reduce Project,点击 Next。
填写 Project name 为 WordCount 即可,点击 Finish 就创建好了项目。
此时在左侧的 Project Explorer 就能看到刚才建立的项目了。
接着右键点击刚创建的 WordCount 项目,选择 New -> Class
需要填写两个地方:在 Package 处填写 org.apache.hadoop.examples;在 Name 处填写 WordCount。
创建 Class 完成后,在 Project 的 src 中就能看到 WordCount.java 这个文件。将如下 WordCount 的代码复制到该文件中。
package org.apache.hadoop.examples;import java.io.IOException;
import java.util.Iterator;
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;public class WordCount {public WordCount() {}public static void main(String[] args) throws Exception {Configuration conf &#61; new Configuration();String[] otherArgs &#61; (new GenericOptionsParser(conf, args)).getRemainingArgs();if(otherArgs.length < 2) {System.err.println("Usage: wordcount [...] ");System.exit(2);}Job job &#61; Job.getInstance(conf, "word count");job.setJarByClass(WordCount.class);job.setMapperClass(WordCount.TokenizerMapper.class);job.setCombinerClass(WordCount.IntSumReducer.class);job.setReducerClass(WordCount.IntSumReducer.class);job.setOutputKeyClass(Text.class);job.setOutputValueClass(IntWritable.class);for(int i &#61; 0; i < otherArgs.length - 1; &#43;&#43;i) {FileInputFormat.addInputPath(job, new Path(otherArgs[i]));}FileOutputFormat.setOutputPath(job, new Path(otherArgs[otherArgs.length - 1]));System.exit(job.waitForCompletion(true)?0:1);}public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {private IntWritable result &#61; new IntWritable();public IntSumReducer() {}public void reduce(Text key, Iterable<IntWritable> values, Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {int sum &#61; 0;IntWritable val;for(Iterator i$ &#61; values.iterator(); i$.hasNext(); sum &#43;&#61; val.get()) {val &#61; (IntWritable)i$.next();}this.result.set(sum);context.write(key, this.result);}}public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {private static final IntWritable one &#61; new IntWritable(1);private Text word &#61; new Text();public TokenizerMapper() {}public void map(Object key, Text value, Mapper<Object, Text, Text, IntWritable>.Context context) throws IOException, InterruptedException {StringTokenizer itr &#61; new StringTokenizer(value.toString());while(itr.hasMoreTokens()) {this.word.set(itr.nextToken());context.write(this.word, one);}}}
}
在运行 MapReduce 程序前&#xff0c;还需要执行一项重要操作&#xff08;也就是上面提到的通过复制配置文件解决参数设置问题&#xff09;&#xff1a;将 /usr/local/hadoop/etc/hadoop 中将有修改过的配置文件&#xff08;如伪分布式需要 core-site.xml 和 hdfs-site.xml&#xff09;&#xff0c;以及 log4j.properties 复制到 WordCount 项目下的 src 文件夹&#xff08;~/workspace/WordCount/src&#xff09;中&#xff1a;
cp /usr/local/hadoop/etc/hadoop/core-site.xml ~/workspace/WordCount/src
cp /usr/local/hadoop/etc/hadoop/hdfs-site.xml ~/workspace/WordCount/src
cp /usr/local/hadoop/etc/hadoop/log4j.properties ~/workspace/WordCount/src
复制完成后&#xff0c;务必右键点击 WordCount 选择 refresh 进行刷新&#xff08;不会自动刷新&#xff0c;需要手动刷新&#xff09;&#xff0c;可以看到文件结构如下所示&#xff1a;
点击工具栏中的 Run 图标&#xff0c;或者右键点击 Project Explorer 中的 WordCount.java&#xff0c;选择 Run As -> Run on Hadoop&#xff0c;就可以运行 MapReduce 程序了。不过由于没有指定参数&#xff0c;运行时会提示 “Usage: wordcount “&#xff0c;需要通过Eclipse设定一下运行参数。
右键点击刚创建的 WordCount.java&#xff0c;选择 Run As -> Run Configurations&#xff0c;在此处可以设置运行时的相关参数&#xff08;如果 Java Application 下面没有 WordCount&#xff0c;那么需要先双击 Java Application&#xff09;。切换到 “Arguments” 栏&#xff0c;在 Program arguments 处填写 “input output” 就可以了。
注意&#xff1a;这里需要你的hdfs文件系统&#xff08;不是本地文件&#xff09;里面要有input文件目录
设定参数后&#xff0c;再次运行程序&#xff0c;可以看到运行成功的提示&#xff0c;刷新 DFS Location 后也能看到输出的 output 文件夹。
至此&#xff0c;你就可以使用 Eclipse 方便的进行 MapReduce程序的开发了。