Intellij IDEA远程向hadoop集群提交mapreduce作业

说明

1、本地环境:win7(64位)、Intellij IDEA2016.3.5
2、集群环境:虚拟机系统centos6.5、hadoop2.6.0,共三个节点,其中master节点为192.168.137.2,slave1:192.168.137.3,slave2:192.168.137.4
3、本文以WordCount为例。
3、参考http://blog.csdn.net/u014695188/article/details/53888832、
http://blog.csdn.net/gong_xucheng/article/details/17396401、
http://blog.csdn.net/u013980127/article/details/52118528、
http://www.cnblogs.com/yjmyzz/p/how-to-remote-debug-hadoop-with-eclipse-and-intellij-idea.html
4、本来以为配置好之后在windows上直接调试运行MR程序会很方便,但是其实并不方便,也是各种麻烦,而且还是要打包运行,可能以后的版本中会改进吧。
5、运行时发现运行挺慢的。
6、因为参考了很多他人的教程,也遇到了很多问题,因此下面的步骤和配置不能保证都是必须的。
7、如若转载请注明出处哦^_^!

安装配置

1、首先将集群上的hadoop环境下载到本地,本文是下载到“E:\javaws”。
2、在本地配置环境变量

HADOOP_HOME=D:\yangjm\Code\study\hadoop\hadoop-2.6.0
HADOOP_BIN_PATH=%HADOOP_HOME%\bin
HADOOP_PREFIX=D:\yangjm\Code\study\hadoop\hadoop-2.6.0
另外,PATH变量在最后追加;%HADOOP_HOME%\bin

3、去网上下载对应hadoop版本的hadoop.dll、winutils.exe,分别放到目录“C:\Windows\System32”和“$HADOOP_HOME\bin”下。
说明:hadoop.dll主要是防止插件报各种莫名错误,比如空对象引用,我本来以为intellij idea不需要安装,结果被空指针错误拖了很久。
4、修改本地的hosts文件。在目录“C:\Windows\System32\drivers\etc”下。
添加集群的ip地址和hostname的对应关系。hosts的具体作用这里不再细说。
在该文件中添加:

192.168.137.2 master
192.168.137.3 slave1
192.168.137.4 slave2

5、在intellij idea下新建maven项目
我最终的项目结构图如下所示,注意是最终
Intellij IDEA远程向hadoop集群提交mapreduce作业_第1张图片
其中,gkd.xgs.yxm是我的package,里面是WordCount.java程序。
resources是我新建的文件夹,里面需要存放hadoop集群中配置文件core-site.xml、mapred-site.xml、yarn-site.xml,此外,将log4j.properties文件也放在下面。
resources目录结构如下图:
Intellij IDEA远程向hadoop集群提交mapreduce作业_第2张图片
其中core-site.xml、mapred-site.xml、yarn-site.xml我都是直接复制的集群中的文件未做修改,log4j.properties配置复制的别人的也未做修改:
core-site.xml





<configuration>
<property>
    <name>fs.defaultFSname>
    <value>hdfs://master:9000value>
property>
<property>
    <name>hadoop.tmp.dirname>
    <value>file:/usr/local/hadoop-2.6.0/tmpvalue>
    <description>Abase for other temporary directories.description>
property>
configuration>

mapred-site.xml






<configuration>
<property>
    <name>mapreduce.framework.namename>
    <value>yarnvalue>
property>
<property>
    <name>mapreduce.jobhistory.addressname>
    <value>master:10020value>
property>
<property>
    <name>mapreduce.jobhistory.webapp.addressname>
    <value>master:19888value>
property>
    <property>
        <name>mapred.remote.osname>
        <value>Linuxvalue>
        <description>Remote MapReduce framework's OS, can be either Linux or Windowsdescription>
    property>

configuration>

yarn-site.xml


<configuration>


<property>
    <name>yarn.resourcemanager.hostnamename>
    <value>mastervalue>
property>
<property>
    <name>yarn.nodemanager.aux-servicesname>
    <value>mapreduce_shufflevalue>
property>
configuration>

log4j.properties

log4j.rootLogger=INFO, stdout
#log4j.logger.org.springframework=INFO
#log4j.logger.org.apache.activemq=INFO
#log4j.logger.org.apache.activemq.spring=WARN
#log4j.logger.org.apache.activemq.store.journal=INFO
#log4j.logger.org.activeio.journal=INFO


log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n

说明:log4j.properties是完全复制粘贴http://www.cnblogs.com/yjmyzz/p/how-to-remote-debug-hadoop-with-eclipse-and-intellij-idea.html中的配置,你也可以直接复制哦(我在配置过程中没有加这个,但是程序总是出错而且中不到原因,发现有了这个很方便)
6、pom.xml的配置。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0modelVersion>

  <groupId>gkd.xgs.yxmgroupId>
  <artifactId>WordCartifactId>
  <version>1.0-SNAPSHOTversion>
  <packaging>jarpackaging>

  <name>WordCname>
  <url>http://maven.apache.orgurl>

  <properties>
    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
  properties>
  <repositories>
    <repository>
      <id>alimavenid>
      <name>aliyun mavenname>
      <url>http://maven.aliyun.com/nexus/content/groups/public/url>
      <releases>
        <enabled>trueenabled>
      releases>
      <snapshots>
        <enabled>falseenabled>
      snapshots>
    repository>
    <repository>
      <id>oschinaid>
      <name>oschina mavenname>
      <url>http://maven.oschina.net/content/groups/public/url>
    repository>
    <repository>
      <id>centralid>
      <name>central mavenname>
      <url>http://repo1.maven.org/maven2/url>
    repository>
    <repository>
      <id>Akka repositoryid>
      <url>http://repo.akka.io/releasesurl>
    repository>
    <repository>
      <id>hadoop-pcapid>
      <url>http://dl.bintray.com/hadoop-pcap/hadoop-pcapurl>
    repository>
  repositories>
  <dependencies>
    <dependency>
      <groupId>org.apache.hadoopgroupId>
      <artifactId>hadoop-commonartifactId>
      <version>2.6.0version>
    dependency>
    <dependency>
      <groupId>org.apache.hadoopgroupId>
      <artifactId>hadoop-mapreduce-client-coreartifactId>
      <version>2.6.0version>
    dependency>
    <dependency>
      <groupId>org.apache.hadoopgroupId>
      <artifactId>hadoop-hdfsartifactId>
      <version>2.6.0version>
    dependency>
    <dependency>
      <groupId>org.apache.hadoopgroupId>
      <artifactId>hadoop-mapreduce-client-jobclientartifactId>
      <version>2.6.0version>
    dependency>
    <dependency>
      <groupId>org.apache.hadoopgroupId>
      <artifactId>hadoop-mapreduce-client-commonartifactId>
      <version>2.6.0version>
    dependency>
    <dependency>
      <groupId>junitgroupId>
      <artifactId>junitartifactId>
      <version>3.8.1version>
      <scope>testscope>
    dependency>
  dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.pluginsgroupId>
        <artifactId>maven-assembly-pluginartifactId>
        <version>2.5.5version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>trueaddClasspath>
              <classpathPrefix>lib/classpathPrefix>

              <mainClass>gkd.xgs.yxm.WordCountmainClass>

            manifest>
          archive>
          <descriptorRefs>
            <descriptorRef>jar-with-dependenciesdescriptorRef>
          descriptorRefs>
        configuration>
        <executions>
          <execution>
            <id>make-assemblyid>
            <phase>packagephase>
            <goals>
              <goal>singlegoal>
            goals>
          execution>
        executions>
      plugin>
    plugins>
  build>
project>

说明:需要修改其中的 mainClass中的值,该值是用来指明入口类,格式为:包名.类名,其他的可以复制粘贴。
7、添加library(感觉非必须,因为mvn中已经在pom.xml中添加了hadoop相关的依赖)
将本地hadoop2.6.0下的share目录下的所有文件夹添加进来,具体步骤可以参考:http://www.cnblogs.com/yjmyzz/p/how-to-remote-debug-hadoop-with-eclipse-and-intellij-idea.html
8、设置运行环境
Intellij IDEA远程向hadoop集群提交mapreduce作业_第3张图片
说明:
(1)mainclass跟在pom.xml中设置的一样,格式都是:包名.类名
(2)program arguments:查看WordCount.java程序可知,运行程序时需要两个参数,一个是输入文件,一个是结果输出路径。
我的第一个参数是:hdfs://master:9000/user/yxm/input/yxm.log
第二个参数是hdfs://master:9000/user/yxm/output
其中第一个路径及文件必须是已经存在的,第二个参数中的output目录是不存在的。
(3)Working directory:工作路径,选择你本地安装的hadoop2.6.0的路径,比如我这里是:E:\javaws\hadoop-2.6.0。
9、修改WordCount.java程序
添加以下代码

System.setProperty("hadoop.home.dir", "E:\\javaws\\hadoop-2.6.0");//如果没有这句话,会报找不到winutils.exe的错误,也不知道是不是由于我修改了环境变量之后没有重启的原因。
        Configuration conf = new Configuration();
        conf.set("fs.default.name", "hdfs://master:9000");
        conf.set("mapreduce.app-submission.cross-platform", "true");//意思是跨平台提交,在windows下如果没有这句代码会报错 "/bin/bash: line 0: fg: no job control",去网上搜答案很多都说是linux和windows环境不同导致的一般都是修改YarnRunner.java,但是其实添加了这行代码就可以了。
        conf.set("mapreduce.framework.name", "yarn");//集群的方式运行,非本地运行。

10、打包此程序
直接使用mvn package打包,在target程序中会生成包含依赖可以直接运行的程序:WordC-1.0-SNAPSHOT-jar-with-dependencies.jar,我将此jar文件复制到了工程根目录下。
此时在WordCount.java程序中添加一行代码

conf.set("mapred.jar","E:\\javaws\\WordC\\WordC-1.0-SNAPSHOT-jar-with-dependencies.jar");

此时点击运行,可以成功。
Intellij IDEA远程向hadoop集群提交mapreduce作业_第4张图片
说明:
(1)如果不打包添加到程序中还是会报错:No job jar file set. User classes may not be found. See Job or Job#setJar(String)。
(2)查找别人的配置教程,一般就是将jar文件直接放在根目录下,配置时不写绝对路径,代码为:

conf.set("mapred.jar","WordC-1.0-SNAPSHOT-jar-with-dependencies.jar");

我这边运行的时候会报错找不到该jar文件。
11、最终WordCount.java的代码

package gkd.xgs.yxm;

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;


public class WordCount {


    public static class TokenizerMapper
            extends Mapper {


        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();


        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);
            }
        }
    }


    public static class IntSumReducer extends Reducer {
        private IntWritable result = new IntWritable();


        public void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {
            int sum = 0;
            for (IntWritable val : values) {
                sum += val.get();
            }
            result.set(sum);
            context.write(key, result);
        }
    }


    public static void main(String[] args) throws Exception {
        System.setProperty("hadoop.home.dir", "E:\\javaws\\hadoop-2.6.0");
        Configuration conf = new Configuration();
        conf.set("fs.default.name", "hdfs://master:9000");
        conf.set("mapreduce.app-submission.cross-platform", "true");
        conf.set("mapreduce.framework.name", "yarn");
        conf.set("mapred.jar","E:\\javaws\\WordC\\WordC-1.0-SNAPSHOT-jar-with-dependencies.jar");
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        if (otherArgs.length < 2) {
            System.err.println("Usage: wordcount  [...] ");
            System.exit(2);
        }
        Job job = Job.getInstance(conf, "word count");
        job.setJarByClass(WordCount.class);
        job.setMapperClass(TokenizerMapper.class);
        job.setCombinerClass(IntSumReducer.class);
        job.setReducerClass(IntSumReducer.class);
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);
        for (int i = 0; i < otherArgs.length - 1; ++i) {
            FileInputFormat.addInputPath(job, new Path(otherArgs[i]));
        }
        FileOutputFormat.setOutputPath(job,
                new Path(otherArgs[otherArgs.length - 1]));
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

你可能感兴趣的:(大数据平台)