美文网首页BigData
Windows 下使用 eclipse 编译打包运行自己的 Ma

Windows 下使用 eclipse 编译打包运行自己的 Ma

作者: 跟着大数据和AI去旅行 | 来源:发表于2018-11-13 21:08 被阅读24次

    一、相关文件准备

    1. java JDK for Windows

    2. hadoop-2.6.4.tar.gz 就是安装hadoop时使用的文件

    3. Eclipse JEE版本

    image

    二、环境准备

    1.安装java并配置环境

    自己百度

    2.解压hadoop-2.6.4.tar.gz源文件

    Hadoop源文件在整个开发过程中都会用到,因为很多依赖包都出自里面,用户可按自己的喜好选择位置,但路径层次最好不要太多,本文选在解压到E盘根目录下,即E:\hadoop-2.6.4

    3.安装Eclipse

    自己百度

    三、使用Eclipse创建一个Java工程

    使用Eclipse创建一个名为wordcound的Java工程

    四、导入Hadoop的相关jar包

    在编写MapReduce代码时,需要用到Hadoop源文件中的部分Jar包,就像在编写纯Java代码时需要使用Java自带的依赖包一样,所以这里需要把相应的Hadoop依赖包导入工程。

    现在工程 wordcount上右键,在弹出的菜单中选择第一个 New(新建),在选择Folder(文件),名称填上lib; 然后在把下面目录下的jar包复制到lib文件夹下(之前把Hadoop源文件解压到E盘根目录下)。

    E:\hadoop-2.6.4\share\hadoop\common
    E:\hadoop-2.6.4\share\hadoop\common\lib
    E:\hadoop-2.6.4\share\hadoop\common\lib\hadoop-hdfs-2.6.4.jar
    E:\hadoop-2.6.4\share\hadoop\mapreduce
    E:\hadoop-2.6.4\share\hadoop\yarn
    

    导入Jar包后,还需要把这些jar包添加到工程的构建路径,否则工程并不能识别。选中所有的jar包然后单击右键,选择Build Path -> Add to Build Path.

    上面就是Eclipse导入jar包的其中一种方法,其他方法也可以,只要让Eclipse程序能够引用上面的Jar包即可。

    五、 MapReduce 代码实现

    本代码演示 wordcount程序。

    MapReduce代码实现并不难,这里要编写3个类,分别是WordMapper类、WordReducer类和WordMain驱动类,前面两个类分别实现相应的 Map 和 Reduce 方法,后面一个则是对任务的创建进行部署。

    分别创建这3个类,并放入wordcount package下,目录结构如下:

    image

    WordMapper.java

    package wordcount;
    
    import java.io.IOException;
    import java.util.StringTokenizer;
    
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    //创建一个 WordMapper 类继承与 Mapper 抽象类
    public class WordMapper extends Mapper<Object, Text, Text, IntWritable>{
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();
        
        //Mapper 抽象类的核心方法,三个参数
        @Override
        protected void map(Object key,  //首字符偏移量     
                          Text value,   //文件的一行内容
                          Context context)  //Mapper端的上下文
                throws IOException, InterruptedException {
            //默认使用空格分隔
            StringTokenizer itr = new StringTokenizer(value.toString());
            while(itr.hasMoreTokens()){
                word.set(itr.nextToken());
                context.write(word, one);
            }
        }
    }
    

    map函数实现了对传入值的解析,将value解析成<key, value>的形式,然后使用context.write(word, one)进行输出。

    WordReducer.java

    package wordcount;
    
    import java.io.IOException;
    import org.apache.hadoop.io.IntWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Reducer;
    
    //创建一个 WordReducer 类继承与 Reducer 抽象类
    public class WordReducer extends Reducer<Text, IntWritable, Text, IntWritable>{
        private IntWritable result = new IntWritable(); //记录词频
        
        // Reducer 抽象类的核心方法,3个参数
        @Override
        protected void reduce(Text key, //Map 端输出的 key 值
                            Iterable<IntWritable> values,   //Map 端输出的 Value 集合
                            Context context)    //Reducer端上下文
                            throws IOException, InterruptedException {
            int sum = 0;
            
            for (IntWritable var : values) {    //遍历 values 集合,并把值相加
                sum += var.get();
            }
            
            result.set(sum);    //得到最终词频数
            context.write(key, result);     //写入结果
            
        }
    }
    

    reduce方法中,将获取的values进行遍历累加,得到相应的key出现的次数,最后将结果写入HDFS。

    WordMain.java

    WordMain驱动类主要是在Job中设定相应的Mapper类和Reducer类(用户编写的类),这样任务运行时才知道使用相应的类进行处理;WordMain驱动类还可以对MapReducer程序进行相应配置,让任务在Hadoop集群运行时按所定义的配置进行。其代码如下:

    package wordcount;
    
    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.lib.input.FileInputFormat;
    import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
    import org.apache.hadoop.util.GenericOptionsParser;
    
    public class WordMain 
    {
        
        public static void main(String[] args) throws Exception 
        {
            
            // Configuration 类: 读取hadoop的配置文件,如 site-core.xml...;
            //也可以用set方法重新设置(会覆盖): conf.set("fs.defaultFS","hdfs://master:9000")
            Configuration conf = new Configuration();
            
            //将命令行中的参数自动设置到变量conf中
            String[] otherArgs = new GenericOptionsParser(conf,args).getRemainingArgs();
            
            if (otherArgs.length != 2) 
            {
                System.err.println("Usage: wordcount <in> <out>");
                System.exit(2);
            }
            
            Job job = new Job(conf,"word count");   //新建一个job,传入配置信息
            job.setJarByClass(WordMain.class);  //设置主类
            job.setMapperClass(WordMapper.class);   //设置Mapper类
            job.setReducerClass(WordReducer.class); //设置Reducer类
            job.setOutputKeyClass(Text.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);   //等待完成退出
            
        }
    }
    

    该类中的main方法就是MapReduce程序的入口,在main方法中,首先创建一个Configuration类对象conf用于保存所有的配置信息,该对象在创建时会读取所需要配置文件如 site-core.xml、hdfs-site.xml等,根据配置文件中的变量信息进行初始化,当然配置文件中的配置有时候并不是人们想要的,这时候可以调用Configuration类中的set方法进行覆盖,如想要修改Reducer的数量,可以使用如下方法:

    conf.set("mapreduce.job.reduces","2");
    

    也不是所有的变量都可以修改,有时候集群管理员并不希望用户在应用程序中修改某变量的值,这时候会在相应变量后面添加final属性:

    <property>
        <name>mapreduce.task.io.sort.factor</name>
        <value>10</value>
        <final>true</final>
    </property>
    

    这时候,Configuration类中在set上面的属性将不再起左右。

    最后,main方法中创建一个Job类对象job,并传入配置信息conf和作业名称。之后对job对象进行相关设置,如Mapper类、Reducer类等。job对象就是最终的作业对象,它里面包含一个作业所需的所有信息。

    至此,一个MapReduce程序便开发完成了。

    六、打包工程为jar包

    WordCount代码完成后,并不能直接在hadoop中运行,还需要将其打包成jvm所能执行的二进制文件,即打包成.jar文件,才能被hadoop所有。

    在WordCount项目上右击,选择Export(导出),在弹出的对话框中选择 JAR file,如下图所示,然后单击Next。之后会进入JAR依赖包过滤对话框,这里只选择src即可,把lib文件夹前的勾选去掉,因为lib中的依赖包本来就是复制的hadoop的源文件,在集群中已经包含了。之后选择一个保存位置,单击Finish即可。

    选择Jar file jar依赖包过滤

    打包成wordcount.jar

    WordMain驱动类为wordcount.WordMain。

    七、部署并运行

    部署其实就把前面打包生成的wordcount.jar包放入集群中运行。hadoop一般会有多个节点,一个namenode节点和多个datanode节点,这里只需要把jar放入namenode中,并使用相应的hadoop命令即可,hadoop集群会把任务传送给需要运行任务的节点。wordcount.jar运行时需要有输入文本。

    1.创建测试文本并上传相关文件到namenode中

    为了方便,在桌面上创建测试文本file1.txt、file2.txt。内容分别为

    File: file1.txt                 File:file2.txt
    hadoop is very good             hadoop is very good
    mapreduce is very good           mapreduce is very good
    

    然后使用WinSCP工具把上述txt文件和wordcount.jar文件一起上传到namenode节点的hadoop用户目录下,hadoop用户指的是安装运行hadoop集群的用户,本文的用户名就为hadoop.

    注意:
    上传结束后,需要查看上传文件的权限是否为hadoop:hadoop(hadoop用户和hadoop组),如果不是则需要将上传文件的权限改为hadoop:hadoop,命令为:

    sudo chown -R hadoop:hadoop file1.txt
    sudo chown -R hadoop:hadoop file2.txt
    sudo chown -R hadoop:hadoop wordcount.jar
    

    如下图所示:

    image

    2.上传测试文件到HDFS

    hdfs dfs -mkdir input   //创建输入文件夹input
    hdfs dfa -put file* input   //将file1.txt file2.txt放入input文件夹中
    

    3.在hadoop集群中运行WordCount

    测试文件已经准备完毕,现在要做的就是把任务提交到hadoop集群中。
    在hadoop中运行jar任务需要使用的命令:

    hadoop jar [jar文件位置] [jar 主类] [HDFS输入位置] [HDFS输出位置]
    
    • hadoop: hadoop脚本命令,如果要直接使用,必须添加相应bin路径到环境变量PATH中。
    • jar: 表示要运行的是一个基于Java的任务。
    • jar文件位置: 提供所要运行任务的jar文件位置,如果在当前操作目录下,可直接使用文件名。
    • jar主类: 提供入口函数所在的类,格式为[包名.]类名
    • HDFS输入位置: 指定输入文件在HDFS中的位置。
    • HDFS输出位置: 执行输出文件在HDFS中的存储位置,该位置必须不存在,否则任务不会运行,该机制就是为了防止文件被覆盖出现意外丢失。

    本例的操作命令如下:

    hadoor jar wordcount.jar wordcount.WordMain input output
    

    提交任务后,hadoop集群便会开始执行任务,在任务的执行过程中,会出现一系列任务提示或信息进度,如下所示:

    image

    4.查看任务结果

    任务结束保存在设定的输出目录中,如下图所示:

    image
    • _SUCCESS: 该文件中无任何内容,生成它主要是为了使hadoop集群检测并停止任务。
    • part-r-00000: 由Reducer生成的结果文件,一般来说一个Reducer生成一个,本例中只有一个Reducer运行,所以结果文件只有一个。

    可以使用hdfs dfs中的-cat命令查看结果:

    hdfs dfs -cat output/*
    

    结果如下图所示:

    image

    至此,一个MapReducer程序的开发过程就结束了。

    本文转自:《Hadoop大数据处理技术基础与实践》--安俊秀 编著

    更多精彩内容,欢迎关注微信公众号: 不会搬砖的码农

    不会搬砖的码农

    相关文章

      网友评论

        本文标题:Windows 下使用 eclipse 编译打包运行自己的 Ma

        本文链接:https://www.haomeiwen.com/subject/kbkrfqtx.html