Windows7 x64+Eclipse+Hadoop 2.5.2搭建MapReduce开发集群

MapReduce开发测试的代码,可以提交到Hadoop集群上测试运行,也可以在本机测试运行。由于我们的开发机是windows系统,我在尝试将代码提交到Hadoop集群上测试运行的时候,出现了一个接一个的错误。最后我还是采用了本机测试运行的方法,本文介绍的配置方法最终能够实现本地运行测试代码。当然如此测试的代码打包之后,上传到Hadoop集群上去,是可以正确执行的。

运行环境简介:
操作系统: Windows 7 sp1
Java软件版本: jdk1.8.0_121
Eclipse版本: Mars.2 Release (4.5.2)
Hadoop集群版本: hadoop-2.5.2.tar.gz
Eclipse的Hadoop插件版本: hadoop-eclipse-plugin-2.5.2.jar
hadoop-common版本: hadoop-common-2.2.0-bin-master.zip

0. 修改IP地址映射关系

由于Apache Hadoop相关的组件,对Hostname的依赖性非常大,很少直接使用IP地址。所以需要修改系统的host文件,以确定Hadoop集群中的IP地址与hostname的映射关系。
以我的Hadoop集群为例:

192.168.0.50 master.hadoop.frilab
192.168.0.51 slave01.hadoop.frilab
192.168.0.52 slave02.hadoop.frilab
192.168.0.53 slave03.hadoop.frilab
192.168.0.54 slave04.hadoop.frilab

1. 安装配置Hadoop 2.5.2的运行环境

hadoop-2.5.2.tar.gz(后文有下载链接)解压缩到某一目录下,这里我解压缩到B盘(这个盘符是不是很奇葩^_^)里。

下载hadoop-common-2.2.0-bin-master.zip(后文有下载链接),将这个软件包中的hadoop.dllwinutils.exe两个文件复制到hadoop-2.5.2的bin文件夹中。

注意: 上边提到的两个文件,能够保证hadoop在Windows系统上能够运行起来。否则会出现java.io.IOException: Could not locate executable null\bin\winutils.exe in the Hadoop binaries.的错误。

注意: 这里使用2.5.2版的hadoop,却是用2.2.0版本的hadoop-common,你也许会存在疑问。但是相信我,你没有看错,确实可以用。

接着修改系统的环境变量,添加两个变量,分别是:

HADOOP_HOMEB:\hadoop-2.5.2,你需要将这个地址修改为你解压缩hadoop-2.5.2.tar.gz的地址。

HADOOP_USER_NAMEhadoop,这个变量的值是你的Hadoop运行环境中的用户名。如果这个值不正确,在读写hdfs时会出现权限错误。

PATH;%HADOOP_HOME%/bin,在PATH变量上再增加一个目录,指向Hadoop的执行目录。

至此就完成了Hadoop 2.5.2运行环境的配置。

2. 在Eclipse中添加Hadoop插件

在Eclipse上安装Hadoop插件非常简单,只需要将hadoop-eclipse-plugin-2.5.2.jar(后文有下载链接)文件放到Eclipse软件目录下的plugins文件夹下,重新启动Eclipse即可。

3. 在Eclipse中添加查看HDFS的功能

在Eclipse上添加Hadoop插件后,HDFS的管理窗口不会默认出现在主界面上,需要手动设置。
在主界面的菜单栏上以此选择Window -> Show View -> Other,界面弹出Show View界面,选择MapReduce Tools -> Map/Reduce Locations。

这里写图片描述

这里写图片描述
添加完成后可以在界面上看到如下的窗口,
这里写图片描述
点击右键,增加选择New Hadoop Location:
这里写图片描述
在配置界面上添加Location name,Map/Reduce、DFS的Host、Port,和User name。配置完成后点击确定即可。
注意:Map/Reduce Master的配置信息可以参考yarn-site.xml中的yarn.resourcemanager.scheduler.address参数的配置,DFS Master的配置信息可以参考core-site.xml中的fs.defaultFS参数的配置。
这里写图片描述
完成后可以在Map/Reduce Locations窗口上看到刚才添加的HDFS连接。
这里写图片描述
并且在Project Exploper窗口的DFS Locations中可以可以看到该连接,使用该连接可以打开目录,查看文件。
这里写图片描述

此时就可以使用eclipse查看,管理hdfs中的文件了。注意通过此方法可以上传、下载和删除文件,但是不可以编辑文件。

4. 编写实现WordCount功能的示例代码

示例代码使用Maven进行管理,在Eclipse上新建一个名为wordcount的Maven项目。
修改项目配置文件pom.xml,主要修改两个要点:修改软件库的依赖关系、修改编译打包参数。

修改软件库的依赖关系:

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.5.2</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>2.5.2</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-client</artifactId>
    <version>2.5.2</version>
</dependency>

修改编译打包参数:

<build>
    <plugins>
        <plugin>
            <artifactId> maven-assembly-plugin </artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <!-- 指定入口类,这里按照实际情况修改成你创建的wordcount的类 -->
                        <mainClass>com.wordcount.WordCount</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

该示例程序虽然是运行在本地,但是操作目录依然是在Hadoop集群的hdfs上边。所以需要hadoop集群的两个配置文件。hdfs-size.xml,core-site.xml。将这两个文件放在src\main\java目录下即可。
为了增加日志显示效果,需要在src\main\java目录下创建log4j.properties,文件,文件内容如下:

### set log levels ###
log4j.rootLogger = ALL, systemOut

log4j.appender.systemOut= org.apache.log4j.ConsoleAppender
log4j.appender.systemOut.layout= org.apache.log4j.PatternLayout
log4j.appender.systemOut.layout.ConversionPattern= [%-d{yyyy-MM-dd HH:mm:ss.SS}] [%p] : %m%n
log4j.appender.systemOut.Threshold= INFO
log4j.appender.systemOut.ImmediateFlush= TRUE
log4j.appender.systemOut.Target= System.out

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true

log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [%-d{yyyy-MM-dd HH:mm:ss.SS}] [%p] : %m%n

创建一个wordcount.java文件,文件内容如下:

package com.wordcount;

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<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 {
            System.out.println(value.toString());
            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:map/reduce的j配置类,向hadoop框架描述map-reduce执行的工作
         */
        Configuration conf = new Configuration();

        @SuppressWarnings("deprecation")
        Job job = new Job(conf, "word count"); // 设置一个用户定义的job名称
        job.setJarByClass(WordCount.class);
        job.setMapperClass(TokenizerMapper.class); // 为job设置Mapper类
        job.setCombinerClass(IntSumReducer.class); // 为job设置Combiner类
        job.setReducerClass(IntSumReducer.class); // 为job设置Reducer类
        job.setOutputKeyClass(Text.class); // 为job的输出数据设置Key类
        job.setOutputValueClass(IntWritable.class); // 为job输出设置value类
        FileInputFormat.addInputPath(job, new Path("/input")); // 为job设置输入路径
        FileOutputFormat.setOutputPath(job, new Path("/output"));// 为job设置输出路径
        System.exit(job.waitForCompletion(true) ? 0 : 1); // 运行job
    }
}

该程序的逻辑是,在hdfs的根目录下寻找input目录,遍历该目录下载所有文件,对这些文件内的内容按照空格分词,统计这些词出现的个数,并将统计结果存放在output目录下的文件中。

在HDFS中创建input目录,在该目录下上传两个文本文件file1.txt和file2.txt。
这里写图片描述

其中file1.txt的文件内容为filename is file1,file2.txt的文件内容为the filename is file2

注意: 通过Eclipse中的Hadoop插件,可以直接在HDFS上创建文件夹,但是无法添加文件和编辑文件。只能在本地创建和编辑好文件后,再通过Eclipse上传到指定目录下。

查看HDFS中是否存在output目录,如果存在,首先删除该目录,否则会提示目录已存在的报错提示。运行该程序,点击右键,选择Run on Hadoop。

运行成功后,可以在HDFS中查看到一个output文件,改文件目录如下所示:
这里写图片描述

打开其中的part-r-00000文件,可以看到如下内容:

part-r-00000的文件内容

说明示例运行成功。

5. 测试程序打包,上传到集群上运行

执行此操作前,先删除hdfs上的output目录。否则再次运行程序的时候,会提示出现output已存在的错误。

在Eclipse上执行mvn install,既可以生成可以运行的jar包。因为我们前面已经修改过项目的配置文件pom.xml了,修改的目的就是项目打包的时候,能够把代码运行所需要的所有库都打包到一个jar文件中。
该命令执行完毕后,会在wordcount项目中的target目录中出现一个wordcount-0.0.1-SNAPSHOT.jarwordcount-0.0.1-SNAPSHOT-jar-with-dependencies.jar。后者就是包含依赖库的打包文件。
wordcount-0.0.1-SNAPSHOT-jar-with-dependencies.jar上传到Hadoop集群上去,运行如下命令来提交任务:

hadoop jar wordcount-0.0.1-SNAPSHOT-jar-with-dependencies.jar

运行成功后,就可以看到HDFS中出现output目录,并且能够得到与在eclipse中执行相同的结果。

能够打包到实际集群上并成功运行,表明我们在Windows上本地运行不会影响MapReduce程序开发的正确性。

附录

点击此处下载,下载的文件包括:hadoop 2.5.2.tar.gz,hadoop-common-2.2.0-bin-master.zip,hadoop-eclipse-plugin-2.5.2.jar。

猜你喜欢

转载自blog.csdn.net/xkjcf/article/details/80525842
今日推荐