这篇文章介绍的是简单的配置Hadoop集群的方法,适合实验和小型项目用,正式运行的集群需要用更正规的方法和更详细的参数配置,不适合使用这篇文章。
相关随笔:
- 用python + hadoop streaming 编写分布式程序(一) -- 原理介绍,样例程序与本地调试
- 用python + hadoop streaming 编写分布式程序(二) -- 在集群上运行与监控
- 用python + hadoop streaming 编写分布式程序(三) -- 自定义功能
安装 JDK
在终端输入
$ java -version
如果有反应,说明已安装过jdk。如果显示的信息里出现了类似OpenJDK的字样,如
java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9.2) (6b20-1.9.2-0ubuntu1~10.04.1) OpenJDK Server VM (build 19.0-b09, mixed mode)
则需要卸载OpenJDK,改用Hadoop使用的Sun JDK。
关于如何卸载OpenJDK和安装Sun JDK,参考 How to correctly remove OpenJDK/OpenJRE and set SunJDK/SunJRE as Default
*注:如果不想用ppa安装,也可以用解压缩-加链接-配置环境变量的办法,网上教程很多,具体google “sun jdk install”即可,此处不赘述
安装完成后检查
$ java -version
如果出现
java version "1.7.0_04" Java(TM) SE Runtime Environment (build 1.7.0_04-b20) Java HotSpot(TM) 64-Bit Server VM (build 23.0-b21, mixed mode)
说明java安装成功。
$ echo $JAVA_HOME
出现java的安装目录,说明环境变量添加成功。同理需要查看$CLASSPATH,并查看java安装目录下的bin文件夹是否添加进了$PATH
设置专用账户
hadoop会利用用户名来配置目录结构,为了配置方便最好保证每台机子上都有一个给hadoop使用的账户,且名字相同(如果每台机子账户不同,需要做很多多余的配置)。
添加用户与用户组
假设需要添加hd用户组,再在其中添加hadoop用户
$ sudo addgroup hd $ sudo adduser --ingroup hd hadoop
添加 sudo 权限
用
$ sudo visudo
打开etc/sudoers为新添加的用户添加sudo权限。
找到
# User privilege specification root ALL=(ALL:ALL) ALL
在下面加上
hadoop ALL=(ALL:ALL) ALL
就能让hadoop这个用户拥有sudo的权限。其他用户名类推。
注意这个文件只能用visudo打开,且绝对不能修改其权限。
切换用户
$ su hadoop
即可切换到hadoop这个用户。以下操作最好都在为hadoop预留的账户中进行(因为ssh的钥匙都是保存在用户文件夹中的)
配置 host 与打通连接
修改 /etc/hostname
为了方便管理,可以将每台机器的hostname修改掉。比如,根据为每台机器设置的不同角色,分别命名为master,slave1,slave2……
ubuntu上需要
$ sudo vi /etc/hostname
默认是机器的名字(比如ubuntu),将其修改成对应的hostname,比如master,slave1等
修改后不会立即生效,需要重启。如果想立刻生效,直接在终端敲类似命令:
$ hostname master
想要检查当前hostname,可以直接敲
$ hostname
修改 /etc/hosts
为了方便记忆和管理,最好将每台机器的ip在hosts文件内做映射
$ sudo vi /etc/hosts
-
第一行如果是
127.0.0.1 localhost
最好保留。如果这里的127.0.0.1后跟着的是其他东西,最好改成localhost
-
ubuntu下建议将默认出现在第二行的
127.0.1.1 xxxx`
改成
实际本机ip xxxx
其中xxxx指本机的hostname,可根据上一步骤改成的hostname对应修改
- 然后添加其他主机ip对应的映射
- 关于hosts配置的官方建议,注意第3项
- [stackoverflow] 可正常搭建的/etc/hosts样例
检查防火墙
如果开启了防火墙,建议关闭或打开需要联通的端口。
ubuntu一般自带的是ufw防火墙,如何查看与关闭防火墙、配置特定端口请看 Ubuntu中文wiki上的文档
关闭 ipv6
请看 Micheal Noll的教程中关于禁用ipv6的步骤
检查联通状况
为每台机器设置好hosts文件和hostname后,在每台机器上ping其他机器即可。
如果机器比较多,可以写个脚本帮忙。同样地,hosts文件可以在一台机器上配置好后复制到其他机器上,对涉及到127.0.1.1和自己的ip的部分稍作修改即可。
配置无密码 ssh
检查 openssh-server
ubuntu下
$ sudo apt-get install openssh-server
即可。有则提示已经是最新版,没有或版本太老则安装或更新。
修改配置与生效
配置无密码SSH过程中可能会出现Host key verification failed错误。最简单的解决办法之一就是在每台机的/etc/ssh/ssh_config中设置
StrictHostKeyChecking no
如果这项已经设置过,修改之。如果没有设置过(默认应该是设置为ask且注释掉的),可以在下面添加,或取消注释并修改为no。
- 注意这里一般是对Host *设置的StrictHostKeyChecking no,会对所有SSH key的检查都放宽要求。如果不想这么做,可以google其他解决方案。
在/etc/ssh/sshd_config中设置
RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys
同样可以修改、取消注释或在下面添加。
然后
service ssh restart
令配置生效。
生成密钥
如果之前机子上生成过密钥可以跳过这一步,否则需要生成密钥。 使用
$ ssh-keygen -t rsa -P ''
一路回车,在~/.ssh目录下生成一对没有passphrase的密钥。
这里不设置passphrase是为了后面认证登陆的时候不用每台机子都输入,会方便一些。
接着
cat id_rsa.pub >> authorized_keys
对生成的公钥进行授权
检查权限
$ chmod 600 ~/.ssh/authorized_keys $ chmod 700 ~/.ssh
保证关键的文件和文件夹权限正确(太高或太低的权限会导致无法无密码ssh)
分发公钥
为了方便我们可以让所有机器都能互相无密码ssh。在每台salve用
$ ssh-copy-id -i id_rsa.pub master
将公钥汇总到master的authorized_key中,再让master将公钥分发到每台机器上即可。比如使用
$ scp ~/.ssh/authorized_keys hadoop@slave1:~/.ssh/authorized_keys
即可将master的authorized_keys覆盖掉slave1的authorized_keys(注意这是覆盖,如果只是想追加,可以用cat+管道,具体google即可)
安装 Hadoop
获取及解压 (每台)
去到官网下载安装包,安装路径随意,按照Linux的惯例可以自己看着装到/opt或者/usr/local,或者直接安装在用户文件夹。
这里将安装包解压到/usr/local/hadoop,然后在/usr/local目录下
chown -R hd:hadoop hadoop
确保能够随意操作这个文件夹。
配置环境变量 (每台)
再配置环境变量,指明Hadoop所在路径,将路径下的bin文件夹加入PATH以使用Hadoop提供的各种脚本 编辑hadoop用户的.bashrc文件
$ vi ~/.bashrc
添加
export HADOOP_HOME=/usr/local/hadoop export PATH=$PATH:$HADOOP_HOME/bin
注:$HADOOP_HOME是旧版Hadoop用的环境变量名,所以如果你用这个名字,在运行Hadoop的时候会得到
$HADOOP_HOME is deprecated
的警告。但是这里设成$HADOOP_HOME也不会有什么大碍。如果你觉得这个警告很烦不想看到,也可以用$HADOOP_PREFIX这个新版的名字。
接下来还需要配置hadoop-env.sh中的JAVA_HOME为对应jdk安装目录。
$ vi $HADOOP_HOME/conf/hadoop-env.sh
找到
export JAVA_HOME=....
这一行,将等号后的东西改成你JAVA的实际安装目录。
配置 masters 及 slaves (master上)
配置conf下的masters及slaves文件为对应分配好的hostname。
如masters
master
slaves
slave1 slave2 ...
配置 *-site.xml (每台)
配置core-site.xml。有一些配置是最好要改的,参见[YDN] Hadoop 配置注意事项 的Important Directories一节。这里修改两个比较重要的配置,默认dfs.name.dir、dfs.data.dir和mapred.system.dir均放在hadoop.tmp.dir下,这些文件夹存有NameNode和DataNode的数据和各种系统资料,而hadoop.tmp.dir却默认放在/tmp/hadoop-${user.name},这意味着重启之后这些东西很可能全都没了。在正式的集群中,这些子文件夹最好放在不依赖于hadoop.tmp.dir的地方。这里为了方便,我们直接先修改hadoop.tmp.dir来改变其他子文件夹,将它放在hadoop安装目录的tmp文件夹,并且显式指明默认的Namenode位置fs.default.name为master的9000端口。
<configuration> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/tmp</value> </property> <property> <name>fs.default.name</name> <value>hdfs://master:9000</value> </property> </configuration>
参数意义参见http://hadoop.apache.org/docs/r1.0.4/core-default.html,往右拖可以看到description(这令人无力的表格列宽……)
配置hdfs-site.xml,这里修改dfs.replication即备份多少副本,1的话就是不备份。注意这个值不能超过Datanode的数目。
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <configuration>
参数意义参见http://hadoop.apache.org/docs/r1.0.4/hdfs-default.html
配置mapred-site.xml,这里指明所有的node在找jobtracker时都要去找master的9001端口。
<configuration> <property> <name>mapred.job.tracker</name> <value>http://master:9001</value> </property> </configuration>
参数意义参见http://hadoop.apache.org/docs/r1.0.4/mapred-default.html
在实际运行的时候也建议将mapred.tasktracker.reduce.tasks.maximum的值增大以增加reducer slots的数目,提高效率。一般指定mapred-site.xml为所在机子的CPU核数-1比较合理。
添加路径
在hadoop目录下新建tmp文件夹(这里是为了配合上一步中core-site.xml中指定的hadoop.tmp.dir。如果你没有用上一步一样的路径也可以,只要确保这个文件夹存在就行)。
运行 Hadoop
格式化 HDFS
先确保tmp文件夹下都是空的(否则spaceID不一致又不去手动改的话会各种报错),然后`
$ hadoop namenode -format
启动 Hadoop
启动时分开启动,start-all是给单节点用的
$ start-dfs.sh $ start-mapred.sh
检查 jps
这时候可以检查守护进程是否启动。master上运行
$ jps
应该会看到NameNode,SecondaryNameNode,JobTracker。slave上运行jps则会看到DataNode和TaskTracker。 如果无法执行jps,可以检查一下java安装目录下的bin文件夹是否在$PATH环境变量中。如果没有,需要修改.bashrc或/etc/profile配置好环境变量。
检查 HDFS
$ hadoop dfsadmin -report
会看到整个hdfs的状态,可以检查一下datanode是否都检测到了。
检查 Web UI
可以在master的浏览器上访问
http://localhost:50070/ 检查namenode,也可以查看HDFS http://localhost:50030/ 可以检查job的运行状态 http://localhost:50060/ 检查task的运行状态
测试运行 example
pi
在hadoop安装目录下
$ hadoop jar hadoop-examples-1.0.4.jar pi 10 100
wordcount
Hadoop Streaming with python
参见[Michael Noll系列教程] 使用 python 编写 Hadoop 程序
参考链接
- [官方教程] Hadoop tutorials on YouTube (强烈推荐)
- [官方教程] Getting Started
- [YDN] Hadoop 配置注意事项
- [Michael Noll系列教程] 单节点配置
- [Michael Noll系列教程] 多节点配置
- [Michael Noll系列教程] 使用 python 编写 Hadoop 程序
- [stackoverflow] 可正常搭建的/etc/hosts样例
相关资源
Troubleshooting
Datanode 无法启动
很常见的一个原因是在tmp文件夹非空的时候执行了hadoop namenode -format。解决方案有两个:
- 删掉hadoop.tmp.dir(可能还有dfs.name.dir和dfs.data.dir,如果你有自己设定)指定路径下的东西,然后hadoop namenode -format
- 修改spaceID,参见http://www.youtube.com/watch?v=jJmOAvxE2GU
Tips
如何在运行时撤下 Slave
参见http://www.youtube.com/watch?v=jJmOAvxE2GU,简单来说就是
- 配置hdfs-site.xml里的dfs.hosts.exclude为一个文件
- 在这个文件里写上要撤下的slave的host name
- 执行 hadoop dfsadmin -refreshNodes