Hadoop安装指南

12年前

支持平台

  • GNU/Linux是产品开发和运行的平台。 Hadoop已在有2000个节点的GNU/Linux主机组成的集群系统上得到验证。
  • Win32平台是作为开发平台支持的。由于分布式操作尚未在Win32平台上充分测试,所以还不作为一个生产平台被支持。    

所需软件

LinuxWindows所需软件包括:

  1. JavaTM1.5.x,必须安装,建议选择Sun公司发行的Java版本。
  2. ssh 必须安装并且保证 sshd一直运行,以便用Hadoop 脚本管理远端Hadoop守护进程。    

一般来说,现在的Linux都带有open ssh,可以通过下面的命令看看是不是启用了sshd ps -ef | grepsshd,如果没有启用可以在/etc/init.d里面找到启用

Windows下的附加软件需求

  1. Cygwin - 提供上述软件之外的shell支持。

安装软件

如果你的集群尚未安装所需软件,你得首先安装它们。

Ubuntu Linux为例:

$ sudo apt-get install ssh
$ sudo apt-get install rsync

Cent OS Linux为例,本示例采用的是Cent OS Linux

yum install rsync

Windows平台上,如果安装cygwin时未安装全部所需软件,则需启动cyqwin安装管理器安装如下软件包:

  • openssh - Net     类

下载

为了获取Hadoop的发行版,从Apache的某个镜像服务器上下载最近的 稳定发行版。这里下载的是0.20.203.0版本

新建系统Hadoop用户

Hadoop要求所有机器上hadoop的部署目录结构要相同,并且都有一个相同的用户名的帐户,所以需要每台机器见一个同名的用户。

在这4台机器上建hadoop用户,密码:hadoop,默认路径/home/hadoop/

运行Hadoop集群的准备工作

解压所下载的Hadoop发行版。编辑conf/hadoop-env.sh文件,至少需要将JAVA_HOME设置为Java安装根路径。

尝试如下命令:
$ bin/hadoop
将会显示hadoop脚本的使用文档。

现在你可以用以下三种支持的模式中的一种启动Hadoop集群:

  • 单机模式
  • 伪分布式模式
  • 完全分布式模式

单机模式的操作方法

默认情况下,Hadoop被配置成以非分布式模式运行的一个独立Java进程。这对调试非常有帮助。

下面的实例将已解压的conf目录拷贝作为输入,查找并显示匹配给定正则表达式的条目。输出写入到指定的output目录。

hadoop根目录下:
$ mkdir input
$ cp conf/*.xml input
$ bin/hadoop jar hadoop-examples-*.jar grep input output 'dfs[a-z.]+'
$ cat output/*

说明:这里的grep不是通常意义的grep,语句的意思是,使用hadoop运行hadoop-examples-*.jargrep作为jar的参数,input作为输入,output作为输出。通常意义的grep如下:

grepglobal search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。Unixgrep家族包括grepegrepfgrep

 

伪分布式模式的操作方法

Hadoop可以在单节点上以所谓的伪分布式模式运行,此时每一个Hadoop守护进程都作为一个独立的Java进程运行。

配置

使用如下的conf/core-site.xml:

<configuration>

  <property>

    <name>fs.default.name</name>

    <value>hdfs://localhost:9000/</value>

  </property>

</configuration>

使用如下的conf/hdfs-site.xml:

<configuration>

  <property>

    <name>dfs.replication</name>

    <value>1</value>

  </property>

</configuration>

使用如下的conf/mapred-site.xml:

<configuration>

  <property>

    <name>mapred.job.tracker</name>

    <value>localhost:9001/</value>

  </property>

</configuration>

免密码ssh设置

注意:使用非root用户登录,此处的用户名为hadoop

现在确认能否不输入口令就用ssh登录localhost:
$ ssh localhost

如果不输入口令就无法用ssh登陆localhost,执行下面的命令:
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

#密钥拷贝为认证keys,将id_dsa.pub文件内容追加authorized_keys
$ cat ~/.ssh/id_dsa.pub >>~/.ssh/authorized_keys  此脚本

注意:root用户直接执行上面脚本就可以实现不输人口令自动ssh登录,但是非root用户还需要做如下工作:

1)修改/etc/ssh/sshd_config 然后用root账户执行/sbin/servicesshd restart重启

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile     .ssh/authorized_keys

 2)执行chmod 600 ~/.ssh/authorized_keys

特别提示:如果报Agent admitted failure to sign using the key错误

则执行ssh-add会出现下述讯息.

Identity added: /home/user/.ssh/id_rsa(/home/user/.ssh/id_rsa)

再次连线就正常囉~

执行

格式化一个新的分布式文件系统:
$ bin/hadoop namenode -format

启动Hadoop守护进程:
$ bin/start-all.sh

注意:如果启动的时候报如下错:

Unrecognizedoption: -jvm  

则解决办法如下:

可以修改的地方有两个

     第一个(次要的):/usr/local/hadoop/conf/hadoop-env.sh
      
修改参数: export HADOOP_HEAPSIZE=256   #默认值为1000M,为Java虚拟机占用的内存的大小

第二个(主要的)
      
查看/usr/local/hadoop/bin/hadoop源码:
      ####################################################################
      if [[ $EUID -eq0 ]]; then
          HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS"
       else
          HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS"
       fi
      ####################################################################
      如果以root身份启动,则hadoop启动java虚拟机时,会带上-jvm参数。
       不同的java版本,启动参数可能会不一致,由此导致以上问题。

因此,
      
新建一个hadoop用户,
       重新初始化操作:#./hadoopnamenode -format
       再次启动
hadoop:#./start-all.sh
       正常。

Hadoop守护进程的日志写入到${HADOOP_LOG_DIR}目录 (默认是${HADOOP_HOME}/logs).

浏览NameNodeJobTracker的网络接口,它们的地址默认为:

将输入文件拷贝到分布式文件系统:
$ bin/hadoop fs -put conf input

运行发行版提供的示例程序:
$ bin/hadoop jar hadoop-examples-*.jar grep inputoutput 'dfs[a-z.]+'

查看输出文件:

将输出文件从分布式文件系统拷贝到本地文件系统查看:
$ bin/hadoop fs -get output output
$ cat output/*

或者

在分布式文件系统上查看输出文件:
$ bin/hadoop fs -cat output/*

完成全部操作后,停止守护进程:
$ bin/stop-all.sh

完全分布式模式的操作方法

下面搭建四台机器的Hadoop集群,四台机器ip分别为:192.168.221.128NameNode, 192.168.221.129JobTracker, 192.168.221.130DataNode1, 192.168.221.131DataNode2

SSH互联

Ssh本机无密码访问前面已经介绍过了,下面只介绍与远程机器ssh无密码访问。

1.   把本地的公钥复制到另外的机器(比如192.168.221.129)上:

scp ~/.ssh/id_dsa.pub hadoop@192.168.221.129:~/.ssh/128_dsa.pub

这个会要求输入129的密码,照提示输入即可。

在配置从NameNode(192.168.221.128免密码ssh访问)JobTracker192.168.221.129)时,一定要在NameNode上执行这个命令。虽然我不知道为什么,但是多次尝试下来,就只有这样才能成功。或许还有其它办法,以后有机会了再研究研究。

2.   在另外一台机器上JobTracker192.168.221.129),把刚刚拷贝过来的公钥导入authorized_keys

cat ~/.ssh/128_dsa.pub >> authorized_keys

3.   128上连接129

ssh 192.168.221.129

同样第一次连接的话会询问是否添加机器以及要求输入密码,第二次就不用了。

至此就算配置好了ssh从其中一台到另外一台的免密码访问了,把这个操作在各个机器上两两执行,就可以让任意一台机器免密码访问另外任意一台机器了。

如果配置过程中有失误,想要重新来,可以删除.ssh下的所有东西,从头来过。

Hadoop集群

关于Hadoop的配置,按照我的理解,应该有六个文件需要修改,它们都在Hadoopconf文件夹下,分别是:

masters/slavers:配置mastersslavers的机器IP

hadoop-env.shHadoop运行时的环境变量,比如JAVA_HOMELOG之类的

core-site.xmlHadoop的核心配置文件,对应并覆盖core-default.xml中的配置项

hdfs-site.xmlHDFS的配置文件,对应并覆盖hdfs-default.xml中的配置项

mapred-site.xmlMap/Reduce的配置文件,对应并覆盖mapred-default.xml中的配置项

上面提到的三个*-default.xmlHadoop的默认配置项,理论上都是只读的,如果要修改,就通过对应的用户配置文件来覆盖其设置。

1、先配置masters/slaversNameNodeJobTrackermasterDataNode01DataNode02salvers

Masters

1. vi /hadoop/conf/masters

masters文件内容如下:

1. 192.168.221.128

2. 192.168.221.129  

Slavers

1. vi /hadoop/conf/slavers  

slavers文件内容如下:

1. 192.168.221.130  

2. 192.168.221.131  

2、先配置hadoop-env.sh,这里最重要的是配置JAVA_HOME,在我的机器上是这样的:

1. export JAVA_HOME=/usr/lib/jvm/java-6-sun  

其余的可以考虑配置日志文件路径:

1. export HADOOP_LOG_DIR=${HADOOP_HOME}/logs  

3、配置core-site.xml,通过文档可以知道这里一般是配置NameNode的地址,即机器名或IP

<configuration>   

   <property> 

       <name>fs.default.name</name>    

       <value>hdfs://192.168.221.128:9000</value>    

</property>  

</configuration>  

4、配置hdfs-site.xml,这里一般配置文件存放路径以及文件权限:

<configuration>   

   <property>   

      <!-- DFS中存储文件命名空间信息的目录 -->   

       <name>dfs.name.dir</name>   

       <value>/home/hadoop/Research/hadoop-0.20.203.0/dfs/name</value>   

   </property>   

   <property>   

   <!-- DFS中存储文件数据的目录 -->   

       <name>dfs.data.dir</name>    

       <value>/home/hadoop/Research/hadoop-0.20.203.0/dfs/data</value>   

   </property>   

   <property>   

   <!-- 是否对DFS中的文件进行权限控制(测试中一般用false)-->   

       <name>dfs.permissions</name>   

       <value>false</value>   

   </property>   

</configuration>  

5、配置mapred-site.xml这里配置的东西有很多,都是跟Map-Reduce相关的,不过暂时先配置如下几项:

<configuration> 

    <property>   

        <!-- JobTracker节点-->   

        <name>mapred.job.tracker</name>   

       <value>192.168.221.129:9001</value>   

    </property>   

    <property>   

        <!-- map/reduce的系统目录(使用的HDFS的路径)-->   

       <name>mapred.system.dir</name>   

        <value>/home/hadoop/Research/hadoop-0.20.203.0/mapred/system</value>   

    </property>   

    <property>   

        <!-- map/reduce的临时目录(可使用“,”隔开,设置多重路径来分摊磁盘IO-->   

       <name>mapred.local.dir</name>   

        <value>/home/hadoop/Research/hadoop-0.20.203.0/mapred/local</value>   

    </property>   

</configuration> 

这些配置都可以在一台机器上搞定,由于Hadoop所有机器是使用同样的配置,所以可以通过scp命令将conf下的内容拷贝复制到各个机器上:

       以下当前路径默认为hadoop-0.20.203.0的上一级目录:

scp –rphadoop-0.20.203.0/confhadoop@192.168.221.129:/home/hadoop/Research/hadoop-0.20.203.0

scp –rphadoop-0.20.203.0/confhadoop@192.168.221.130:/home/hadoop/Research/hadoop-0.20.203.0

scp –rphadoop-0.20.203.0/confhadoop@192.168.221.131:/home/hadoop/Research/hadoop-0.20.203.0

只复制conf是由于我拷贝虚拟机时就已经把JAVA,Hadoop都安装好后才拷贝的,这样可以保证所有文件在同一目录。

启动

然后,激动人心的时刻到了,所有配置都搞定了,我们可以启动了!

不过还有一件事情必须要先做,格式化名称空间。

NameNode上,执行如下命令:

1. cd /hadoop/bin  

2. ./hadoop namenode -format  

执行后结果如下:

然后就可以执行最后一个命令了:

1. ./start-all.sh  

如果一切顺利的话,应该就成功了:

浏览NameNodeJobTracker的网络接口,它们的地址默认为:

将输入文件拷贝到分布式文件系统:
$ bin/hadoop fs -put conf input

运行发行版提供的示例程序:
$ bin/hadoop jar hadoop-examples-*.jar grep inputoutput 'dfs[a-z.]+'

运行上述程序如果遇到java.net.NoRouteToHostException: No route to host错误,则

解决方法:网上有人说是/etc/hosts下面的ip和机器名没写对,有人说是防火墙没关。我遇到这个问题是由于防火墙没关,/etc/init.d/iptables stop关闭防火墙。

 

运行成功后查看输出文件:

将输出文件从分布式文件系统拷贝到本地文件系统查看:
$ bin/hadoop fs -get output output
$ cat output/*

或者

在分布式文件系统上查看输出文件:
$ bin/hadoop fs -cat output/*

完成全部操作后,停止守护进程:
$ bin/stop-all.sh

如果要关闭的话,可以执行

1. ./stop-all.sh  

 

 

附录:常见错误解决:

http://hi.baidu.com/wyw5257/blog/item/39e51fd3c93d451c3af3cf28.html

1. 如果在bin/hadoopdfs -put /home/test-in input该过程中出现"can only bereplicated to node 0, instead of 1",以下两种办法,均可尝试。

1)解决办法一:

打开http://localhost:50070/dfshealth.jsp查看,确定了livenode数目为你的机器实际数目时,再进行put(注:如果有个别datanode没有启动起来,这是正常的,重新格式化文件系统,然后start-up)。

2)解决办法二:

当执行 #bin/hadoop dfs -put input input时,报错 ...,could only bereplicated to 0 nodes, instead of 1,网上查了查,最后确定应该是iptables问题。

如果你的 conf/core-site.xml的配置是:

<configuration>
     <property>
        <name>fs.default.name</name>
        <value>hdfs://machine1:9000/</value>
     </property>
</configuration>

那么你应该将machine19000端口打开:

#iptables -I INPUT -p tcp --dport 9000 -j ACCEPT

然后可以查看 

http://machine1:50070/dfshealth.jsp(你应该将500070端口也打开)

 

 再执行,又报别的错:hdfs.DFSClient: Exception in createBlockOutputStreamjava.net.ConnectException: Connection refused

 应该是datanode上的端口不能访问,到datanode上修改iptables

#iptables -IINPUT  -s machine1 -p tcp  -j ACCEPT

 

 OK了!

 

 

2.如果put时出现java.io.IOException:Not a file: hdfs://localhost:9000/user/icymary/input/test-in 

解决办法是bin/hadoop dfs -rmr input

bin/hadoop dfs -put /home/test-in input

原因是,当执行了多次put之后,就会在分布式文件系统中生成子目录,删除重新put即可。

 

3.如果在 bin/hadoop jarhadoop-0.16.0-examples.jar wordcount input output该过程中出现"canonly be replicated to node 0, instead of 1",解决办法是,给磁盘释放更多的空间,当时我的空间只有200M了,运行一直报错,折腾了1天。

 

4.如果 bin/hadoop jarhadoop-0.16.0-examples.jar wordcount input output过程中

INFO mapred.JobClient: map 0% reduce 0%

且一直卡住,在log日志中也没有出现异样,那么解决办法是,把/etc/hosts里面多余的机器名删掉,即可。