Hadoop HA高可用集群配置详解

来源:互联网 发布:驼峰航线 知乎 编辑:程序博客网 时间:2024/05/01 22:14

1 Hadoop HA架构详解

1.1 HDFS HA背景

HDFS集群中NameNode 存在单点故障(SPOF)。对于只有一个NameNode的集群,如果NameNode机器出现意外情况,将导致整个集群无法使用,直到NameNode 重新启动。

影响HDFS集群不可用主要包括以下两种情况:一是NameNode机器宕机,将导致集群不可用,重启NameNode之后才可使用;二是计划内的NameNode节点软件或硬件升级,导致集群在短时间内不可用。

为了解决上述问题,Hadoop给出了HDFS的高可用HA方案:HDFS通常由两个NameNode组成,一个处于active状态,另一个处于standby状态。Active NameNode对外提供服务,比如处理来自客户端的RPC请求,而Standby NameNode则不对外提供服务,仅同步Active NameNode的状态,以便能够在它失败时快速进行切换。

1.2 HDFS HA架构

一个典型的HA集群,NameNode会被配置在两台独立的机器上,在任何时间上,一个NameNode处于活动状态,而另一个NameNode处于备份状态,活动状态的NameNode会响应集群中所有的客户端,备份状态的NameNode只是作为一个副本,保证在必要的时候提供一个快速的转移。

为了让Standby Node与Active Node保持同步,这两个Node都与一组称为JNS的互相独立的进程保持通信(Journal Nodes)。当Active Node上更新了namespace,它将记录修改日志发送给JNS的多数派。Standby noes将会从JNS中读取这些edits,并持续关注它们对日志的变更。Standby Node将日志变更应用在自己的namespace中,当failover发生时,Standby将会在提升自己为Active之前,确保能够从JNS中读取所有的edits,即在failover发生之前Standy持有的namespace应该与Active保持完全同步。

为了支持快速failover,Standby node持有集群中blocks的最新位置是非常必要的。为了达到这一目的,DataNodes上需要同时配置这两个Namenode的地址,同时和它们都建立心跳链接,并把block位置发送给它们。

任何时刻,只有一个Active NameNode是非常重要的,否则将会导致集群操作的混乱,那么两个NameNode将会分别有两种不同的数据状态,可能会导致数据丢失,或者状态异常,这种情况通常称为“split-brain”(脑裂,三节点通讯阻断,即集群中不同的Datanodes却看到了两个Active NameNodes)。对于JNS而言,任何时候只允许一个NameNode作为writer;在failover期间,原来的Standby Node将会接管Active的所有职能,并负责向JNS写入日志记录,这就阻止了其他NameNode基于处于Active状态的问题。

Hadoop 2.0 HA高可用集群配置详解 www.linuxidc.com

 

基于QJM的HDFS HA方案如上图所示,其处理流程为:集群启动后一个NameNode处于Active状态,并提供服务,处理客户端和DataNode的请求,并把editlog写到本地和share editlog(这里是QJM)中。另外一个NameNode处于Standby状态,它启动的时候加载fsimage,然后周期性的从share editlog中获取editlog,保持与Active节点的状态同步。为了实现Standby在Active挂掉后迅速提供服务,需要DataNode同时向两个NameNode汇报,使得Stadnby保存block to DataNode信息,因为NameNode启动中最费时的工作是处理所有DataNode的blockreport。为了实现热备,增加FailoverController和Zookeeper,FailoverController与Zookeeper通信,通过Zookeeper选举机制,FailoverController通过RPC让NameNode转换为Active或Standby。

1.3 HDFS HA配置要素

NameNode机器:两台配置对等的物理机器,它们分别运行Active和Standby Node。

JouralNode机器:运行JouralNodes的机器。JouralNode守护进程相当的轻量级,可以和Hadoop的其他进程部署在一起,比如NameNode、DataNode、ResourceManager等,至少需要3个且为奇数,如果你运行了N个JNS,那么它可以允许(N-1)/2个JNS进程失效并且不影响工作。

在HA集群中,Standby NameNode还会对namespace进行checkpoint操作(继承Backup Namenode的特性),因此不需要在HA集群中运行SecondaryNameNode、CheckpointNode或者BackupNode。

1.4 HDFS HA配置参数

需要在hdfs.xml中配置如下参数:

dfs.nameservices:HDFS NN的逻辑名称,例如myhdfs。

dfs.ha.namenodes.myhdfs:给定服务逻辑名称myhdfs的节点列表,如nn1、nn2。

dfs.namenode.rpc-address.myhdfs.nn1:myhdfs中nn1对外服务的RPC地址。

dfs.namenode.http-address.myhdfs.nn1:myhdfs中nn1对外服务http地址。

dfs.namenode.shared.edits.dir:JournalNode的服务地址。

dfs.journalnode.edits.dir:JournalNode在本地磁盘存放数据的位置。

dfs.ha.automatic-failover.enabled:是否开启NameNode失败自动切换。

dfs.ha.fencing.methods :配置隔离机制,通常为sshfence。

1.5 HDFS自动故障转移

HDFS的自动故障转移主要由Zookeeper和ZKFC两个组件组成。

Zookeeper集群作用主要有:一是故障监控。每个NameNode将会和Zookeeper建立一个持久session,如果NameNode失效,那么此session将会过期失效,此后Zookeeper将会通知另一个Namenode,然后触发Failover;二是NameNode选举。ZooKeeper提供了简单的机制来实现Acitve Node选举,如果当前Active失效,Standby将会获取一个特定的排他锁,那么获取锁的Node接下来将会成为Active。

ZKFC是一个Zookeeper的客户端,它主要用来监测和管理NameNodes的状态,每个NameNode机器上都会运行一个ZKFC程序,它的职责主要有:一是健康监控。ZKFC间歇性的ping NameNode,得到NameNode返回状态,如果NameNode失效或者不健康,那么ZKFS将会标记其为不健康;二是Zookeeper会话管理。当本地NaneNode运行良好时,ZKFC将会持有一个Zookeeper session,如果本地NameNode为Active,它同时也持有一个“排他锁”znode,如果session过期,那么次lock所对应的znode也将被删除;三是选举。当集群中其中一个NameNode宕机,Zookeeper会自动将另一个激活。

1.6 YARN HA架构

Hadoop 2.0 HA高可用集群配置详解 www.linuxidc.com

YARN的HA架构和HDFSHA类似,需要启动两个ResourceManager,这两个ResourceManager会向ZooKeeper集群注册,通过ZooKeeper管理它们的状态(Active或Standby)并进行自动故障转移。

 

2 高可用集群规划

1.集群规划:

 主机名        IP                安装的软件                            运行的进程
drguo1  192.168.80.149 jdk、hadoop                         NameNode、DFSZKFailoverController(zkfc)、ResourceManager
drguo2 192.168.80.150  jdk、hadoop                         NameNode、DFSZKFailoverController(zkfc)、ResourceManager
drguo3  192.168.80.151  jdk、hadoop、zookeeper     DataNode、NodeManager、JournalNode、QuorumPeerMain
drguo4  192.168.80.152  jdk、hadoop、zookeeper     DataNode、NodeManager、JournalNode、QuorumPeerMain

drguo5 192.168.80.153  jdk、hadoop、zookeeper     DataNode、NodeManager、JournalNode、QuorumPeerMain

排的好好的,显示出来就乱了!!!

2.前期准备:

准备五台机器,修改静态IP、主机名、主机名与IP的映射,关闭防火墙,安装JDK并配置环境变量(不会请看这http://blog.csdn.net/dr_guo/article/details/50886667),创建用户:用户组,SSH免密码登录SSH免密码登录(报错请看这http://blog.csdn.net/dr_guo/article/details/50967442)。


注意:要把127.0.1.1那一行注释掉,要不然会出现jps显示有datanode,但网页显示live nodes为0;


注释之后就正常了,好像有人没注释也正常,我也不知道为什么0.0


3.搭建zookeeper集群(drguo3/drguo4/drguo5)

见:ZooKeeper完全分布式集群搭建

4.正式开始搭建Hadoop HA集群

去官网下最新的Hadoop(http://apache.opencas.org/hadoop/common/stable/),目前最新的是2.7.2,下载完之后把它放到/opt/Hadoop下

[plain] view plain copy
  1. guo@guo:~/下载$ mv ./hadoop-2.7.2.tar.gz /opt/Hadoop/  
  2. mv: 无法创建普通文件"/opt/Hadoop/hadoop-2.7.2.tar.gz": 权限不够  
  3. guo@guo:~/下载$ su root   
  4. 密码:   
  5. root@guo:/home/guo/下载# mv ./hadoop-2.7.2.tar.gz /opt/Hadoop/  
解压
[plain] view plain copy
  1. guo@guo:/opt/Hadoop$ sudo tar -zxf hadoop-2.7.2.tar.gz   
  2. [sudo] guo 的密码:  
解压jdk的时候我用的是tar -zxvf,其中的v呢就是看一下解压的过程,不想看你可以不写。

修改opt目录所有者(用户:用户组)直接把opt目录的所有者/组换成了guo。具体情况在ZooKeeper完全分布式集群搭建说过。

[plain] view plain copy
  1. root@guo:/opt/Hadoop# chown -R guo:guo /opt  

设置环境变量

[plain] view plain copy
  1. guo@guo:/opt/Hadoop$ sudo gedit /etc/profile  
在最后加上(这样设置在执行bin/sbin目录下的脚本时就不用进入该目录用了)
[plain] view plain copy
  1. #hadoop  
  2. export HADOOP_HOME=/opt/Hadoop/hadoop-2.7.2  
  3. export PATH=$PATH:$HADOOP_HOME/sbin  
  4. export PATH=$PATH:$HADOOP_HOME/bin  
然后更新配置
[plain] view plain copy
  1. guo@guo:/opt/Hadoop$ source /etc/profile  

修改/opt/Hadoop/hadoop-2.7.2/etc/hadoop下的hadoop-env.sh

[plain] view plain copy
  1. guo@guo:/opt/Hadoop$ cd hadoop-2.7.2  
  2. guo@guo:/opt/Hadoop/hadoop-2.7.2$ cd etc/hadoop/  
  3. guo@guo:/opt/Hadoop/hadoop-2.7.2/etc/hadoop$ sudo gedit ./hadoop-env.sh  
进入文件后
[plain] view plain copy
  1. export JAVA_HOME=${JAVA_HOME}#将这个改成JDK路径,如下  
  2. export JAVA_HOME=/opt/Java/jdk1.8.0_73  
然后更新文件配置
[plain] view plain copy
  1. guo@guo:/opt/Hadoop/hadoop-2.7.2/etc/hadoop$ source ./hadoop-env.sh 
前面配置和单机模式一样,我就直接复制了。
注意:汉语注释是给你看的,复制粘贴的时候都删了!!!
修改core-site.xml
[html] view plain copy
  1. <configuration>  
  2. <!-- 指定hdfs的nameservice为ns1 -->  
  3. <property>  
  4. <name>fs.defaultFS</name>  
  5. <value>hdfs://ns1/</value>  
  6. </property>  
  7. <!-- 指定hadoop临时目录 -->  
  8. <property>  
  9. <name>hadoop.tmp.dir</name>  
  10. <value>/opt/Hadoop/hadoop-2.7.2/tmp</value>  
  11. </property>  
  12. <!-- 指定zookeeper地址 -->  
  13. <property>  
  14. <name>ha.zookeeper.quorum</name>  
  15. <value>drguo3:2181,drguo4:2181,drguo5:2181</value>  
  16. </property>  
  17. </configuration>  
修改hdfs-site.xml
[html] view plain copy
  1. <configuration>  
  2.     <!--指定hdfs的nameservice为ns1,需要和core-site.xml中的保持一致 -->  
  3.     <property>  
  4.         <name>dfs.nameservices</name>  
  5.         <value>ns1</value>  
  6.     </property>  
  7.     <!-- ns1下面有两个NameNode,分别是nn1,nn2 -->  
  8.     <property>  
  9.         <name>dfs.ha.namenodes.ns1</name>  
  10.         <value>nn1,nn2</value>  
  11.     </property>  
  12.     <!-- nn1的RPC通信地址 -->  
  13.     <property>  
  14.         <name>dfs.namenode.rpc-address.ns1.nn1</name>  
  15.         <value>drguo1:9000</value>  
  16.     </property>  
  17.     <!-- nn1的http通信地址 -->  
  18.     <property>  
  19.         <name>dfs.namenode.http-address.ns1.nn1</name>  
  20.         <value>drguo1:50070</value>  
  21.     </property>  
  22.     <!-- nn2的RPC通信地址 -->  
  23.     <property>  
  24.         <name>dfs.namenode.rpc-address.ns1.nn2</name>  
  25.         <value>drguo2:9000</value>  
  26.     </property>  
  27.     <!-- nn2的http通信地址 -->  
  28.     <property>  
  29.         <name>dfs.namenode.http-address.ns1.nn2</name>  
  30.         <value>drguo2:50070</value>  
  31.     </property>  
  32.     <!-- 指定NameNode的元数据在JournalNode上的存放位置 -->  
  33.     <property>  
  34.         <name>dfs.namenode.shared.edits.dir</name>  
  35.         <value>qjournal://drguo3:8485;drguo4:8485;drguo5:8485/ns1</value>  
  36.     </property>  
  37.     <!-- 指定JournalNode在本地磁盘存放数据的位置 -->  
  38.     <property>  
  39.         <name>dfs.journalnode.edits.dir</name>  
  40.         <value>/opt/Hadoop/hadoop-2.7.2/journaldata</value>  
  41.     </property>  
  42.     <!-- 开启NameNode失败自动切换 -->  
  43.     <property>  
  44.         <name>dfs.ha.automatic-failover.enabled</name>  
  45.         <value>true</value>  
  46.     </property>  
  47.     <!-- 配置失败自动切换实现方式 -->  
  48.     <property>  
  49.         <name>dfs.client.failover.proxy.provider.ns1</name>  
  50.         <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>  
  51.     </property>  
  52.     <!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行-->  
  53.     <property>  
  54.         <name>dfs.ha.fencing.methods</name>  
  55.         <value>  
  56.             sshfence  
  57.             shell(/bin/true)  
  58.         </value>  
  59.     </property>  
  60.     <!-- 使用sshfence隔离机制时需要ssh免登陆 -->  
  61.     <property>  
  62.         <name>dfs.ha.fencing.ssh.private-key-files</name>  
  63.         <value>/home/guo/.ssh/id_rsa</value>  
  64.     </property>  
  65.     <!-- 配置sshfence隔离机制超时时间 -->  
  66.     <property>  
  67.         <name>dfs.ha.fencing.ssh.connect-timeout</name>  
  68.         <value>30000</value>  
  69.     </property>  
  70. </configuration>  
先将mapred-site.xml.template改名为mapred-site.xml然后修改mapred-site.xml
[html] view plain copy
  1. <configuration>  
  2.     <!-- 指定mr框架为yarn方式 -->  
  3.     <property>  
  4.         <name>mapreduce.framework.name</name>  
  5.         <value>yarn</value>  
  6.     </property>  
  7. </configuration>  
修改yarn-site.xml
[html] view plain copy
  1. <configuration>  
  2.     <!-- 开启RM高可用 -->  
  3.     <property>  
  4.        <name>yarn.resourcemanager.ha.enabled</name>  
  5.        <value>true</value>  
  6.     </property>  
  7.     <!-- 指定RM的cluster id -->  
  8.     <property>  
  9.        <name>yarn.resourcemanager.cluster-id</name>  
  10.        <value>yrc</value>  
  11.     </property>  
  12.     <!-- 指定RM的名字 -->  
  13.     <property>  
  14.        <name>yarn.resourcemanager.ha.rm-ids</name>  
  15.        <value>rm1,rm2</value>  
  16.     </property>  
  17.     <!-- 分别指定RM的地址 -->  
  18.     <property>  
  19.        <name>yarn.resourcemanager.hostname.rm1</name>  
  20.        <value>drguo1</value>  
  21.     </property>  
  22.     <property>  
  23.        <name>yarn.resourcemanager.hostname.rm2</name>  
  24.        <value>drguo2</value>  
  25.     </property>  
  26.     <!-- 指定zk集群地址 -->  
  27.     <property>  
  28.        <name>yarn.resourcemanager.zk-address</name>  
  29.        <value>drguo3:2181,drguo4:2181,drguo5:2181</value>  
  30.     </property>  
  31.     <property>  
  32.        <name>yarn.nodemanager.aux-services</name>  
  33.        <value>mapreduce_shuffle</value>  
  34.     </property>  
  35. </configuration>  
修改slaves
[html] view plain copy
  1. drguo3  
  2. drguo4  
  3. drguo5  
把Hadoop整个目录拷贝到drguo2/3/4/5,拷之前把share下doc删了(文档不用拷),这样会快点。
5.启动zookeeper集群(分别在drguo3、drguo4、drguo5上启动zookeeper)
[plain] view plain copy
  1. guo@drguo3:~$ zkServer.sh start  
  2. ZooKeeper JMX enabled by default  
  3. Using config: /opt/zookeeper-3.4.8/bin/../conf/zoo.cfg  
  4. Starting zookeeper ... STARTED  
  5. guo@drguo3:~$ jps  
  6. 2005 Jps  
  7. 1994 QuorumPeerMain  
  8. guo@drguo3:~$ ssh drguo4  
  9. Welcome to Ubuntu 15.10 (GNU/Linux 4.2.0-16-generic x86_64)  
  10.   
  11.  * Documentation:  https://help.ubuntu.com/  
  12.   
  13. Last login: Fri Mar 25 14:04:43 2016 from 192.168.80.151  
  14. guo@drguo4:~$ zkServer.sh start  
  15. ZooKeeper JMX enabled by default  
  16. Using config: /opt/zookeeper-3.4.8/bin/../conf/zoo.cfg  
  17. Starting zookeeper ... STARTED  
  18. guo@drguo4:~$ jps  
  19. 1977 Jps  
  20. 1966 QuorumPeerMain  
  21. guo@drguo4:~$ exit  
  22. 注销  
  23. Connection to drguo4 closed.  
  24. guo@drguo3:~$ ssh drguo5  
  25. Welcome to Ubuntu 15.10 (GNU/Linux 4.2.0-16-generic x86_64)  
  26.   
  27.  * Documentation:  https://help.ubuntu.com/  
  28.   
  29. Last login: Fri Mar 25 14:04:56 2016 from 192.168.80.151  
  30. guo@drguo5:~$ zkServer.sh start  
  31. ZooKeeper JMX enabled by default  
  32. Using config: /opt/zookeeper-3.4.8/bin/../conf/zoo.cfg  
  33. Starting zookeeper ... STARTED  
  34. guo@drguo5:~$ jps  
  35. 2041 Jps  
  36. 2030 QuorumPeerMain  
  37. guo@drguo5:~$ exit  
  38. 注销  
  39. Connection to drguo5 closed.  
  40. guo@drguo3:~$ zkServer.sh status  
  41. ZooKeeper JMX enabled by default  
  42. Using config: /opt/zookeeper-3.4.8/bin/../conf/zoo.cfg  
  43. Mode: leader  
6.启动journalnode(分别在drguo3、drguo4、drguo5上启动journalnode)注意只有第一次需要这么启动,之后启动hdfs会包含journalnode。
[plain] view plain copy
  1. guo@drguo3:~$ hadoop-daemon.sh start journalnode  
  2. starting journalnode, logging to /opt/Hadoop/hadoop-2.7.2/logs/hadoop-guo-journalnode-drguo3.out  
  3. guo@drguo3:~$ jps  
  4. 2052 Jps  
  5. 2020 JournalNode  
  6. 1963 QuorumPeerMain  
  7. guo@drguo3:~$ ssh drguo4  
  8. Welcome to Ubuntu 15.10 (GNU/Linux 4.2.0-16-generic x86_64)  
  9.   
  10.  * Documentation:  https://help.ubuntu.com/  
  11.   
  12. Last login: Fri Mar 25 00:09:08 2016 from 192.168.80.149  
  13. guo@drguo4:~$ hadoop-daemon.sh start journalnode  
  14. starting journalnode, logging to /opt/Hadoop/hadoop-2.7.2/logs/hadoop-guo-journalnode-drguo4.out  
  15. guo@drguo4:~$ jps  
  16. 2103 Jps  
  17. 2071 JournalNode  
  18. 1928 QuorumPeerMain  
  19. guo@drguo4:~$ exit  
  20. 注销  
  21. Connection to drguo4 closed.  
  22. guo@drguo3:~$ ssh drguo5  
  23. Welcome to Ubuntu 15.10 (GNU/Linux 4.2.0-16-generic x86_64)  
  24.   
  25.  * Documentation:  https://help.ubuntu.com/  
  26.   
  27. Last login: Thu Mar 24 23:52:17 2016 from 192.168.80.152  
  28. guo@drguo5:~$ hadoop-daemon.sh start journalnode  
  29. starting journalnode, logging to /opt/Hadoop/hadoop-2.7.2/logs/hadoop-guo-journalnode-drguo5.out  
  30. guo@drguo5:~$ jps  
  31. 2276 JournalNode  
  32. 2308 Jps  
  33. 1959 QuorumPeerMain  
  34. guo@drguo5:~$ exit  
  35. 注销  
  36. Connection to drguo5 closed.  
在drguo4/5启动时发现了问题,没有journalnode,查看日志发现是因为汉语注释造成的,drguo4/5全删了问题解决。drguo4/5的拼音输入法也不能用,我很蛋疼。。镜像都是复制的,咋还变异了呢。
7.格式化HDFS(在drguo1上执行)
[plain] view plain copy
  1. guo@drguo1:/opt$ hdfs namenode -format  
这回又出问题了,还是汉语注释闹得,drguo1/2/3也全删了,问题解决。
注意:格式化之后需要把tmp目录拷给drguo2(不然drguo2的namenode起不来)
[plain] view plain copy
  1. guo@drguo1:/opt/Hadoop/hadoop-2.7.2$ scp -r tmp/ drguo2:/opt/Hadoop/hadoop-2.7.2/  
8.格式化ZKFC(在drguo1上执行)
[plain] view plain copy
  1. guo@drguo1:/opt$ hdfs zkfc -formatZK  
9.启动HDFS(在drguo1上执行)
[plain] view plain copy
  1. guo@drguo1:/opt$ start-dfs.sh   
10.启动YARN(在drguo1上执行)
[plain] view plain copy
  1. guo@drguo1:/opt$ start-yarn.sh   
PS:
1.drguo2的resourcemanager需要手动单独启动:
yarn-daemon.sh start resourcemanager
2.namenode、datanode也可以单独启动:
hadoop-daemon.sh start namenode
hadoop-daemon.sh start datanode
3.NN 由standby转化成active
hdfs haadmin -transitionToActive nn1 --forcemanual
大功告成!!!


原创粉丝点击