Hadoop安装部署笔记

最近一直在看Hadoop分布式计算框架,也打算在这个基础之上做一些简单的应用研究。在研读了一些Hadoop相关的论文之后,发现做理论研究的一般都很少提及Hadoop的安装与搭建。作为一个实践派的骨灰级粉丝,我决定从搭建Hadoop环境开始认识这个仅仅0.2的版本号就能被推上神坛的分布式计算框架。

查阅了一些资料,发现Hadoop似乎只支持在Linux上部署生产环境,如果在Windows下部署开发调试环境,也需要Cygwin的支持。首先,搭建Linux环境。我选用的Linux发行版是Ubuntu Server 10.4 LTS版本。虽然11.10已经释出,但是基于稳定性的考虑,还是使用LTS(Long Time Support)版本。

Hadoop允许用户使用三种不同的部署方式:

  • 单机部署
  • 伪分布式部署
  • 分布式部署

为了全面体验Hadoop的特性,了解在生产环境下部署Hadoop可能遇到的问题,我悍然选择第三种部署方式。这种部署方式至少需要两台电脑,即一个NameNode和一个DataNode。我选用了一个Name节点和两个Data节点的部署方式。首先启动VMWare,建立一个虚拟机,安装Ubuntu Server 11.04。像大多数部署Ubuntu环境一样,选择最基本环境,外加OpenSSH,大约20分钟左右,即可安装成功。

由于Hadoop是利用Java编写,Linux上必须安装JDK。理论上讲可以选择Ubuntu默认的Open-JDK安装,还是基于可靠性考虑,我还是选择安装Sun官方提供的JDK。从官网下载(以下所有命令均为root执行)
wget http://download.oracle.com/otn-pub/java/jdk/6u29-b11/jdk-6u29-linux-i586.bin
下载完成后,为其加入可执行权限:
chmod +x jdk-6u29-linux-i586.bin
开始安装和解压缩软件包
./jdk-6u29-linux-i586.bin
等待解压完成,可以看到jdk1.6.0_29的目录。接下来,将文件夹移动到安装目录:
mkdir -p /usr/lib/jvm/
mv ./jdk1.6.0_29 /usr/lib/jvm/
cd /usr/lib/jvm
ln -s jdk1.6.0_29 latest

接下来,设置环境变量,使用vi编辑器打开/etc/environment文件,修改为以下内容:

PATH=”/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/lib/jvm/latest/bin:/usr/lib/jvm/latest/jre/bin”
CLASSPATH=”./:/usr/lib/jvm/latest/lib:/usr/lib/jvm/latest/jre/lib”
JAVA_HOME=”/usr/lib/jvm/latest”

其中PATH路径请根据自己实际情况修改。然后,我们需要将sun-jdk设为我们选择的jdk软件包
update-alternatives --install /usr/bin/java java /usr/java/latest/bin/java 60
update-alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 60
update-alternatives --install /usr/bin/javaws javaws /usr/java/latest/bin/javaws 60

如果你已经安装了Open-JDK,可以使用以下命令选择新的JDK
update-alternatives --config java
好了,可以测试下我们的安装情况了。在命令行输入
java -version
版本号君就现身了,T_T
java version "1.6.0_29"
Java(TM) SE Runtime Environment (build 1.6.0_29-b11)
Java HotSpot(TM) Client VM (build 20.4-b02, mixed mode, sharing)

Java环境部署完毕,我们来下载Hadoop,目前稳定版是0.20.X,可以从以下地址下载:
wget http://labs.renren.com/apache-mirror/hadoop/common/stable/hadoop-0.20.203.0rc1.tar.gz
人人网提供的镜像速度还不错~
接下来,我们来配置基本环境。首先,我们需要添加Hadoop使用的用户和准备安装目录。
groupadd hadoop
useradd -d /home/hadoop/ -g hadoop -m -s /bin/bash
mv hadoop-0.20.203.0rc1.tar.gz /home/hadoop/

解压缩软件包,并且建立访问链接和必要的路径。
tar zxvf hadoop-0.20.203.0rc1.tar.gz
ln -s hadoop-0.20.203.0 hadoop
mkdir -p hadoop-conf hadoop-logs filesystem/name filesystem/data tmp

接下来,配置我们的Hadoop环境。首先将安装包里面的conf下的文件全部拷贝到hadoop-conf里面,这样便于集中管理,升级时无需重新配置。
mv hadoop/conf/* ./hadoop-conf/*
接下来,我们需要配置系统变量,告诉Hadoop我们自定义了配置文件夹,用编辑器打开/etc/environment文件,在最后行添加:
HADOOP_CONF_DIR="/home/hadoop/hadoop-conf"
首先,我们必须得配置Hadoop所需的环境变量,打开~/hadoop-conf/hadoop-env.sh, 修改以下三个环境变量导入:
export HADOOP_HOME=/home/hadoop/hadoop
export JAVA_HOME=/usr/lib/jvm/latest
export HADOOP_LOG_DIR=/home/hadoop/hadoop-logs

在我们配置的环境中,使用了三台机器,他们分别拥有以下的hostname和ip地址
192.168.24.139 NameNode NameNode
192.168.24.140 DataNode-1 DataNode-1
192.168.24.141 DataNode-2 DataNode-2

为了访问方便,我们需要将hosts文件进行修改,请将上面的内容添加到hosts文件中,注意,除了这些配置和localhost之外,最好不要有其他配置项,以免出现问题。我在配置环境的时候就出现了DataNode无法访问NameNode的问题,原因即hosts文件多了额外的配置。

接着,我们来逐一修改Hadoop的配置文件。在hadoop 0.2.0.x的版本中,原来的hadoop-site.xml配置文件被废弃,取而代之的是三个配置文件,它们是core-site.xml、hdfs-site.xml、mapred-site.xml三个文件。网上很多资料都写到了hadoop-site.xml,虽然可以使用,但运行时会提示配置文件已废弃。

对于core-site.xml,请参照以下内容修改:

对于hdfs-site.xml,请参照以下内容修改:

对于mapred-site.xml,请参照以下内容修改:

另外,我们需要配置Hadoop的masters和slaves配置文件,他们位于hadoop-conf文件夹下,将masters文件填写为:
NameNode
slaves填写为:
DataNode-1
DataNode-2

由于hadoop需要通过SSH访问DataNode,因此我们需要配置基于公钥私钥的认证,而不是基于密码的认证。接下来我们需要进行这些工作。
su hadoop
ssh-keygen -t rsa

当询问其保存路径时直接回车采用默认路径,当提示要为生成的密钥输入passphrase的时候,直接回车,也就是将其设定为空密码。生成的密钥对id_rsa,id_rsa.pub,默认存储在~/.ssh目录下。接下来拷贝公钥为认证密钥:
cd ~/.ssh
cp id_rsa.pub authorized_keys
chmod 644 authorized_keys

这时候测试下先
ssh localhost
第一次连接的时候,系统会提示是否保存到认识的主机列表,输入yes回车。如果你成功连接到了服务器,并且没有输入密码,那么恭喜你成功了。

然后,我们返回到系统中的ROOT用户,将hadoop目录的所有权设为hadoop用户
chown hadoop:hadoop -R /home/hadoop/*

接下来,我们开始复制虚拟机。先关闭当前虚拟机,最好退出VMWare。我建立的虚拟机名为NameNode,所有相关文件都是NameNode.*。我们将虚拟机文件夹复制后,重命名为DataNode#1和DataNode#2,虚拟机相关的所有文件名也都以此命名。打开DataNode#1.vmx,查找NameNode,批量替换为DataNode#1和DataNode#2。

在VMWare中打开新复制的虚拟机,选择虚拟机属性,修改在Option选项卡中修改虚拟机名称;选择网卡,点击高级按钮,重新生成机器的Mac地址。

运行新的虚拟机,VMWare会给我们提示,我们选择I copied it。新复制的两个虚拟机还必须修改hostname和删除Mac地址缓存。修改hostname,请使用编辑器打开/etc/hostname即可修改,对于清除Mac地址缓存,我们可以使用以下命令:
rm -rf /etc/udev/rules.d/70-persistent-net.rules
重启机器,如果启用了DHCP配置IP地址,那么三台机器的IP地址将被重新分配。根据新的IP地址修改hosts表,确保根据主机名称能够使得三台机器之间相互ping通。

这样,复制虚拟机的工作就完成了。接下来,我们需要对整个Hadoop环境进行总装测试了。

首先使用NameNode的ssh客户端连接DataNode-1和DataNode-2,确保可以通过无密码的方式访问到两台数据节点。如果这一步不能通过,请检查密钥生成及存放是否有问题,尤其是验证.ssh文件夹下的文件拥有者和访问权限是否正确。

修改NameNode的hdfs-site.xml文件,删除dfs.data.dir属性块的定义;修改DataNode的hdfs-site.xml文件,删除dfs.name.dir属性块的定义。

一切就绪后,我们来格式化HDFS。在NameNode中,使用hadoop用户身份登入,执行以下命令:
cd ~/hadoop/hadoop/bin
./hadoop namenode -format

系统会询问是否要格式化,选择Y。
格式化完毕后,使用以下命令启动Hadoop:
./start-all.sh
这时我们可以看到,Name节点和Data节点依次被启动。要关闭Hadoop,请使用:
./stop-all.sh
在启动Hadoop之后,我们可以通过Web方式来监控工作情况:
监控HDFS:http://[server]:50070
监控Job Tracker:http://[server]:50030
在这里,我们可以看到已经加入的数据节点和可用空间。如果没有什么问题,我们可以向HDFS中写入文件了:
cd ~/hadoop/bin
./hadoop dfs -put /path/to/file /upload/path/file

你可以根据自己的喜好上传一些文件到HDFS中。接下来,我们看看文件的情况:
./hadoop dfs -ls
如果没有什么意外,你应该可以看到:

至此,Hadoop的环境搭建就基本上没有问题了。我们可以尝试下运行MapReduce的例子WordCount:

首先在本地建立要输入的文件:
mkdir -p ~/input/
echo "Hello world Bye world" > ~/input/f1
echo "hello hadoop bye hadoop" > ~/input/f2

在HDFS上建立输入目录并上传文件:
cd ~/hadoop/bin
./hadoop fs -mkdir /tmp/input
./hadoop fs -put ~/input /tmp

查看文件是否被上传:
./hadoop fs -ls /tmp/input
接下来,我们执行wordcount:
./hadoop jar ../hadoop-examples-0.20.203.0.jar wordcount /tmp/input /output
宏伟的Hadoop和MapReduce就要开始运行了!

hadoop@NameNode:/home/hadoop/hadoop/bin$ ./hadoop jar ../hadoop-examples-0.20.203.0.jar wordcount /tmp/input /output
11/12/07 21:05:34 INFO input.FileInputFormat: Total input paths to process : 2
11/12/07 21:05:34 INFO mapred.JobClient: Running job: job_201112072039_0002
11/12/07 21:05:35 INFO mapred.JobClient: map 0% reduce 0%
11/12/07 21:05:49 INFO mapred.JobClient: map 50% reduce 0%
11/12/07 21:05:50 INFO mapred.JobClient: map 100% reduce 0%
11/12/07 21:06:01 INFO mapred.JobClient: map 100% reduce 100%
11/12/07 21:06:06 INFO mapred.JobClient: Job complete: job_201112072039_0002
11/12/07 21:06:06 INFO mapred.JobClient: Counters: 25
11/12/07 21:06:06 INFO mapred.JobClient: Job Counters
11/12/07 21:06:06 INFO mapred.JobClient: Launched reduce tasks=1
11/12/07 21:06:06 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=17543
11/12/07 21:06:06 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0
11/12/07 21:06:06 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0
11/12/07 21:06:06 INFO mapred.JobClient: Launched map tasks=2
11/12/07 21:06:06 INFO mapred.JobClient: Data-local map tasks=2
11/12/07 21:06:06 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=10043
11/12/07 21:06:06 INFO mapred.JobClient: File Output Format Counters
11/12/07 21:06:06 INFO mapred.JobClient: Bytes Written=31
11/12/07 21:06:06 INFO mapred.JobClient: FileSystemCounters
11/12/07 21:06:06 INFO mapred.JobClient: FILE_BYTES_READ=75
11/12/07 21:06:06 INFO mapred.JobClient: HDFS_BYTES_READ=242
11/12/07 21:06:06 INFO mapred.JobClient: FILE_BYTES_WRITTEN=63461
11/12/07 21:06:06 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=31
11/12/07 21:06:06 INFO mapred.JobClient: File Input Format Counters
11/12/07 21:06:06 INFO mapred.JobClient: Bytes Read=46
11/12/07 21:06:06 INFO mapred.JobClient: Map-Reduce Framework
11/12/07 21:06:06 INFO mapred.JobClient: Reduce input groups=4
11/12/07 21:06:06 INFO mapred.JobClient: Map output materialized bytes=81
11/12/07 21:06:06 INFO mapred.JobClient: Combine output records=6
11/12/07 21:06:06 INFO mapred.JobClient: Map input records=2
11/12/07 21:06:06 INFO mapred.JobClient: Reduce shuffle bytes=81
11/12/07 21:06:06 INFO mapred.JobClient: Reduce output records=4
11/12/07 21:06:06 INFO mapred.JobClient: Spilled Records=12
11/12/07 21:06:06 INFO mapred.JobClient: Map output bytes=78
11/12/07 21:06:06 INFO mapred.JobClient: Combine input records=8
11/12/07 21:06:06 INFO mapred.JobClient: Map output records=8
11/12/07 21:06:06 INFO mapred.JobClient: SPLIT_RAW_BYTES=196
11/12/07 21:06:06 INFO mapred.JobClient: Reduce input records=6

激动人心的时刻到了,让我们来看输出结果:

成功!

好了,至此,Hadoop的分布式运行环境已经搭建完毕了。虽然你可能几分钟就看完了这篇文章,但是真心是折腾了足足6个多小时才把他完全的搭建起来。参考这篇文章搭建Hadoop,可以帮你省不少事儿,但是实在是不敢保证能够完全好使。不过,大体的思路有了,再遇到问题就见招拆招即可了。最后附上一些参考文章,也许可以帮你解决什么问题,也欢迎大家积极讨论~共同学习~

参考文章:

《Running Hadoop On Ubuntu Linux (Multi-Node Cluster)》
http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-multi-node-cluster/

《Hadoop学习笔记二 安装部署》
http://www.cnblogs.com/wayne1017/archive/2007/03/20/678724.html

《Hadoop Cluster Setup》
http://hadoop.apache.org/common/docs/stable/cluster_setup.html

《Ubuntu下Hadoop快速安装手册》
http://www.iteye.com/topic/964704

《Hadoop的安装与配置及示例程序wordcount的运行》
http://wenku.baidu.com/view/41eac9d850e2524de5187ef3.html