Hadoop集群动态扩缩容
1 项目需求
随着公司业务的增长,数据量越来越大,原有DataNode节点的容量已经不能满足数据存储的需求,需要在原有集群基础上动态添加新的数据节点,也就是俗称的动态扩容。如果在Hadoop集群运行过程中,某些节点变得反常,例如故障率过高或者性能过低,可能就需要停止这些节点上的Hadoop服务,并从Hadoop集群中移除,也就是俗称的动态缩容。通常情况下,节点需要同时运行DataNode和NodeManager守护进程,所以两者一般同时新增或者移除。
2 动态扩容原理
增加一个新节点非常简单:首先配置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文件。
3 动态缩容原理
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守护进程,这两个属性指向同一个文件。
4 原Hadoop集群配置与启动
在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
hadoop3
3.配置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 exclude
5.同步修改的配置文件
将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
5 Hadoop集群动态扩容
向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 hadoop
2.添加新增节点
(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
6 集群动态缩容
从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
想了解更多大数据技术,如大数据运维、大数据开发、大数据架构、湖仓一体化、流批一体、离线+实时数仓等等,可以扫描添加下面微信。