在搭建Hadoop分布式集群之前,还需要提前做一些准备规划工作,包含主机规划、软件规划、用户规划和目录规划。 1.1 主机规划 由于资源有限,这里仍然以Zookeeper集群的 3 台主机来安装Hadoop集群,每台主机运行哪些守护进程具体规划如表6-1所示:
表6-1 主机规划
守护进程 | hadoop1/192.168.0.111 | hadoop2/192.168.0.112 | hadoop3/192.168.0.113 |
|---|---|---|---|
NameNode | 是 | 是 | |
DataNode | 是 | 是 | 是 |
ResourceManager | 是 | 是 | |
Journalnode | 是 | 是 | 是 |
Zookeeper | 是 | 是 | 是 |
1.2 软件规划 考虑到各个软件版本之间的兼容性,软件规划具体如表6-2所示。
表6-2 软件规划
软件 | 版本 |
|---|---|
jdk | jdk 1.8 |
centos | centos 7 |
zookeeper | Apache zookeeper 3.4.6 |
hadoop | Apache hadoop 2.9.2 |
1.3 用户规划 为了保持Hadoop集群环境的独立性,我们分别在每个节点单独新建hadoop用户和用户组,每个节点的用户规划如表6-3所示。
表6-3 用户规划
节点名称 | 用户组 | 用户 |
|---|---|---|
hadoop1 | hadoop | hadoop |
hadoop2 | hadoop | hadoop |
hadoop3 | hadoop | hadoop |
1.4 目录规划 为了方便Hadoop集群各个节点的管理,需要在hadoop用户下提前创建好相关目录,具体目录规划如表6-4所示。
表6-4 目录规划
名称 | 路径 |
|---|---|
所有软件目录 | /home/hadoop/app/ |
所有数据和日志目录 | /home/hadoop/data/ |
Hadoop集群是由HDFS和YARN两个部分组成,这里我们首先搭建HDFS分布式集群。
1.下载解压Hadoop
首先到官网(地址:https://archive.apache.org/dist/hadoop/common/)下载Hadoop稳定版本的安装包,然后上传至hadoop1节点下的/home/hadoop/app目录下并解压,具体操作如下所示。
[hadoop@hadoop1 app]$ tar -zxvf hadoop-2.9.2.tar.gz //解压
[hadoop@hadoop1 app]$ ln -s hadoop-2.9.2 hadoop //创建软连接
[hadoop@hadoop1 app]$ cd /home/hadoop/app/hadoop/etc/hadoop/ //切换到配置目录2.修改HDFS配置文件
(1)修改hadoop-env.sh配置文件
hadoop-env.sh文件主要配置跟hadoop环境相关的变量,这里主要修改JAVA_HOME的安装目录,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi hadoop-env.sh
export JAVA_HOME=/home/hadoop/app/jdk(2)修改core-site.xml配置文件
core-site.xml文件主要配置hadoop的公有属性,具体需要配置的每个属性如下所示
[hadoop@hadoop1 hadoop]$ vi core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
< !--这里的值指的是默认的HDFS路径,取名为mycluster-->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/data/tmp</value>
</property>
< !--hadoop的临时目录,目录需要我们自己创建-->
<property>
<name>ha.zookeeper.quorum</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
< !--配置Zookeeper 管理HDFS-->
</configuration>(3) 修改hdfs-site.xml配置文件
hdfs-site.xml文件主要配置跟HDFS相关的属性,具体需要配置的每个属性如下所示。
[hadoop@hadoop1 hadoop]$ vi hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
< !--数据块副本数为3-->
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
< !--权限默认配置为false-->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
< !--命名空间,与fs.defaultFS的值对应,mycluster是HDFS对外提供的统一入口-->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
< !--指定mycluster下的NameNode名称,为逻辑名称,名字随便起,不重复即可-->
< hadoop1 http地址>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop1:9000</value>
</property>
< !--hadoop1 rpc地址-->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop1:50070</value>
</property>
< !--hadoop2 http地址-->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop2:9000</value>
</property>
< !--hadoop2 rpc地址-->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop2:50070</value>
</property>
< !--hadoop2 http地址-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
< !--启动故障自动恢复-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop1:8485;hadoop2:8485;hadoop3:8485/mycluster</value>
</property>
< !--指定journal-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
< !--指定mycluster出故障时,哪个实现类负责执行故障切换-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/data/journaldata/jn</value>
</property>
< !--指定JournalNode集群存储edits.log时,本地磁盘的存储路径-- >
<property>
<name>dfs.ha.fencing.methods</name>
<value>shell(/bin/true)</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>10000</value>
</property>
<property>
<name>dfs.namenode.handler.count</name>
<value>100</value>
</property>
</configuration>(4)配置slaves文件
slaves文件是根据集群规划配置DataNode节点所在的主机名,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi slaves
hadoop1
hadoop2
hadoop3(5)向所有节点远程复制Hadoop安装目录
在hadoop1节点,切换到/home/hadoop/app目录下,将Hadoop安装目录远程复制到hadoop2和hadoop3节点,具体操作如下所示。
[hadoop@hadoop1 app]$scp -r hadoop-2.9.2 hadoop@hadoop2:/home/hadoop/app/
[hadoop@hadoop1 app]$scp -r hadoop-2.9.2 hadoop@hadoop3:/home/hadoop/app/然后在hadoop2和hadoop3节点上分别创建软连接,具体操作如下所示。
[hadoop@hadoop2 app]$ ln -s hadoop-2.9.2 hadoop
[hadoop@hadoop3 app]$ ln -s hadoop-2.9.2 hadoop1.启动Zookeeper集群 在集群所有节点分别启动Zookeeper服务,具体操作如下所示。
[hadoop@hadoop1 zookeeper]$ bin/zkServer.sh start
[hadoop@hadoop2 zookeeper]$ bin/zkServer.sh start
[hadoop@hadoop3 zookeeper]$ bin/zkServer.sh start2.启动Journalnode集群 在集群所有节点分别启动Journalnode服务,具体操作如下所示。
[hadoop@hadoop1 hadoop]$sbin/hadoop-daemon.sh start journalnode
[hadoop@hadoop2 hadoop]$sbin/hadoop-daemon.sh start journalnode
[hadoop@hadoop3 hadoop]$sbin/hadoop-daemon.sh start journalnode3.格式化主节点NameNode 在hadoop1节点(NameNode主节点)上,使用如下命令对NameNode进行格式化。
[hadoop@hadoop1 hadoop]$ bin/hdfs namenode -format / /namenode 格式化
[hadoop@hadoop1 hadoop]$ bin/hdfs zkfc -formatZK //格式化高可用
[hadoop@hadoop1 hadoop]$bin/hdfs namenode //启动namenode4.备用NameNode同步主节点元数据 在hadoop1节点启动NameNode服务的同时,需要在hadoop2节点(NameNode备用节点)上执行如下命令同步主节点的元数据。
[hadoop@hadoop2 hadoop]$ bin/hdfs namenode -bootstrapStandby 5.关闭Journalnode集群 hadoop2节点同步完主节点元数据之后,紧接着在hadoop1节点上,按下〈Ctrl+C〉组合键来结束NameNode进程,然后关闭所有节点上面的Journalnode进程,具体操作如下所示。
[hadoop@hadoop1 hadoop]$sbin/hadoop-daemon.sh stop journalnode
[hadoop@hadoop2 hadoop]$ sbin/hadoop-daemon.sh stop journalnode
[hadoop@hadoop3 hadoop]$ sbin/hadoop-daemon.sh stop journalnode6.一键启动HDFS集群 如果上面操作没有问题,在hadoop1节点上,可以使用脚本一键启动HDFS集群所有相关进程,具体操作如图6-1所示。
[hadoop@hadoop1 hadoop]$ sbin/start-dfs.sh注意:第一次安装HDFS需要对NameNode进行格式化,HDFS集群安装成功之后,以后使用start-dfs.sh脚本一键启动HDFS集群的所有进程即可。
在浏览器中输入网址http://hadoop1:50070,通过 Web 界面查看hadoop1节点的NameNode的状态,结果如图6-2所示。该节点的状态为active,表示HDFS可以通过hadoop1节点的NameNode对外提供服务。

图6-2 active状态的NameNode界面 在浏览器中输入网址http://hadoop2:50070,通过Web界面查看hadoop2节点的NameNode的状态,结果如图6-3所示。该节点的状态为standby,表示hadoop2节点的`NameNode`不能对外提供服务,只能作为备用节点。

图6-3 standby状态的NameNode界面
注意:某一时刻只能有一个NameNode节点处于active状态。
在hadoop1节点的/home/hadoop/app/hadoop目录下创建words.log文件,然后上传至 HDFS文件系统的/test目录下,检查 HDFS是否能正常使用,具体操作如下:
#本地新建words.log文件
[hadoop@hadoop1 hadoop]$ vi words.log
hadoop hadoop hadoop
spark spark spark
flink flink flink
[hadoop@hadoop1 hadoop]$ hdfs dfs -mkdir /test
#上传本地文件words.log
[hadoop@hadoop1 hadoop]$ hdfs dfs -put words.log /test
#查看words.log是否上传成功
[hadoop@hadoop1 hadoop]$ hdfs dfs -ls /test
/test/words.log如果上面操作没有异常,说明HDFS分布式集群搭建成功。
HDFS分布式集群搭建成功之后,接下我们来安装配置YARN集群。
1.修改 mapred-site.xml配置文件 mapred-site.xml 文件主要配置跟 MapReduce 相关的属性,这里主要将MapReduce的运行环境指定为YARN,核心配置如下所示。
[hadoop@hadoop1 hadoop]$ vi mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!--指定运行mapreduce的环境是YARN,与hadoop1不同的地方-->
</configuration>2.修改 yarn-site.xml配置文件 yarn-site.xml 文件主要配置跟YARN 相关的属性,核心配置如下所示。
[hadoop@hadoop1 hadoop]$ vi yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.connect.retry-interval.ms</name>
<value>2000</value>
</property>
< !--超时的周期-->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 打开高可用-->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!--启动故障自动恢复-->
<property>
<name>yarn.resourcemanager.ha.automatic-failover.embedded</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yarn-rm-cluster</value>
</property>
<!--给yarn cluster 取个名字yarn-rm-cluster-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!--给ResourceManager 取个名字 rm1,rm2-->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop1</value>
</property>
<!--配置ResourceManager rm1 hostname-->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop2</value>
</property>
<!--配置ResourceManager rm2 hostname-->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!--启用resourcemanager 自动恢复-->
<property>
<name>yarn.resourcemanager.zk.state-store.address</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
<!--配置Zookeeper地址-->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop1:2181,hadoop2:2181,hadoop3:2181</value>
</property>
<!--配置Zookeeper地址-->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>hadoop1:8032</value>
</property>
< !--rm1端口号-->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hadoop1:8034</value>
</property>
< !--rm1调度器的端口号-->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop1:8088</value>
</property>
< !--rm1 webapp端口号-->
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>hadoop2:8032</value>
</property>
<!-- rm2端口号-->
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hadoop2:8034</value>
</property>
< !--rm2调度器的端口号-->
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop2:8088</value>
</property>
< !--rm2 webapp端口号-->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<!--执行MapReduce需要配置的shuffle过程-->
</configuration>#将 mapred-site.xml文件远程复制到hadoop2和hadoop3节点
[hadoop@hadoop1 app]$scp -r mapred-site.xml hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop
[hadoop@hadoop1 app]$scp -r mapred-site.xml hadoop@hadoop3:/home/hadoop/app/hadoop/etc/hadoop
#将yarn-site.xml文件远程复制到hadoop2和hadoop3节点
[hadoop@hadoop1 app]$scp -r yarn-site.xml hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop
[hadoop@hadoop1 app]$scp -r yarn-site.xml hadoop@hadoop3:/home/hadoop/app/hadoop/etc/hadoopYARN HA的实现依赖于Zookeeper,所以需要优先启动Zookeeper集群。因为前面操作已经启动Zookeeper集群,所以该步骤可以跳过。
1.启动YARN集群
在hadoop1节点上,使用脚本一键启动YARN集群,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ sbin/start-yarn.sh2.启动备用ResourceManager
因为start-yarn.sh脚本不包含启动备用ResourceManager进程的命令,所以需要在hadoop2节点上单独启动ResourceManager,具体操作如下所示。
[hadoop@hadoop2 hadoop]$ sbin/yarn-daemon.sh start resourcemanager1.Web界面查看YARN集群 在浏览器中输入网址http://hadoop1:8088(或者http://hadoop2:8088 ),通过 Web 界面查看YARN集群信息,结果如图6-6所示。

图6-6 Web界面查看YARN集群 2.查看`ResourceManager`状态 在`hadoop1`节点上,使用命令查看两个ResourceManager的状态,具体操作如图6-7所示。 图6-7 查看ResourceManager状态
如果一个ResourceManager为active状态,另外一个ResourceManager为standby状态,说明YARN集群构建成功。
3.YARN集群测试
为了测试YARN集群是否可以正常运行MapReduce程序,我们以Hadoop自带的wordcount示例来进行演示,具体操作如图6-8所示。

图6-8 YARN集群运行wordcount
MapReduce作业在YARN集群执行状态结果,如图6-9所示。

图6-9 MapReduce作业运行状态
如果上述操作没有异常,最终作业的状态信息显示为SUCCEEDED,就说明MapReduce程序在YARN集群上面运行成功,从而说明Hadoop分布式集群已经全部搭建成功。
在生产环境中,Hadoop集群一旦运行起来之后不会轻易关闭,日常工作更多的是对Hadoop集群进行管理和维护。
Hadoop集群进程的管理主要是对NameNode、DataNode、ResourceManager和NodeManager等进程进行上线和下线操作,接下来我们分别对每个进程的操作进行讲解。 1.NameNode守护进程管理 (1)下线操作 执行sbin/hadoop-daemon.sh stop namenode 命令关闭NameNode进程,如果此时关闭的是Active状态的NameNode,那么备用的NameNode会自动切换为Active状态对外提供服务。NameNode进程关闭之后,可以对其所在节点进行相关维护操作。 (2)上线操作 完成对NameNode所在节点的维护工作之后,可以执行sbin/hadoop-daemon.sh start namenode命令重新启动NameNode进程。如果HDFS集群中已经有NameNode为Active状态,那么刚刚启动的NameNode会以Standby状态运行。 2.DataNode守护进程管理 (1)下线操作 执行sbin/hadoop-daemon.sh stop datanode 命令关闭DataNode进程,此时当前DataNode中的数据块会迁移到其他DataNode节点中,从而实现数据容错。等待DataNode进程关闭之后,即可对数据节点进行相关的维护操作。 (2)上线操作 完成对DataNode所在节点的维护工作之后,可以执行sbin/hadoop-daemon.sh start datanode命令重新启动DataNode进程。然后可以执行负载均衡命令,将集群中的部分数据块迁移到当前DataNode节点中,从而提高集群的数据存储能力。 3.ResourceManager守护进程管理 (1)下线操作 执行sbin/yarn-daemon.sh stop resourcemanager命令关闭ResourceManager进程,如果此时关闭的是Active状态的ResourceManager,那么备用的ResourceManager会自动切换为Active状态对外提供服务。ResourceManager进程关闭之后,可以对其所在节点进行相关维护操作。 (2)上线操作 完成对ResourceManager所在节点的维护工作之后,可以执行sbin/yarn-daemon.sh start resourcemanager命令重新启动ResourceManager进程。如果YARN集群中已经有ResourceManager为Active状态,那么刚刚启动的ResourceManager会以Standby状态运行。 4.NodeManager守护进程管理 (1)下线操作 执行sbin/yarn-daemon.sh stop nodemanager命令关闭NodeManager进程,此时如果当前NodeManager所在节点运行有task任务,YARN集群会自动将task任务调度到其他NodeManager节点运行。等待NodeManager进程关闭之后,即可对该节点进行相关的维护操作。 (2)上线操作 完成对NodeManager所在节点的维护工作之后,可以执行sbin/yarn-daemon.sh start nodemanager命令重新启动NodeManager进程。当YARN集群中有新的task任务需要运行,会优先提交到当前NodeManager所在节点运行。
在实际工作中,针对 Hadoop 集群的运行和维护涉及方方面面,接下来将介绍两种常见的运维技巧。 1.查看日志 Hadoop 集群运行过程中,无论遇到什么错误或异常,日志是 Hadoop 运维最重要的依据,第一步操作就是查看 Hadoop 运行日志。Hadoop 集群各个进程的日志路径如下所示。
$ HADOOP_HOME/logs/hadoop-hadoop-namenode-hadoop1.log
$ HADOOP_HOME/logs/yarn-hadoop-resourcemanager-hadoop1.log
$ HADOOP_HOME/logs/hadoop-hadoop-datanode-hadoop1.log
$ HADOOP_HOME/logs/yarn-hadoop-nodemanager-hadoop1.log一般可以通过Linux命令查看日志,比如vi、cat等命令。也可以通过tail -f命令实时查看更新的日志。 2.清理临时文件 大多数情况下,由于对集群操作太频繁或者日志输出不合理,会造成日志文件和临时文件占用大量磁盘,直接影响正常 HDFS 的存储,此时可以定期清理这些临时文件,临时文件的路径如下所示。
(1)HDFS的临时文件路径:${hadoop.tmp.dir}/mapred/staging。
(2)本地临时文件路径:${mapred.local.dir}/mapred/local。3.定期执行负载均衡脚本 造成HDFS数据不均衡的原因有很多,比如新增一个DataNode、快速删除HDFS上的大量文件、计算任务分布不均匀等。数据不均衡会降低MapReduce计算本地化的概率,从而降低作业执行效率。当发现Hadoop集群数据不均衡,可以执行Hadoop脚本sbin/start-balancer.sh进行负载均衡操作。
随着公司业务的增长,数据量越来越大,原有DataNode节点的容量已经不能满足数据存储的需求,需要在原有集群基础上动态添加新的数据节点,也就是俗称的动态扩容。如果在Hadoop集群运行过程中,某些节点变得反常,例如故障率过高或者性能过低,可能就需要停止这些节点上的Hadoop服务,并从Hadoop集群中移除,也就是俗称的动态缩容。通常情况下,节点需要同时运行DataNode和NodeManager守护进程,所以两者一般同时新增或者移除。
增加一个新节点非常简单:首先配置hdfs-site.xml文件指向NameNode,然后配置yarn-site.xml文件指向ResourceManager,最后启动DataNode和NodeManager守护进程即可。 然而随便允许一台机器以DataNode的身份连接到NameNode是非常不安全的,因为该机器很可能会访问未授权的数据。此外,这台机器可能并非真正的DataNode,不在集群的控制之内,随时可能停止从而导致潜在的数据丢失。另外由于错误配置的可能性,即使这台机器都在本机房的防火墙之内,这种做法的风险也比较高。因此所有工作集群上的DataNode(或者NodeManager)都应该被明确管理。 我们将允许连接到NameNode的所有DataNode都放在一个文件中,文件名称由dfs.hosts属性指定,该文件的每一行对应一个DataNode的网络地址。类似的,可能连接到ResourceManager的各个NodeManager也是在一个文件中指定,该文件的名称由yarn.resourcemanager.nodes.include-path属性指定。 在通常情况下,由于集群中的节点同时运行DataNode和NodeManager守护进程,dfs.hosts和yarn.resourcemanager.nodes.include-path会同时指向一个文件,即取名为include文件。include文件不同于slaves文件,前者提供NameNode和ResourceManager使用,用于决定可以连接到哪些工作节点。Hadoop控制脚本使用slaves文件执行面向整个集群范围的操作,比如启停Hadoop集群等,而Hadoop守护进程从来不会使用slaves文件。
HDFS集群能够容忍DataNode故障,这并不意味着我们可以随意终止DataNode。HDFS集群默认配置为3个副本,如果同时关闭不同机架上的3个DataNode,则数据丢失的概率非常高。正确的操作方法是,我们将准备移除的DataNode告知NameNode,那么HDFS集群会在DataNode停机之前,将数据块复制到其他DataNode,从而实现数据容错。 有了NodeManager的支持,YARN集群对故障的容忍度更高。如果关闭一个正在运行MapReduce作业的NodeManager,ApplicationMaster会检测到故障,并在其他NodeManager节点上重新调度失败的任务。 需要移除的节点是由exclude文件控制。对于HDFS集群来说,exclude文件路径是由dfs.hosts.exclude属性设置。对于YARN集群来说,exclude文件路径是由yarn.resourcemanager.nodes.exclude-path属性设置。通常情况下,准备移除的节点同时运行着DataNode和Nodemanager守护进程,这两个属性指向同一个文件。
在Hadoop集群进行动态扩缩容之前,首先需要修改原有集群的配置文件,具体操作步骤如下所示。 1.配置include文件路径 在NameNode节点(hadoop1)上,修改hdfs-site.xml配置文件添加dfs.hosts属性,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi hdfs-site.xml
<property>
<name>dfs.hosts</name>
<value>/home/hadoop/app/hadoop/etc/hadoop/include</value>
</property>在ResourceManager节点(hadoop1)上,修改yarn-site.xml配置文件添加
yarn.resourcemanager.nodes.include-path属性,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi yarn-site.xml
<property>
<name>yarn.resourcemanager.nodes.include-path</name>
<value>/home/hadoop/app/hadoop/etc/hadoop/include</value>
</property>2.创建include文件 在NameNode和ResourceManager节点(hadoop1)上,创建include文件,并将集群节点的hostname信息添加到include文件中,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi include
hadoop1
hadoop2
hadoop33.配置exclude文件路径
在NameNode(hadoop1)节点上,修改hdfs-site.xml配置文件添加dfs.hosts.exclude属性,具体配置如下所示。
[hadoop@hadoop1 hadoop]$ vi hdfs-site.xml
<property>
<name>dfs.hosts.exclude</name>
<value>/home/hadoop/app/hadoop/etc/hadoop/exclude</value>
</property>在ResourceManager(hadoop1)节点上,修改yarn-site.xml配置文件添加yarn.resourcemanager.nodes.exclude-path属性,具体配置如下所示。
[hadoop@hadoop1 hadoop]$ vi yarn-site.xml
<property>
<name>yarn.resourcemanager.nodes.exclude-path</name>
<value>/home/hadoop/app/hadoop/etc/hadoop/exclude</value>
</property>4.创建exclude文件 在NameNode节点和ResourceManager节点(hadoop1)上,创建一个空的exclude文件即可,具体配置如下所示。
[hadoop@hadoop1 hadoop]$ touch exclude5.同步修改的配置文件 将hadoop1节点中修改的配置文件远程拷贝到集群其他节点,这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp hdfs-site.xml hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/
[hadoop@hadoop1 hadoop]$ scp yarn-site.xml hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/
[hadoop@hadoop1 hadoop]$ scp include hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/
[hadoop@hadoop1 hadoop]$ scp exclude hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/6.启动Hadoop集群 (1)启动Zookeeper集群 在集群所有节点分别启动Zookeeper服务,具体操作如下所示。
[hadoop@hadoop1 zookeeper]$ bin/zkServer.sh start
[hadoop@hadoop2 zookeeper]$ bin/zkServer.sh start
[hadoop@hadoop3 zookeeper]$ bin/zkServer.sh start(2)启动HDFS集群 在hadoop1节点上,使用脚本一键启动HDFS集群,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ sbin/start-dfs.sh(3)启动YARN集群 在hadoop1节点上,使用脚本一键启动YARN集群,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ sbin/start-yarn.sh向Hadoop集群添加新节点的操作步骤如下所示。 1.基础准备 (1)准备新节点 首先准备好一个新的虚拟机节点,创建hadoop用户和用户组,然后将静态IP设置为192.168.0.114,、主机名设置为hadoop4,最后完成免密登录、关闭防火墙、JDK和时钟同步等配置操作。 (2)配置hosts文件 在hadoop1节点上修改hosts文件,将集群所有节点(包含新增节点)的hostname与IP地址映射配置进去,同时集群所有节点保持hosts文件统一。hosts文件具体内容如下所示。
[root@hadoop1 ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.111 hadoop1
192.168.0.112 hadoop2
192.168.0.113 hadoop3
192.168.0.114 hadoop4(3)SSH免密登录 为了设置NameNode节点(hadoop1)到新增DataNode节点(hadoop4)的免密登录,我们需要将hadoop4节点的公钥id_ras.pub复制到hadoop1节点中的authorized_keys文件中,具体操作如下所示。
[hadoop@hadoop4 ~]$cat ~/.ssh/id_rsa.pub | ssh hadoop@hadoop1 'cat >> ~/.ssh/authorized_keys'然后将hadoop1节点中的authorized_keys文件分发到hadoop4节点,具体操作如下所示。
[hadoop@hadoop1 .ssh]$scp -r authorized_keys hadoop@hadoop4:~/.ssh/然后在hadoop1节点的hadoop用户下,使用如下命令即可免密登录hadoop4节点。
[hadoop@hadoop1 .ssh]$ ssh hadoop4(4)新增节点安装Hadoop 在NameNode节点(hadoop1)上,将Hadoop安装目录拷贝到hadoop4节点,具体操作如下所示。
[hadoop@hadoop1 app]$scp -r hadoop-2.9.2 hadoop@hadoop4:/home/hadoop/app/然后在hadoop4节点上创建软连接,具体操作如下所示。
[hadoop@hadoop4 app]$ ln -s hadoop-2.9.2 hadoop2.添加新增节点 (1)修改include文件 在NameNode和ResourceManager节点(hadoop1)上,修改include文件,并将新增节点的hostname信息添加到include文件中,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi include
hadoop1
hadoop2
hadoop3
hadoop4然后将修改后的include文件同步集群其他节点(包括新增节点),这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp include hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/(2)刷新NameNode 将一系列审核过的DataNode来更新NameNode设置,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ bin/hdfs dfsadmin -refreshNodes(3)刷新ResourceManager 将一系列审核过的NodeManager来更新ResourceManager设置,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ bin/yarn rmadmin -refreshNodes(4)修改slaves文件 在NameNode节点(hadoop1)上,修改slaves文件添加新增节点的hostname信息,以便Hadoop控制脚本启停集群时将新增节点纳入操作范围,具体配置如下所示。
[hadoop@hadoop1 hadoop]$ vi slaves
hadoop1
hadoop2
hadoop3
hadoop4备注:使用一键启动脚本启动Hadoop集群时,会根据slaves文件中的hostname信息启动从节点的DataNode和NodeManager守护进程。 然后将修改后的slaves文件同步到集群其他节点(包括新增节点),这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp slaves hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/(5)启动新增节点 在新增的hadoop4节点中,使用如下命令启动DataNode和NodeManager守护进程。
[hadoop@hadoop4 hadoop]$ sbin/hadoop-daemon.sh start datanode
[hadoop@hadoop4 hadoop]$sbin/yarn-daemon.sh start nodemanager(6)检查新增节点 分别通过HDFS(地址:http://hadoop1:50070/)和YARN(地址:http://hadoop1:8088/)的Web界面,查看新增节点hadoop4是否添加成功。如果能检查到新的DataNode和NodeManager,则说明Hadoop集群扩容成功了。 (7)启动负载均衡 当Hadoop集群扩容成功之后,HDFS集群不会自动将数据块从旧的DataNode迁移到新的DataNode以保持集群数据负载均衡,而是需要用户手动执行脚本来实现负载均衡,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ sbin/start-balancer.sh从Hadoop集群移除节点的操作步骤如下所示。 (1)修改exclude文件 在NameNode和ResourceManager节点(hadoop1)上,修改exclude文件,并将需要移除节点的hostname信息添加到exclude文件中,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi exclude
hadoop4然后将修改后的exclude文件同步集群其他节点(包括新增节点),这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp exclude hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/(2)刷新NameNode 在NameNode(hadoop1)节点上,使用一组新的审核过的DataNode来更新NameNode设置,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ bin/hdfs dfsadmin -refreshNodes(3)刷新ResourceManager 在ResourceManager(hadoop1)节点上,使用一组新的审核过的NodeManager来更新ResourceManager设置,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ bin/yarn rmadmin -refreshNodes(4)开始解除节点 通过Web界面(地址:http://hadoop1:50070/)查看待解除DataNode的管理状态是否已经变为正在解除(Decommission In Progress),因为此时相关的DataNode正在被解除过程中,这些DataNode会把它们的数据块复制到其他DataNode中。当所有DataNode的状态变为解除完毕(Decommissioned)时,表明所有数据块已经复制完毕,此时会关闭已经解除的节点。 (5)停止退役节点进程 等待退役节点hadoop4的状态为decommissioned时,说明所有块已经复制成功,然后使用如下命令关闭DataNode和NodeManager进程。
[hadoop@hadoop4 hadoop]$ sbin/hadoop-daemon.sh stop datanode
#操作之前,NodeManager进程其实已经关闭
[hadoop@hadoop4 hadoop]$ sbin/yarn-daemon.sh stop nodemanager(6)修改include文件 在NameNode和ResourceManager节点(hadoop1)中,从include文件中删除退役节点hadoop4的hostname信息,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi include
hadoop1
hadoop2
hadoop3然后将修改后的include文件同步集群其他节点(包括退役节点),这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp include hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/(7)刷新NameNode和ResourceManager 在NameNode和ResourceManager节点(hadoop1)中,刷新NameNode和ResourceManager的设置,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ bin/hdfs dfsadmin -refreshNodes
[hadoop@hadoop1 hadoop]$ bin/yarn rmadmin -refreshNodes(8)修改slaves文件 在NameNode(hadoop1)节点上,从slaves文件中删除退役节点hadoop4的hostname信息,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ vi slaves
hadoop1
hadoop2
hadoop3然后将修改后的slaves文件同步集群其他节点(包括退役节点),这里以hadoop2节点为例,具体操作如下所示。
[hadoop@hadoop1 hadoop]$ scp slaves hadoop@hadoop2:/home/hadoop/app/hadoop/etc/hadoop/(9)启动负载均衡 若Hadoop集群中数据分布不均匀,可以使用如下命令启动负载均衡。
[hadoop@hadoop1 hadoop]$ sbin/start-balancer.sh