hadoop-0.20.0分布式部署

来源:互联网 发布:网络吞吐量指标 编辑:程序博客网 时间:2024/05/21 12:49

1.  前言

Hadoop 是一个实现了 MapReduce 计算模型的开源分布式并行编程框架,借助于 Hadoop, 程序员可以轻松地编写分布式并行程序,将其运行于计算机集群上,完成海量数据的计算。在本文档中,详细介绍了如何部署Hadoop 分布式运行环境,如何让程序分布式运行于多台普通的计算机上等内容(在这里用的是VMware虚拟的linux系统)。而hadoop又分为单机(非分布式)模式,伪分布式运行模式和分布式运行模式,其中前两种运行模式体现不了 Hadoop 分布式计算的优势,并没有什么实际意义,但对程序的测试及调试很有帮助,我们先从这两种模式入手,了解基于 Hadoop的分布式并行程序是如何编写和运行的。

然后在对分布式运行模式做一个详细的说明。

 

2.  部署说明

2.1   单机(非分布式)模式

这种模式在一台单机上运行,没有分布式文件系统,而是直接读写本地操作系统的文件系统。

一、实现进入hadoop目录(这是我们解压的hadoop的目录

$ cd /cygdrive/c/hadoop-0.20.0

二、在hadoop-0.20.0目录下创建一个test-in的文件夹

$ mkdir test-in 

三、在 test-in 目录下创建两个文本文件,文件名分别为file1.txt,file2.tex, WordCount               程序将统计其中各个单词出现次数,具体的操作如下: 

$ cd test-in   切入到test-in目录下

$ echo "hello world bye world" >file1.txt  

$ echo "hello hadoop goodbye hadoop" >file2.txt

$ cd ..

四、执行hadoop提供的wordcount例子

$ bin/hadoop jar hadoop-0.20.0-examples.jar wordcount test-intest-out

五、执行结果:

$ cd test-out

$ cat part-00000

bye     1

goodbye  1

hadoop  2

hello    2

world   2

注意事项:运行 bin/hadoop jar hadoop-0.20.0-examples.jar wordcount test-intest-out时,务必注意第一个参数是 jar,不是 -jar, 当你用 -jar时,不会告诉你是参数错了,报告出来的错误信息是:Exceptionin thread "main" java.lang.NoClassDefFoundError:org/apache/hadoop/util/ProgramDriver,当时以为是 classpath的设置问题,浪费了不少时间。通过分析 bin/hadoop脚本可知,-jar并不是 bin/hadoop脚本定义的参数,此脚本会把 -jar作为 Java 的参数,Java-jar参数表示执行一个 Jar文件(这个 Jar文件必须是一个可执行的 Jar,即在 MANIFEST中定义了主类),此时外部定义的 classpath是不起作用的,因而会抛出java.lang.NoClassDefFoundError异常。而 jar bin/hadoop 脚本定义的参数,会调用 Hadoop自己的一个工具类 RunJar,这个工具类也能够执行一个 Jar文件,并且外部定义的 classpath有效。

 

 

2.2   伪分布式运行模式

这种模式也是在一台单机上运行,但用不同的Java进程模仿分布式运行中的各类结点 ( NameNode, DataNode, JobTracker, TaskTracker,Secondary NameNode ),请注意分布式运行中的这几个结点的区别:

从分布式存储的角度来说,集群中的结点由一个NameNode和若干个 DataNode组成,另有一个 Secondary NameNode作为 NameNode的备份。从分布式应用的角度来说,集群中的结点由一个JobTracker和若干个 TaskTracker组成,JobTracker负责任务的调度,TaskTracker负责并行执行任务。TaskTracker必须运行在 DataNode 上,这样便于数据的本地计算。JobTracker NameNode则无须在同一台机器上。

 

a.        首先修改配置文件(conf下)

core-site.xml配置如下信息:

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific propertyoverrides in this file. -->

<configuration>

<property>

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

<value>hdfs://192.168.0.116:9000</value>

<description>The name of the defaultfile system. Either the literal string

"local" or a host:port forDFS.</description>

</property>

</configuration>

参数 fs.default.name指定 NameNode IP 地址和端口号。缺省值是 file:///,表示使用本地文件系统,用于单机非分布式模式。此处我们指定使用运行于本机localhost上的 NameNode

 

hdfs-site.xml配置如下信息:

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific property overridesin this file. -->

<configuration>

<property>

<name>dfs.replication</name>

<value>1</value>

<description>Default blockreplication. The actual number of replications

can be specified when the file is created.The default is used if replication

is not specified in createtime.</description>

</property>

</configuration>

参数 dfs.replication指定 HDFS中每个 Block被复制的次数,起数据冗余备份的作用。在典型的生产系统中,这个数常常设置为3

 

mapred-site.xml配置信息如下:

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific propertyoverrides in this file. -->

<configuration>

<property>

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

<value>192.168.0.116:9001</value>

<description>The host and port thatthe MapReduce job tracker runs at. If

"local", then jobs are run in-processas a single map and reduce task.</description>

</property>

</configuration>

参数 mapred.job.tracker指定 JobTracker IP 地址和端口号。缺省值是 local,表示在本地同一 Java进程内执行 JobTracker TaskTracker, 用于单机非分布式模式。此处我们指定使用运行于本机localhost上的 JobTracker (用一个单独的 Java进程做 JobTracker )

 

b.       配置 SSH

为了执行ssh localhost的时候,确认你的机器可以用 SSH连接,并且连接时不需要手工输入密码,需要执行如下代码:

$ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa

$cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

 

 

c.         格式化一个新的文件系统

$cd /cygdrive/c/hadoop-0.16.0

$bin/hadoop namenodeformat

 

 

d.       运行wordcount应用

将本地文件系统上的./test-in目录拷到HDFS的根目录上,目录名改为input,操作如下:

$bin/hadoop dfs -put ./test-in input

 

执行bin/hadoop dfs -help可以学习各种HDFS命令的使用

执行wordcount例子,代码如下:

$bin/hadoop jar hadoop-0.16.0-examples.jar wordcount input output

 

 查看执行结果:

$bin/hadoop dfs -get output output

$cat output/*

#也可以直接查看

$bin/hadoop dfs -cat output/*

 

 停止hadoop进程

$bin/stop-all.sh

 

故障诊断

(1) 执行 $ bin/start-all.sh启动 Hadoop进程后,会启动5 java进程,同时会在 /tmp目录下创建五个 pid文件记录这些进程 ID 号。通过这五个文件,可以得知 namenode, datanode,secondary namenode, jobtracker, tasktracker分别对应于哪一个 Java进程。当你觉得 Hadoop 工作不正常时,可以首先查看这5 java进程是否在正常运行。

(2) 使用 web接口。访问 http://localhost:50030可以查看 JobTracker的运行状态。访问 http://localhost:50060可以查看 TaskTracker的运行状态。访问 http://localhost:50070可以查看 NameNode以及整个分布式文件系统的状态,浏览分布式文件系统中的文件以及 log等。

(3) 查看 ${HADOOP_HOME}/logs目录下的 log文件,namenode, datanode,secondary namenode, jobtracker, tasktracker各有一个对应的 log文件,每一次运行的计算任务也有对应用 log文件。分析这些 log文件有助于找到故障原因。

 

 

2.3   分布式运行模式

下面的内容我们将重点介绍hadoop分布式模式如何部署。

 

2.3.1  准备工作

1.虚拟机环境搭建

a)       安装VMware

具体操作参考:VMware_Workstation_6.0绿色汉化版的安装和使用

b)       在VMware上新建三个Linux的虚拟机

使这三台虚拟机器的机器名分布为home06,home07,home08均安装 Redhat Enterprise Linux 5.0 (其它 Linux 发行版亦可), 确保各台机器之间网络畅通,机器名与 IP 地址之间解析正确,从任一台机器都可以 ping 通其它机器的机器名。如有机器名的解析问题,可通过设置/etc/hosts 文件解决,当然更好的解决方法是在你的网络中配置 DNS 服务器。此外,需要在三台机器上创建相同的用户帐号,如 songhq, 或直接使用 root 帐号亦可。在这里我们直接使用root账户。

在这里我们通过设置/etc/hosts 文件来解决机器名的解析问题。home06,home07,home08的/etc/hosts 文件的设置如下图:

 

关于RedhatEnterprise Linux 5.0如何在VMware上安装以及VMware如何新建虚拟机请参考文档:VMware_Workstation_6.0绿色汉化版的安装和使用.doc    如何在VMware上安装Linux系统.doc

 

c)        以home06为主节点

我们将使用 home06 作为分布式文件系统 HDFS 的 Name Node及 MapReduce 运行过程中的 Job Tracker 结点,我们将 home06称之为主结点。其它两台机器 (home07, home08) 作为 HDFS 的Data Node 以及 MapReduce 运行过程中的Task Tracker 结点,这些结点可统称为从结点。如你需要部署更多的机器,也是很容易的,将新加入的机器作为 Data Node以及 Task Tracker 结点即可,其配置过程与本文介绍的三台机器的环境类似,此不赘述。(这里的机器为虚拟的机器)

 

2. 配置SSH

目的

在 Hadoop 分布式环境中,Name Node (主节点) 需要通过 SSH启动和停止 Data Node (从结点)上的各类进程。我们需要保证环境中的各台机器均可以通过 SSH 登录访问,并且 NameNode 用 SSH 登录 Data Node 时,不需要输入密码,这样 Name Node 才能在后台自如地控制其它结点。可以将各台机器上的 SSH 配置为使用无密码公钥认证方式来实现。

操作步骤

现在流行的各类 Linux 发行版一般都安装了 SSH 协议的开源实现OpenSSH, 并且已经启动了 SSH 服务, 即这些机器缺省应该就是支持 SSH 登录的。如果你的机器缺省不支持 SSH, 请下载安装 OpenSSH。

以下是配置 SSH 的无密码公钥认证的过程。首先,在 homer06 机器上执行命令,如下代码所示:

homer06: $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/caoyuz/.ssh/id_rsa):  
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/caoyuz/.ssh/id_rsa.
Your public key has been saved in /home/caoyuz/.ssh/id_rsa.pub.
The key fingerprint is:
2e:57:e2:bf:fd:d4:45:5c:a7:51:3d:f1:51:3c:69:68 root@krusty04

这个命令将为 home06 上的当前用户 root 生成其密钥对,密钥对的保存路径使用缺省的 /home/root/.ssh/id_rsa, 要求输入 passphrase 的时候,直接回车。这样生成的证书以及公钥将存储在 /home/root/.ssh 目录,形成两个文件 id_rsa,id_rsa.pub。然后将 id_rsa.pub 文件的内容复制到每一台机器(包括本机 home06)的 /home/root/.ssh/authorized_keys文件的尾部,如果机器上不存在/home/root/.ssh/authorized_keys文件,可以自行创建一个。请注意 id_rsa.pub 文件的内容是长长的一行,复制时需注意,不要遗漏字符或混入了多余换行符。

 

接下来可以做一下 SSH 连接测试,从 home06 分别向 home06, home07, home08 发起 SSH 连接请求,确保不需要输入密码就能 SSH 连接成功。注意第一次 SSH 连接时会出现如下提示信息:

The authenticity of host [home06] can't be established.The key fingerprint is: 74:32:91:f2:9c:dc:2e:80:48:73:d4:53:ab:e4:d3:1a Are yousure you want to continue connecting (yes/no)?

请输入 yes, 这样 OpenSSH 会把连接过来的这台主机的信息自动加到 /home/root/.ssh/know_hosts文件中去,第二次再连接时,就不会有这样的提示信息了。

[root@home06 ~]# ssh home07

Last login: Tue Sep 22 00:31:062009 from home06

[root@home07 ~]#

用ssh主机名能直接进入相应的主机就说明配置成功了,如上代码。

 

补充:

1.       当我们在home6主机上执行ssh-keygen -t rsa之后会在home6的/home/root/.ssh/id_rsa文件夹下生成id_rsa,id_rsa.pub,然后将 id_rsa.pub 文件的内容复制到每一台机器(包括本机 home06)的 /home/root/.ssh/authorized_keys文件的尾部。如果没有authorized_keys这个文件我们需要手动创建一个,创建的命令为:touch authorized_keys,然后在把这个文件copy到home7和home08相应的文件夹中去。

2.在这里我充分应用了SecureCRT这个工具,具体的使用请查看我提供的资料。

 

2.3.2  部署、配置和启动Hadoop环境

a)       安装 Hadoop 及 jdk1.6

我们首先在主控结点 home06 上安装和配置好 Hadoop。我们把 Hadoop 安装在 /usr/hadoop-0.20.0目录中,并且 Jdk 1.6 安装在 /usr/java 目录下。务必安装jdk1.6,否则会有问题,具体请查看问题文档:搭建hadoop环境遇到的问题.

具体的操作请查看:Linux下jdk1.6的安装和配置.doc

b)       修改 conf/hadoop-env.sh 文件

在其中设置 JAVA_HOME 环境变量:export JAVA_HOME=”/usr/java/jdk1.6.0_16”


一定要记得把前面的#号去掉

c)        修改 conf/hadoop-site.xml 文件

在hadoop-0.20.0版本以前的版本conf文件夹下是存在hadoop-site.xml这个文件的,但是到hadoop-0.20.0这个版本它的配置是需要分开配置的。分成了core-site.xml,hdfs-site.xml以及mapred-site.xml三个文件进行配置。

具体的配置情况如下:

core-site.xml配置如下信息:(公共配置文件)

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific propertyoverrides in this file. -->

<configuration>

<property>

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

<value>hdfs://192.168.0.116:9000</value>

<description>The name of the defaultfile system. Either the literal string

"local" or a host:port forDFS.</description>

</property>

<property>

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

<value>/tmp/hadoop-root/dfs/name</value>

<description>Determines where on thelocal filesystem the DFS name node

should store the name table. If this is acomma-delimited list of directories

then the name table is replicated in all ofthe directories,

for redundancy. </description>

</property>

<property>

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

<value>/tmp/hadoop-root/dfs/data</value>

<description>Determines where on thelocal filesystem an DFS data node

should store its blocks. If this is acomma-delimited list of directories,

then data will be stored in all nameddirectories, typically on different devices.

Directories that do not exist areignored.</description>

</property>

</configuration>

l 参数 fs.default.name 指定 Name Node 的 IP 地址和端口号,此处我们将其设定为 home06 及 9000 端口,

 

 

hdfs-site.xml配置如下信息:(HDFS配置文件)

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific propertyoverrides in this file. -->

<configuration>

<property>

<name>dfs.replication</name>

<value>2</value>

<description>Default blockreplication. 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>

</configuration>

l 参数 dfs.name.dir 指定 Name Node 相关数据在本地文件系统上的存放位置, 此处我们将其设定为/tmp/hadoop-root/dfs/name ,

l 参数 dfs.data.dir 指定 Data Node 相关数据在本地文件系统上的存放位置,此处我们将其设定为 /tmp/hadoop-root/dfs/data 。注意, Hadoop 会自动创建这两个目录,无需事先创建。

 

mapred-site.xml配置信息如下:(MR配置文件)

<?xml version="1.0"?>

<?xml-stylesheettype="text/xsl" href="configuration.xsl"?>

<!-- Put site-specific propertyoverrides in this file. -->

<configuration>

<property>

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

<value>192.168.0.116:9001</value>

<description>The host and port thatthe MapReduce job tracker runs at. If

"local", then jobs are runin-process as a single map and reduce task.</description>

</property>

</configuration>

l  参数 mapred.job.tracker 指定 JobTracker 的 IP 地址和端口号,此处我们将其设定为 home06 及 9001 端口。

l 更多的参数配置,可以参考 src/core/core-default.xml 文件,并在上三个文件中进行相应的设置。

 

d)       设定主从节点

修改conf/masters 文件,将其中的 localhost 改为 homer06 ,修改 conf/slaves文件,删掉其中的 localhost,将我们的另两台机器 homer07, homer08加入,注意每个机器一行。

Home06conf/masters文件如下配置:


conf/slaves文件如下配置:


 

e)        将 Hadoop 部署到其它机器上去

至此, 我们已经在 home06上安装和配置好了 hadoop jdk, 现在需要将其部署到其它机器上去,通过 scp命令即可完成,如代码所示:

home06: $ scp -r /usr/hadoop-0.20.0 home07:/usr/hadoop-0.20.0
home06: $ scp -r /usr/java/ jdk1.6.0_16 home07:/usr/java/ jdk1.6.0_16
home06: $ scp -r /usr/hadoop-0.20.0 home08: /usr/hadoop-0.20.0
home06: $ scp -r /usr/java/ jdk1.6.0_16 home08: /usr/java/ jdk1.6.0_16

其中用 scp 拷贝 jdk目录到其它机器上去不是必须的。你只需保证你的所有机器上均安装了 jdk1.5以上版本,并且都是安装在同一目录。

 

f)        在 home06 上格式化一个新的分布式文件系统

home06: $ cd /usr /hadoop-0.20.0
home06: $ bin/hadoop namenode -format
 
[root@home06 hadoop-0.20.0]# bin/hadoop namenode -format
09/09/21 16:13:50 INFO namenode.NameNode: STARTUP_MSG: 
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = home06/192.168.0.116
STARTUP_MSG:   args = [-format]
STARTUP_MSG:   version = 0.20.0
STARTUP_MSG:   build = https://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.20 -r 763504; compiled by 'ndaley' on Thu Apr  9 05:18:40 UTC 2009
************************************************************/
Re-format filesystem in /tmp/hadoop-root/dfs/name ? (Y or N) y
Format aborted in /tmp/hadoop-root/dfs/name
09/09/21 16:13:52 INFO namenode.NameNode: SHUTDOWN_MSG: 
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at home06/192.168.0.116
************************************************************/

 

g)       在 home06 上启动 hadoop 进程

home06: $ cd /usr/hadoop-0.20.0
home06: $ bin/start-all.sh
 
[root@home06 hadoop-0.20.0]# bin/start-all.sh
starting namenode, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-namenode-home06.out
home07: starting datanode, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-datanode-home07.out
home08: starting datanode, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-datanode-home08.out
home06: starting secondarynamenode, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-secondarynamenode-home06.out
starting jobtracker, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-jobtracker-home06.out
home07: starting tasktracker, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-tasktracker-home07.out
home08: starting tasktracker, logging to /usr/hadoop-0.20.0/bin/../logs/hadoop-root-tasktracker-home08.out
 

启动完成之后,运行 ps-ef 命令应该可以看到home06上启动了 3个新的 java进程 (namenode, secondarynamenode, jobtracker)
同时,我们可以到home07, home08两台机器上用 ps –ef查看,这两台机器上应该已经自动启动 2个新的 java 进程 (datanode, tasktracker)

 

通过jps查出:

[root@home06hadoop-0.20.0]# jps

3475 SecondaryNameNode

3616 Jps

3544 JobTracker

3320 NameNode

2.3.3 运行 Hadoop 样例程序

至此,整个 Hadoop 分布式环境已经部署完毕,并已启动相关后台进程。现在我们可以尝试运行一下hadoop提供给我们的 wordcount程序,如下代码所示:

homer06: $ mkdir -p /home/test-in
# 请先将待测的文件放到本地文件系统的/home/test-in目录
homer06: $ cd /home/caoyuz/hadoop-0.16.0
homer06: $ bin/hadoop dfs –put /home/test-in input  
# 将本地文件系统上的 /home/test-in 目录拷到 HDFS 的根目录上,目录名改为 input
$ bin/hadoop jar hadoop-0.16.0-examples.jar wordcount input output
#查看执行结果:
# 将文件从 HDFS 拷到本地文件系统中再查看:
$ bin/hadoop dfs -get output output 
$ cat output/*
# 也可以直接查看
$ bin/hadoop dfs -cat output/*

 

现在拥有了一个真正的分布式执行环境,我们的数据分布存储于数据节点 home07 home08上,可以在这两台机器的/tmp/hadoop-root/dfs/data目录 (这是我们在 conf/core-site.xml中指定的 dfs.data.dir参数)下看到一些数据文件,并且整个 wordcount的计算过程神奇地由home06, home07, home08三台机器并行协同完成,我们还可以很方便的增加更多的机器来参与运算。这就是分布式并行程序的优势:可以很容易地通过加入新的机器来获得更多的存储空间和计算能力,部署的机器越多,就越能有效地完成海量数据的计算。

 

2.3.4  FAQ

Home06,home07,home08的防火窗要关闭,否则将不能相互访问。Linux关闭防火窗的命令为:/etc/rc.d/init.d/iptablesstop