• 在eclipse中用gradle搭建MapReduce项目


    我用的系统是ubuntu14.04
    新建一个Java Project。

    这里用的是gradle打包,gradle默认找src/main/java下的类编译。src目录已经有了,手动在src下创建main/java(也可以配置gradle去找其他路径的下的文件)。
    在项目跟录下创建build.gradle文件。

    apply plugin: 'java'
    apply plugin: 'eclipse'
    
    jar {
      baseName = 'hadoop'
      version =  '0.0.1'
    }
    
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    
    dependencies {
      compile fileTree(dir: 'lib', include: ['*.jar'])
    }


    根目录下创建一个lib文件夹,将hadoop安装目录下share/hadoop下的 common, common/lib, mapreduce, yarn, yarn/lib目录下的jar包拷进项目的lib文件夹里。选中所有的jar包,右键Build Path-->add to build path。
    项目基础环境搭好,把源码包中的WordCount测试类中的代码拷进项目里。

    package fzk;
    
    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 MR {
      public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
    
        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<Text, IntWritable, Text, IntWritable> {
        private IntWritable result = new IntWritable();
    
        public void reduce(Text key, Iterable<IntWritable> 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 {
        Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
    
        if (otherArgs.length < 2) {
          System.err.println("Usage: wordcount <in> [<in>...] <out>");
          System.exit(2);
        }
        Job job = Job.getInstance(conf, "word count");
        job.setJarByClass(MR.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);
      }
    }

    一切准备就绪后,想利用hadoop运行mapreduce项目,需要自己手动打包。利用gradle打包,打开一个终端,在build.gradle的目录下,执行

    $ gradle build

    等命令执行结束后,会发现项目中多出了一个build文件夹,我们打出来的jar包在build/lib目录下。确保jar下确实包含了我们自己编写的类可以用解压软件进入jar看一下(不用解压,只是查看一下)。里面有src目录下的文件就说明已经打包成功了。
    我们在build.gradle中配置的打出来的jar包的名字叫hadoop-0.0.1.jar。随自己起什么名都可以。
    接下来测试一下,测试需要的是一个已经存在的文件作文输入,名字随便(这里是input),为了方便把input放在和打出来的jar包放在一个目录下,在测试时还需要一个输出的目录(这里是output),指定的目录下不可以存在这个目录。进入到jar包的目录下执行下面命令测试程序

    $ hadoop jar hadoop-0.0.1.jar fzk.MR input output

    fzk.MR前面的是包名,在代码中已经把包名粘出来了,说明我就是在fzk包下创建的MR类。这个地方指定类的时候前面需要加上包名。input就是手动创建的一个测试文件,output在这个目录下不可以存在,程序运行后会创建出一个output文件夹,结果就在里边。
    为了方便我们可以创建一个run.sh这样每次运行的时候就不用输入那么多的命令:

    rm -fr output
    hadoop jar build/libs/hadoop-0.0.1.jar fzk.MR input output

    每次执行前先把output文件夹删掉,这行这条命令的目录是在项目根目录下,input应该放在根目录下,也会在根目录生成output结果。

    到这里,我们就是完整的运行完一个WordCount程序了。但是这样太麻烦,我们已经用eclipse了为什么还需要打包才能运行。我们确实是不需要每次都去打包才可以测试的。如果向直接在eclipse里运行,jar必须确保把需要的全部导入了,如果程序运行时报什么ClassDefNotFound之类的错误就是哪个jar没有导,自己找找导进去就行了。下面看看怎么直接在eclipse运行程序。
    这里只需要把main方法修改一下即可,我们这里需要args中的参数,但是ctrl + f11 运行的时候肯定是传不进去参数的,这里你可以在配置run configuration中添加启动参数,至少两个,从第一个到倒数第一个是input,最后一个是output。也可以偷懒一下我们只是测试,只需要在用到args的时候赋值就可以了,在main方法的第一行加上

        args = new String[] {"input", "output/" + System.currentTimeMillis()};

    output后面加上当前时间戳的目的是不用每次运行的时候都去手动删掉output目录。

    这里只是对于初学的时候方便自己随便怎么修改。接下来就去探索了。

  • 相关阅读:
    基于android混合开发的JsBridge技术学习
    使用centos引导内核错误:kernel: pnp 00:0b: can't evaluate _CRS: 8
    mysql的错误:The server quit without updating PID file /usr/local/mysql/data/door.pid).
    关于新的man版本出现“无法解析 /usr/share/man/zh_CN/man1/ls.1.gz: 没有那个文件或目录“
    使用struts2标签<s:action无法显示引用页面问题
    cookie 跨域的问题
    mysql8.0 在window环境下的部署与配置
    webconfig的配置解析
    C#.net 创建XML
    HashMap和HashTable的区别
  • 原文地址:https://www.cnblogs.com/badboyf/p/6228318.html
Copyright © 2020-2023  润新知