Hadoop安装指南
支持平台
- GNU/Linux是产品开发和运行的平台。 Hadoop已在有2000个节点的GNU/Linux主机组成的集群系统上得到验证。
- Win32平台是作为开发平台支持的。由于分布式操作尚未在Win32平台上充分测试,所以还不作为一个生产平台被支持。
所需软件
Linux和Windows所需软件包括:
- JavaTM1.5.x,必须安装,建议选择Sun公司发行的Java版本。
- ssh 必须安装并且保证 sshd一直运行,以便用Hadoop 脚本管理远端Hadoop守护进程。
一般来说,现在的Linux都带有open ssh,可以通过下面的命令看看是不是启用了sshd: ps -ef | grepsshd,如果没有启用可以在/etc/init.d里面找到启用
Windows下的附加软件需求
- 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-*.jar,grep作为jar的参数,input作为输入,output作为输出。通常意义的grep如下:
grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。Unix的grep家族包括grep、egrep和fgrep。
伪分布式模式的操作方法
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).
浏览NameNode和JobTracker的网络接口,它们的地址默认为:
- NameNode - http://localhost:50070/
- JobTracker - http://localhost:50030/
将输入文件拷贝到分布式文件系统:
$ 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.128(NameNode), 192.168.221.129(JobTracker), 192.168.221.130(DataNode1), 192.168.221.131(DataNode2)
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访问)JobTracker(192.168.221.129)时,一定要在NameNode上执行这个命令。虽然我不知道为什么,但是多次尝试下来,就只有这样才能成功。或许还有其它办法,以后有机会了再研究研究。
2. 在另外一台机器上JobTracker(192.168.221.129),把刚刚拷贝过来的公钥导入authorized_keys
cat ~/.ssh/128_dsa.pub >> authorized_keys
3. 从128上连接129:
ssh 192.168.221.129
同样第一次连接的话会询问是否添加机器以及要求输入密码,第二次就不用了。
至此就算配置好了ssh从其中一台到另外一台的免密码访问了,把这个操作在各个机器上两两执行,就可以让任意一台机器免密码访问另外任意一台机器了。
如果配置过程中有失误,想要重新来,可以删除.ssh下的所有东西,从头来过。
Hadoop集群
关于Hadoop的配置,按照我的理解,应该有六个文件需要修改,它们都在Hadoop的conf文件夹下,分别是:
masters/slavers:配置masters和slavers的机器IP
hadoop-env.sh:Hadoop运行时的环境变量,比如JAVA_HOME,LOG之类的
core-site.xml:Hadoop的核心配置文件,对应并覆盖core-default.xml中的配置项
hdfs-site.xml:HDFS的配置文件,对应并覆盖hdfs-default.xml中的配置项
mapred-site.xml:Map/Reduce的配置文件,对应并覆盖mapred-default.xml中的配置项
上面提到的三个*-default.xml是Hadoop的默认配置项,理论上都是只读的,如果要修改,就通过对应的用户配置文件来覆盖其设置。
1、先配置masters/slavers,NameNode和JobTracker是master,DataNode01和DataNode02是salvers
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
如果一切顺利的话,应该就成功了:
浏览NameNode和JobTracker的网络接口,它们的地址默认为:
- NameNode - http://localhost:50070/
- JobTracker - http://localhost:50030/
将输入文件拷贝到分布式文件系统:
$ 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>
那么你应该将machine1的9000端口打开:
#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里面多余的机器名删掉,即可。