Hadoop集群环境的模拟
Hadoop是一个开源的分布式计算框架,本文讲述用几台虚拟机来搭建一个Hadoop集群环境的过程。
有关方面的详细文档官方网站就有,但个人建议花点时间,看看Tom White编著的Hadoop: The Definitive Guide,这样能更系统的了解Hadoop,毕竟,安装只是第一步,后续怎么应用才是关键。
测试环境
这里使用5台虚拟机来搭建集群,系统均使用slackware 13.37,软件都是完全安装,只启用ssh服务,为Hadoop提供一个纯粹的平台。
5台机器都在同一个网段,网络配置如下:
域名 | IP地址 |
---|---|
hadoop1.example.org | 192.168.176.51/24 |
hadoop2.example.org | 192.168.176.52/24 |
hadoop3.example.org | 192.168.176.53/24 |
hadoop4.example.org | 192.168.176.54/24 |
hadoop5.example.org | 192.168.176.55/24 |
角色划分:
- hadoop1作为主节点(master)、NameNode和JobTracker;
- hadoop2~hadoop5四个作为从节点(slave)、DataNode和TaskTracer;
- 暂不设立Secondary NameNode。
初始安装
集群规模很小,故暂不采用NFS等网络集中管理方案,下面这些操作在每台机器上都要做。
安装jdk
从Oracle下载jdk(Java Platform, Standard Edition Development Kit),当时的版本是Java SE 6 Update 31。安装:
sh jdk-6u31-linux-x64.bin mv jdk1.6.0_31/ /usr/local/
这里将安装文件放在/usr/local目录下。
添加用户
我们新建一个普通账户hadoop,而不是直接用root:
useradd -m -s /bin/bash hadoop
设置环境变量
以hadoop用户登录,编辑.profile,设置几个环境变量:
export LANG=en_US.UTF-8 export JAVA_HOME=/usr/local/jdk1.6.0_31 export PATH=$JAVA_HOME/bin:$HOME/bin:$PATH
安装hadoop
从官网下载安装包,当时的版本是hadoop-1.0.0.tar.gz。以hadoop用户登录:
mkdir tmp cd tmp/ tar xzvf hadoop-1.0.0.tar.gz mv hadoop-1.0.0/* ~/
这里将所有安装文件都放在用户主目录下。
编辑~/conf/hadoop-env.sh,设置JAVA_HOME:
# The java implementation to use. Required. export JAVA_HOME=/usr/local/jdk1.6.0_31
配置域名解析
由于网络规模很小,就不采用集中的DNS域名解析机制了,直接编辑/etc/hosts文件,添加其余所有节点的IP信息。
比如hadoop1的内容如下:
127.0.0.1 localhost 192.168.176.51 hadoop1.example.org hadoop1 192.168.176.52 hadoop2.example.org hadoop2 192.168.176.53 hadoop3.example.org hadoop3 192.168.176.54 hadoop4.example.org hadoop4 192.168.176.55 hadoop5.example.org hadoop5
比如hadoop3的内容:
127.0.0.1 localhost 192.168.176.53 hadoop3.example.org hadoop3 192.168.176.51 hadoop1.example.org hadoop1 192.168.176.52 hadoop2.example.org hadoop2 192.168.176.54 hadoop4.example.org hadoop4 192.168.176.55 hadoop5.example.org hadoop5
集群配置
接下来的操作只在主节点(master)上进行,即hadoop1。
ssh登录配置
Hadoop利用ssh来进行各节点的管理工作,在当前这个测试环境,至少要能让master采用无密码的方式ssh登录到所有节点(包括自己)。
为此,首先生成一对密钥:
ssh-keygen
接下来把密钥中的公钥附加到要登录节点的.ssh/authorized_keys文件里,通过ssh-copy-id命令完成:
ssh-copy-id hadoop1 ssh-copy-id hadoop2 ssh-copy-id hadoop3 ssh-copy-id hadoop4 ssh-copy-id hadoop5
进行一次登录测试,确保可以无交互的登录:
ssh localhost ssh hadoop1 ssh hadoop2 ssh hadoop3 ssh hadoop4 ssh hadoop5
配置文件
真正的大规模集群配置是很复杂的,这里只模拟一个最简单的集群,所以只做些基础的配置:
conf/core-site.xml
设置fs.default.name,指定NameNode(hadoop1):
<property> <name>fs.default.name</name> <value>hdfs://hadoop1</value> <description>The name of the default file system. A URI whose scheme and authority determine the FileSystem implementation. The uri's scheme determines the config property (fs.SCHEME.impl) naming the FileSystem implementation class. The uri's authority is used to determine the host, port, etc. for a filesystem.</description> </property>
conf/hdfs-site.xml
设置dfs.replication,指定文件系统存储块的重复数量:
<property> <name>dfs.replication</name> <value>3</value> <description>Default block replication. The actual number of replications can be specified when the file is created. The default is used if replication is not specified in create time. </description> </property>
conf/mapred-site.xml
设置mapred.job.tracker,指定JobTracker(hadoop1);同时也指定map和reduce任务的数量:
<property> <name>mapred.job.tracker</name> <value>hadoop1:9001</value> <description>The host and port that the MapReduce job tracker runs at. If "local", then jobs are run in-process as a single map and reduce task. </description> </property> <property> <name>mapred.map.tasks</name> <value>40</value> <description>The default number of map tasks per job. Ignored when mapred.job.tracker is "local". </description> </property> <property> <name>mapred.reduce.tasks</name> <value>8</value> <description>The default number of reduce tasks per job. Typically set to 99% of the cluster's reduce capacity, so that if a node fails the reduces can still be executed in a single wave. Ignored when mapred.job.tracker is "local". </description> </property>
conf/slaves
设置所有从节点的名称,每个节点一行:
hadoop2 hadoop3 hadoop4 hadoop5
文件同步
Hadoop没有提供一个集中的配置管理方案,配置文件在每个节点机器上都要有一份,同步工作由管理员负责。这里环境简单,所以直接手工搞定:
scp core-site.xml hdfs-site.xml mapred-site.xml slaves hadoop2:conf/ scp core-site.xml hdfs-site.xml mapred-site.xml slaves hadoop3:conf/ scp core-site.xml hdfs-site.xml mapred-site.xml slaves hadoop4:conf/ scp core-site.xml hdfs-site.xml mapred-site.xml slaves hadoop5:conf/
对于大规模的集群,手工显然是不可行的,可以考虑dsh、pdsh等并行shell解决方案。
初始化
配置完毕,首次使用前,先要格式化hdfs文件系统:
hadoop namenode -format
启动集群:
start-all.sh
停止集群:
stop-all.sh
如果期间有错误产生,查看日志是一个不错的诊断方法(日志在logs/目录下)。
集群测试
配置好的集群是否能正常工作,接下里就做一个简单的测试。
Hadoop在hadoop-examples-1.0.0.jar里提供了一个wordcount程序,我们就用它来测试。
首先准备两个文本文件file01和file02。
file01内容:
Hello World Bye World
file02内容:
Hello Hadoop Goodbye Hadoop
把这两个文件放到hdfs文件系统中(/input目录下):
hadoop dfs -mkdir /input hadoop dfs -put file0? /input
运行wordcount程序:
hadoop jar hadoop-examples-1.0.0.jar wordcount /input /output
结果存放在hdfs文件系统的/output目录下:
hadoop@hadoop1:~$ hadoop dfs -ls /output Found 10 items -rw-r--r-- 3 hadoop supergroup 0 2012-11-04 03:14 /output/_SUCCESS drwxr-xr-x - hadoop supergroup 0 2012-11-04 03:13 /output/_logs -rw-r--r-- 3 hadoop supergroup 10 2012-11-04 03:14 /output/part-r-00000 -rw-r--r-- 3 hadoop supergroup 16 2012-11-04 03:14 /output/part-r-00001 -rw-r--r-- 3 hadoop supergroup 0 2012-11-04 03:14 /output/part-r-00002 -rw-r--r-- 3 hadoop supergroup 0 2012-11-04 03:14 /output/part-r-00003 -rw-r--r-- 3 hadoop supergroup 0 2012-11-04 03:14 /output/part-r-00004 -rw-r--r-- 3 hadoop supergroup 6 2012-11-04 03:14 /output/part-r-00005 -rw-r--r-- 3 hadoop supergroup 9 2012-11-04 03:14 /output/part-r-00006 -rw-r--r-- 3 hadoop supergroup 0 2012-11-04 03:14 /output/part-r-00007
显示执行结果:
hadoop@hadoop1:~$ hadoop dfs -cat /output/part* Goodbye 1 Hello 2 World 2 Bye 1 Hadoop 2