https://blog.csdn.net/everl_1/article/details/52303011
一个显然的前提是,两台namenode节点需要保存一致的元数据。
我们知道namenode节点是用来管理这些元数据的,响应客户端请求时(上传)需要增加元数据信息,如果使用主主模式,那么两个节点都将对元数据进行写操作,怎么同步是个很困难的问题。因此,只能有一台机器响应请求,也即处在active状态的节点(可称为主节点),而另一台namenode在主节点正常工作情况下仅用来同步active节点的元数据信息,这个namenode称为备用节点(处在standby状态),可见,要解决的问题主要是怎么同步active节点的元数据信息。
响应客户端请求的是active节点,因此只有active节点保存了最新的元数据。元数据分为两部分,一部分是刚写入新的元数据(edits),另一部分是合并后的较旧的(fsimage)。HA机制解决同步问题的方法是将active节点新写入的edits元数据放在zookeeper集群上(zookeeper集群主要功能是实现少量数据的分布式同步管理),standby节点在active节点正常情况下只需要将zookeeper集群上edits文件同步到自己的fsimage中就可以。
hadoop框架为这个集群专门写了个分布式应用qjournal(依赖zookeeper实现),实现qjournal的节点称为journalnode。
解决方案是专门在namenode节点上启动一个监控进程,时刻监控namenode的状态。对于处在active状态的namenode,如果发现不正常就向zookeeper集群中写入一些数据。对于处在standby状态的namenode,监控进程从zookeeper集群中读数据,从而感知到active节点是否正常。如果发现异常,监控进程负责将standby状态切换到active状态。这个监控进程在hadoop中叫做zkfc(依赖zookeeper实现)。
脑裂:active namenode工作不正常后,zkfc在zookeeper中写入一些数据,表明异常,这时standby namenode中的zkfc读到异常信息,并将standby节点置为active。但是,如果之前的active namenode并没有真的死掉,出现了假死(死了一会儿后又正常了,哈哈,是不是很搞笑),这样,就有两台namenode同时工作了。这种现象称为脑裂。
解决方案:standby namenode感知到主用节点出现异常后并不会立即切换状态,zkfc会首先通过ssh远程杀死active节点的 namenode进程(kill -9 进程号)。但是(这样还不行,惊讶),如果kill指令没有执行成功咋办??如果在一段时间内没有收到执行成功的回执,standby节点会执行一个自定义脚本,尽量保证不会出现脑裂问题!这个机制在hadoop中称为fencing(包括ssh发送kill指令,执行自定义脚本两道保障)
解决上诉问题以后,基本上就实现了hadoop HA 。
主机名 软件 进程 sempplsl-02 jdk,hadoop,zookeeper QuorumPeerMain(zookeeper),journalnode,datanode,nodemanager sempplsl-03 jdk,hadoop,zookeeper QuorumPeerMain(zookeeper),journalnode,datanode,nodemanager sempplsl-04 jdk,hadoop,zookeeper QuorumPeerMain(zookeeper),journalnode,datanode,nodemanager sempplsl-05 jdk,hadoop namenode,zkfc(active) sempplsl-06 jdk,hadoop namenode,zkfc sempplsl-07 jdk,hadoop resourcemanager sempplsl-08 jdk,hadoop resourcemanager
(注:datanode,nodemanager一般放到一起。journalnode依赖zookeeper来实现,因此QuorumPeerMain(zookeeper),journalnode必须放一起!)
core-site.xml ---->
fs.defaultFS
hdfs://ns1/
hadoop.tmp.dir
/home/hadoop/app/hadoop-2.4.1/tmp
ha.zookeeper.quorum
sempplsl-02:2181,sempplsl-03:2181,sempplsl-04:2181
hdfs-site.xml --->
dfs.nameservices
ns1
dfs.ha.namenodes.ns1
nn1,nn2
dfs.namenode.rpc-address.ns1.nn1
sempplsl-05:9000
dfs.namenode.http-address.ns1.nn1
sempplsl-05:50070
dfs.namenode.rpc-address.ns1.nn2
sempplsl-06:9000
dfs.namenode.http-address.ns1.nn2
sempplsl-06:50070
dfs.namenode.shared.edits.dir
qjournal://sempplsl-02:8485;sempplsl-03:8485;sempplsl-04:8485/ns1
dfs.journalnode.edits.dir
/home/hadoop/app/hadoop-2.4.1/journaldata
dfs.ha.automatic-failover.enabled
true
dfs.client.failover.proxy.provider.ns1
org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
dfs.ha.fencing.methods
sshfence
shell(/bin/true)
dfs.ha.fencing.ssh.private-key-files
/home/hadoop/.ssh/id_rsa
dfs.ha.fencing.ssh.connect-timeout
30000
yarn-site.xml --->
yarn.resourcemanager.ha.enabled
true
yarn.resourcemanager.cluster-id
yrc
yarn.resourcemanager.ha.rm-ids
rm1,rm2
yarn.resourcemanager.hostname.rm1
sempplsl-07
yarn.resourcemanager.hostname.rm2
sempplsl-08
yarn.resourcemanager.zk-address
sempplsl-02:2181,sempplsl-02:2181,sempplsl-02:2181
yarn.nodemanager.aux-services
mapreduce_shuffle
marped-site.xml --->
mapreduce.framework.name
yarn
slaves文件保存子节点的位置,要在sempplsl-05上启动hdfs,按照集群配置,需要指定datanode在sempplsl-02,sempplsl-03,sempplsl-04上,方法是进入sempplsl-05机器中的hadoop-2.4.1/etc/hadoop安装文件夹。
此外,在sempplsl-07上启动yarn,按照集群配置,需要指定nodemanager在sempplsl-02,sempplsl-03,sempplsl-04上,方法同上。
配置sempplsl-05到sempplsl-02,sempplsl-03,sempplsl-04,sempplsl-06的无密钥登陆;(ssh-keygen -t rsa,ssh-copy-id 目标主机)
配置sempplsl-07到sempplsl-02,sempplsl-03,sempplsl-04,sempplsl-08的无密钥登陆;
scp -r
分别在sempplsl-02,sempplsl-03,sempplsl-04机器上执行启动指令:./zkServer.sh start
查看zookeeper状态:./zkServer.sh status, 正确的状态是一个leader,两个follower。
分别在sempplsl-02,sempplsl-03,sempplsl-04机器上执行启动指令:sbin/hadoop-daemon.sh start journalnode。
启动成功后会多出一个JournalNode进程。
在sempplsl-05上执行格式化指令:hadoop namenode -format
在sempplsl-05上执行格式化指令: hdfs zkfc -formatZK
格式化成功后会在zookeeper集群建立新的文件路径(该路径下存放zkfc监控namenode节点的信息)
在sempplsl-05上执行:start-dfs.sh。
在sempplsl-07上执行sbin/start-yarn.sh
在sempplsl-08上执行./yarn-daemon.sh start resourcemanager
至此,HA集群启动成功!