原文地址:http://www.linuxidc.com/Linux/2015-01/112029.htm


我的环境是:Ubuntu14.04+Hadoop2.6.0+JDK1.8.0_25

官网2.6.0的安装教程:http://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-common/SingleCluster.html

为了方面配置,我在每台机器上都使用了hadoop用户来操作,这样做的确够方便。

结点信息:(分布式集群架构:master为主节点,其余为从节点)

机器名

IP

作用

master

122.205.135.254

NameNode and JobTracker 

slave1

122.205.135.212

DataNode and TaskTracker 

1.JDK的安装

首先Hadoop运行需要Java的支持,所以必须在集群中所有的节点安装JDK,

jdk1.8.0_25的详细安装见我的另一篇文章:http://www.linuxidc.com/Linux/2015-01/112030.htm 注意:最好将集群中的JDK都安装在同一目录下,便于配置。实践中,笔者一般将JDK安装在/usr/java这个目录,但并不是必须的。

2.配置hosts文件

修改集群中所有机器的/etc/hosts,打开该文件的命令如下:

sudo gedit /etc/hosts

添加:

122.205.135.254 master

122.205.135.212 slave1

如图所示:


运行hadoop项目的NameNode的main方法_apache

注意:这里的master、slave1、slave2等等,指的是机器的机器名(使用命令hostname可以查看本机的机器名),切记,如果不是机器名的话会出问题的,并且集群中所有结点的机器名都应该不一样。

3.SSH无密码登录

Hadoop主从节点无密码登录的安装配置详细见我的另一篇章:点击打开链接

4.Hadoop的安装与配置

(1).下载解压Hadoop稳定版

我用的是hadoop-2.6.0,下载地址:http://mirrors.hust.edu.cn/apache/hadoop/common/stable/

将下载后的Hadoop 拷贝到hadoop目录下,解压到master服务器的/hadoop目录下(配置好master结点后再将其复制到其它的服务器上,一般来说,群集中所有的hadoop都安装在同一目录下):

解压命令如下:

tar xzfv hadoop-2.6.0.tar.gz


运行hadoop项目的NameNode的main方法_apache_02

(2).配置Hadoop

1.修改hadoop-2.6.0/etc/hadoop/hadoop-env.sh,添加JDK支持:
 export JAVA_HOME=/usr/java/jdk1.8.0_25
 如果不知道你的JDK目录,使用命令echo $JAVA_HOME查看。
 2.修改hadoop-2.6.0/etc/hadoop/core-site.xml
 注意:必须加在<configuration></configuration>节点内
 <configuration>
 <property>
         <name>hadoop.tmp.dir</name>
         <value>/home/hadoop/hadoop-2.6.0/tmp</value>
         <description>Abase for other temporary directories.</description>
     </property>
     <property>
         <name>fs.default.name</name>
         <value>hdfs://master:9000</value>
     </property>
 </configuration> 3.修改hadoop-2.6.0/etc/hadoop/hdfs-site.xml
 <property>
     <name>dfs.name.dir</name>
     <value>/home/hadoop/hadoop-2.6.0/dfs/name</value>
     <description>Path on the local filesystem where the NameNode stores the namespace and transactions logs persistently.</description>
 </property>
  
 <property>
     <name>dfs.data.dir</name>
     <value>/home/hadoop/hadoop-2.6.0/dfs/data</value>
     <description>Comma separated list of paths on the local filesystem of a DataNode where it should store its blocks.</description>
 </property>
 <property>
     <name>dfs.replication</name>
     <value>1</value>
 </property> 4.修改hadoop-2.6.0/etc/hadoop/mapred-site.xml
 <property>
     <name>mapred.job.tracker</name>
     <value>master:9001</value>
     <description>Host or IP and port of JobTracker.</description>
 </property> 5. 修改hadoop-2.6.0/etc/hadoop/masters
 列出所有的master节点:
 master
 6.修改hadoop-2.6.0/etc/hadoop/slaves
 这个是所有datanode的机器,例如:
 slave1
 slave2
 slave3
 slave4
 7.将master结点上配置好的hadoop文件夹拷贝到所有的slave结点上
 以slave1为例:命令如下:
 scp -r  ~/hadoop-2.6.0 hadoop@slave1:~/
 安装完成后,我们要格式化HDFS然后启动集群所有节点。
 5.启动Hadoop
 1.格式化HDFS文件系统的namenode
 (这里要进入hadoop-2.6.0目录来格式化好些):
 cd hadoop-2.6.0  //进入hadoop-2.6.0目录
 bin/hdfs namenode -format  //格式化

2.启动Hadoop集群
启动hdrs命令如下:

sbin/start-dfs.sh //开启进程

成功的话输入jps会出现如下界面:


运行hadoop项目的NameNode的main方法_hadoop_03

补充,关闭hdfs集群的命令如下:

sbin/stop-dfs.sh

我们也可以通过网页来看是否正常安装与配置,地址如下:http://master:50070/


运行hadoop项目的NameNode的main方法_hadoop_04

CentOS安装和配置Hadoop2.2.0  http://www.linuxidc.com/Linux/2014-01/94685.htm

Ubuntu 13.04上搭建Hadoop环境 http://www.linuxidc.com/Linux/2013-06/86106.htm

Ubuntu 12.10 +Hadoop 1.2.1版本集群配置 http://www.linuxidc.com/Linux/2013-09/90600.htm

Ubuntu上搭建Hadoop环境(单机模式+伪分布模式) http://www.linuxidc.com/Linux/2013-01/77681.htm

Ubuntu下Hadoop环境的配置 http://www.linuxidc.com/Linux/2012-11/74539.htm

单机版搭建Hadoop环境图文教程详解 http://www.linuxidc.com/Linux/2012-02/53927.htm

搭建Hadoop环境(在Winodws环境下用虚拟机虚拟两个Ubuntu系统进行搭建) http://www.linuxidc.com/Linux/2011-12/48894.htm



6.实例运行(运行wordcount程序)

1.创建 input目录

Hadoop-2.6.0目录下创建input目录命令如下:

mkdir input


运行hadoop项目的NameNode的main方法_Hadoop_05

2.在input创建f1、f2并写内容

命令如下:

cat input/f1 Hello world  bye jj

cat input/f2 Hello world  bye jj

或者手动创建文本文件,并在里面放下英文文章

运行hadoop项目的NameNode的main方法_Hadoop_06

3.在hdfs创建/porrylee/input目录

命令如下:

bin/hadoop fs  -mkdir /porrylee

bin/hadoop fs  -mkdir /porrylee/input

4.将f1、f2文件copy到hdfs /porrylee/input目录

命令如下:

bin/hadoop fs  -put input/ /porrylee

5.查看hdfs上是否有f1、f2文件

命令如下:

bin/hadoop fs -ls /porrylee/input/


运行hadoop项目的NameNode的main方法_Hadoop_07

6、执行wordcount程序

命令如下:

bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.0.jar wordcount /porrylee/input/ /output/wordcount3

执行完毕后如下,


运行hadoop项目的NameNode的main方法_Hadoop_08

7.查看执行结果

命令如下:

hadoop@master:~/hadoop-2.6.0$ bin/hdfs dfs -cat /output/wordcount3/*

执行后,可以看到统计结果

运行hadoop项目的NameNode的main方法_hadoop_09

7.附录(核心代码)

package com.felix;
 import java.io.IOException;
 import java.util.Iterator;
 import java.util.StringTokenizer;
 import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.io.IntWritable;
 import org.apache.hadoop.io.LongWritable;
 import org.apache.hadoop.io.Text;
 import org.apache.hadoop.mapred.FileInputFormat;
 import org.apache.hadoop.mapred.FileOutputFormat;
 import org.apache.hadoop.mapred.JobClient;
 import org.apache.hadoop.mapred.JobConf;
 import org.apache.hadoop.mapred.MapReduceBase;
 import org.apache.hadoop.mapred.Mapper;
 import org.apache.hadoop.mapred.OutputCollector;
 import org.apache.hadoop.mapred.Reducer;
 import org.apache.hadoop.mapred.Reporter;
 import org.apache.hadoop.mapred.TextInputFormat;
 import org.apache.hadoop.mapred.TextOutputFormat;
 /**
  * 
  * 描述:WordCount explains by Felix
  * @author Hadoop Dev Group
  */
 public class WordCount
 {
     /**
     * MapReduceBase类:实现了Mapper和Reducer接口的基类(其中的方法只是实现接口,而未作任何事情)
     * Mapper接口:
     * WritableComparable接口:实现WritableComparable的类可以相互比较。所有被用作key的类应该实现此接口。
     * Reporter 则可用于报告整个应用的运行进度,本例中未使用。 
     * 
     */
     public static class Map extends MapReduceBase implements
             Mapper<LongWritable, Text, Text, IntWritable>
     {
         /**
         * LongWritable, IntWritable, Text 均是 Hadoop 中实现的用于封装 Java 数据类型的类,这些类实现了WritableComparable接口,
         * 都能够被串行化从而便于在分布式环境中进行数据交换,你可以将它们分别视为long,int,String 的替代品。
         */
         private final static IntWritable one = new IntWritable(1);
         private Text word = new Text();
         
         /**
         * Mapper接口中的map方法:
         * void map(K1 key, V1 value, OutputCollector<K2,V2> output, Reporter reporter)
         * 映射一个单个的输入k/v对到一个中间的k/v对
         * 输出对不需要和输入对是相同的类型,输入对可以映射到0个或多个输出对。
         * OutputCollector接口:收集Mapper和Reducer输出的<k,v>对。
         * OutputCollector接口的collect(k, v)方法:增加一个(k,v)对到output
         */
         public void map(LongWritable key, Text value,
                 OutputCollector<Text, IntWritable> output, Reporter reporter)
                 throws IOException
         {
             String line = value.toString();
             StringTokenizer tokenizer = new StringTokenizer(line);
             while (tokenizer.hasMoreTokens())
             {
                 word.set(tokenizer.nextToken());
                 output.collect(word, one);
             }
         }
     }
     public static class Reduce extends MapReduceBase implements
             Reducer<Text, IntWritable, Text, IntWritable>
     {
         public void reduce(Text key, Iterator<IntWritable> values,
                 OutputCollector<Text, IntWritable> output, Reporter reporter)
                 throws IOException
         {
             int sum = 0;
             while (values.hasNext())
             {
                 sum += values.next().get();
             }
             output.collect(key, new IntWritable(sum));
         }
     }
     public static void main(String[] args) throws Exception
     {
         /**
         * JobConf:map/reduce的job配置类,向hadoop框架描述map-reduce执行的工作
         * 构造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等
         */
         JobConf conf = new JobConf(WordCount.class);
         conf.setJobName("wordcount");          //设置一个用户定义的job名称
         conf.setOutputKeyClass(Text.class);    //为job的输出数据设置Key类
         conf.setOutputValueClass(IntWritable.class);  //为job输出设置value类
         conf.setMapperClass(Map.class);        //为job设置Mapper类
         conf.setCombinerClass(Reduce.class);      //为job设置Combiner类
         conf.setReducerClass(Reduce.class);        //为job设置Reduce类
         conf.setInputFormat(TextInputFormat.class);    //为map-reduce任务设置InputFormat实现类
         conf.setOutputFormat(TextOutputFormat.class);  //为map-reduce任务设置OutputFormat实现类
         /**
         * InputFormat描述map-reduce中对job的输入定义
         * setInputPaths():为map-reduce job设置路径数组作为输入列表
         * setInputPath():为map-reduce job设置路径数组作为输出列表
         */
         FileInputFormat.setInputPaths(conf, new Path(args[0]));
         FileOutputFormat.setOutputPath(conf, new Path(args[1]));
         JobClient.runJob(conf);        //运行一个job
     }
 }