Hadoop使用了master/slave的集群架构。master包括了NameNode和ResourseManager两个重要的Hadoop节点。所以master是一种非常重要的节点。一定要保证master的硬件资源是最好的。
但是,即使是最好硬件,最稳定的机器也可能出现问题,而master又是如此重要,所以我们需要一种高可用架构,使得即使master坏掉,整个集群也能迅速恢复工作。
Hadoop 2.x引入了高可用的集群架构,这个架构方案是针对master单点故障导致整个集群奔溃提出的解决方案。
架构的关键就是配置多台master主机,形成一个master集群。一个master是真正工作的,另外的master备份工作master的数据。一旦工作master宕机,其余的master能够马上进入工作状态。
这涉及到两个master状态:Active和Stand-by。表示工作状态和等待状态。
那么我们如何维护这个master集群,如何实时获取、修改它们的状态呢?这就可以使用ZooKeeper对它们进行管理。
我们可以让每个master主机保持一个Zookeeper临时节点。当Active的临时节点消失(要么网络差,要么这个NameNode奔溃了),就马上选出一个新的master。
为了保持高可用性,需要保证多个master保持同步。所以我们还需要Journal Node(s)节点。
拿NameNode来说,所有NameNode节点都保持和Journal Node(s)节点的通信。当Active NameNode更新了元数据信息,会把日志修改记录发给Journal Node(s),Stand-by NameNode(s)会从Journal Node(s)上读取这些更新的edits文件或者是edits的更新记录。随后将日志变更保存在自己这里。可见这是一种热备份(注意区别于SecondaryNameNode,是冷备份)。
如果Active NameNode挂掉了,被选为新的Active Namenode的Stand-by NameNode会马上从Journal Node(s)处更新一遍edits。确保此时的元数据和Active的一致。
ResourceManager也使用Journal Node(s)来保证元数据的热备份,它可以和NameNode共用Journal Node(s)。
以上架构需要多个NameNode、ResourseManager、DataNode、NodeManager、Zookeeper、Journal Node(s)等,需要大量的机器。如果经济情况不好,可以做适当的合并。例如把NameNode和Zookeeper放在一起。
准备集群
下面以6台虚拟机(CentOS 6.5)作为示例。
集群的架构策略如下:
- master1
- Zookeeper
- NameNode (active)
- ResourceManager (active)
- master2
- Zookeeper
- NameNode (stand-by)
- master3
- Zookeeper
- ResourceManager (stand-by)
- slave1
- DataNode
- NodeManager
- JournalNode
- slave2
- DataNode
- NodeManager
- JournalNode
- slave3
- DataNode
- NodeManager
- JournalNode
我们先准备一台纯净的虚拟机,随后拷贝虚拟机即可。按照以下的步骤操作:
准备jdk,这里使用1.8_65版本,具体步骤不再演示。
[root@master1 ~]# java -version
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
[root@master1 ~]# javac -version
javac 1.8.0_65
[root@master1 ~]# echo $JAVA_HOME
/usr/develop/jdk1.8.0_65
[root@master1 ~]# echo $JRE_HOME
/usr/develop/jdk1.8.0_65/jre
关闭防火墙(真实环境请配置iptables,不要关闭)
[root@master1 ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter [ OK ]
iptables: Flushing firewall rules: [ OK ]
iptables: Unloading modules: [ OK ]
[root@master1 ~]# chkconfig iptables off
配置主机名以及hosts文件
[root@master1 ~]# vim /etc/hosts
127.0.0.1 localhost
::1 localhost
192.168.117.52 master1
192.168.117.53 master2
192.168.117.54 master3
192.168.117.55 slave1
192.168.117.56 slave2
192.168.117.57 slave3
安装Hadoop,不进行配置。加上HADOOP_HOME环境变量,将HADOOP的bin和sbin加入PATH
[root@master1 hadoop-2.7.1]# echo $HADOOP_HOME
/usr/develop/hadoop-2.7.1
[root@master1 hadoop-2.7.1]# hadoop version
Hadoop 2.7.1
Subversion https://git-wip-us.apache.org/repos/asf/hadoop.git -r 15ecc87ccf4a0228f35af08fc56de536e6ce657a
Compiled by jenkins on 2015-06-29T06:04Z
Compiled with protoc 2.5.0
From source with checksum fc0a1a23fc1868e4d5ee7fa2b28a58a
This command was run using /usr/develop/hadoop-2.7.1/share/hadoop/common/hadoop-common-2.7.1.jar
随后,关机,克隆5台虚拟机。
克隆完成之后,根据上面的方案修改每台主机的配置。注意需要修改/etc/sysconfig/network下的主机名和/etc/sysconfig/network-script/ifcfg-eth0下的ip地址。
下面演示修改master2的步骤,其余都是类似的:
配置克隆机的网卡(否则会使用eth1)
[root@master2 ~]# vim /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:0c:29:b7:b0:19", ATTR{
type}=="1", KERNEL=="eth*", NAME="eth0"
配置host
[root@master2 ~]# vim /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=master2
NTPSERVERARGS=iburst
配置ifcfg-etho0
[root@master2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
IPADDR=192.168.117.53
NETMASK=255.255.255.0
GATEWAY=192.168.117.2
ONBOOT=yes
TYPE=Ethernet
IPV6INIT=no
DNS1=192.168.117.2
其余克隆机的配置步骤和上面类似,注意需要配置为自己的ip和host。
确保各个虚拟机之间能够ping通后,给这6台虚拟机配置ssh免密登录。
6台虚拟机都需要生成公钥和私钥。并且要发送到其余的虚拟机上。
下面是在master1上配置ssh免密,然后发送到其余5台和自己上。每台的操作都和master1类似:
[root@master1 ~]# ssh-keygen
[root@master1 ~]# ssh-copy-id -i root@master1
[root@master1 ~]# ssh-copy-id -i root@master2
[root@master1 ~]# ssh-copy-id -i root@master3
[root@master1 ~]# ssh-copy-id -i root@slave1
[root@master1 ~]# ssh-copy-id -i root@slave2
[root@master1 ~]# ssh-copy-id -i root@slave3
确保每台机器之间能够正常免密登录之后,准备工作就完成了。
为master安装Zookeeper
现在master1上,把Zookeeper的安装包上传。然后解压。
[root@master1 ~]# tar xzf zookeeper-3.4.7.tar.gz -C /usr/develop/
[root@master1 ~]# rm zookeeper-3.4.