HA:High Available,高可用。为什么需要HA机制?怎么配置HA?
为什么会有Hadoop HA机制
在HDFS集群中NameNode会存在单点故障(SPOF:A Single Point of Failure)问题:对于只有一个NameNode的集群,如果唯一的NameNode机器出现故障,比如宕机、软件硬件升级等。那么整个集群将无法使用,直到NameNode重新启动才会恢复。
所以在hadoop2.0之前,出现这种单节点故障问题是无法解决的;但是Hadoop HA机制的出现就很好的解决了这个问题,在一个典型的Hadoop HA集群中,使用两台单独的机器配置为NameNodes节点。在任何时间点,确保NameNodes中只有一个处于Active状态,另一个处在Standby状态。其中ActiveNameNode负责集群中所有的客户端的操作,StandbyNameNode仅仅充当备机,保证一旦ActiveNameNode出现问题能够快速切换。
准备两台NameNode解决单节点故障问题是完全可行,但是又出现一个问题:Active和Standby两个 NameNodes的元数据信息(editlog)如何同步才能让Standby节点切换后”无缝对接工作”?那么就需要一个共享存储系统,这个系统就是Zookeeper,Active NameNode会将数据写入共享存储系统,而Standby便可以快速切为Active NameNode接替其工作。为了实现这一目标,DataNode需要配置NameNodes的位置,并同时给他们发送文件块信息以及心跳检测。
集群规划和准备
基于Hadoop集群环境搭建的准备条件,集群规划:
| hadoop02 | hadoop03 | hadoop04 | hadoop05 |
---|
namenode | ✔ | ✔ | | |
datanode | ✔ | ✔ | ✔ | ✔ |
resourcemanager | | | ✔ | ✔ |
nodemanager | ✔ | ✔ | ✔ | ✔ |
zookeeper | ✔ | ✔ | ✔ | |
journalnode | ✔ | ✔ | ✔ | |
zkfc | ✔ | ✔ | | |
集群配置
hadoop-env.sh
1
| export JAVA_HOME= /usr/local/jdk1.8.0_73
|
core-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <configuration>
<property> <name>fs.defaultFS</name> <value>hdfs://myha01/</value> </property>
<property> <name>hadoop.tmp.dir</name> <value>/home/hadoop/data/hadoopdata/</value> </property>
<property> <name>ha.zookeeper.quorum</name> <value>hadoop02:2181,hadoop03:2181,hadoop04:2181</value> </property> </configuration>
|
hdfs-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| <configuration>
<property> <name>dfs.replication</name> <value>2</value> </property>
<property> <name>dfs.nameservices</name> <value>myha01</value> </property>
<property> <name>dfs.ha.namenodes.myha01</name> <value>nn1,nn2</value> </property>
<property> <name>dfs.namenode.rpc-address.myha01.nn1</name> <value>hadoop02:9000</value> </property>
<property> <name>dfs.namenode.http-address.myha01.nn1</name> <value>hadoop02:50070</value> </property>
<property> <name>dfs.namenode.rpc-address.myha01.nn2</name> <value>hadoop03:9000</value> </property>
<property> <name>dfs.namenode.http-address.myha01.nn2</name> <value>hadoop03:50070</value> </property>
<property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop02:8485;hadoop03:8485;hadoop04:8485/myha01</value> </property>
<property> <name>dfs.journalnode.edits.dir</name> <value>/home/hadoop/data/journaldata</value> </property>
<property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
<property> <name>dfs.client.failover.proxy.provider.myha01</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property>
<property> <name>dfs.ha.fencing.methods</name> <value> sshfence 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>30000</value> </property> </configuration>
|
mapred-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <configuration>
<property> <name>mapreduce.framework.name</name> <value>yarn</value> </property>
<property> <name>mapreduce.jobhistory.address</name> <value>hadoop02:10020</value> </property>
<property> <name>mapreduce.jobhistory.webapp.address</name> <value>hadoop02:19888</value> </property> </configuration>
|
yarn-site.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| <configuration>
<property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property>
<property> <name>yarn.resourcemanager.cluster-id</name> <value>yrc</value> </property>
<property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property>
<property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoop04</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoop05</value> </property>
<property> <name>yarn.resourcemanager.zk-address</name> <value>hadoop02:2181,hadoop03:2181,hadoop04:2181</value> </property>
<property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
<property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property>
<property> <name>yarn.log-aggregation.retain-seconds</name> <value>86400</value> </property>
<property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property>
<property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> </configuration>
|
slaves
1 2 3 4
| hadoop02 hadoop03 hadoop04 hadoop05
|
配置环境变量和分发安装包
1 2 3 4 5 6 7 8 9 10
| vim ~/.bashrc #如果没找到,先执行 ll -a ~/ 添加两行: export HADOOP_HOME=/home/hadoop/apps/hadoop-2.7.5 export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
分发安装包和环境变量: scp -r ~/apps/hadoop-2.7.5 hadoop@hadoop03:~/apps/ ... scp ~/.bashrc hadoop@hadoop03:~/ ...
|
集群初始化和启动
HA集群的启动是有一定的顺序的,第一次启动严格按照以下步骤:
启动zookeeper集群
配置zookeeper集群的节点都需要启动
启动命令:zkServer.sh start
查看状态:zkServer.sh status
启动journalnode进程:
配置journalnode集群的节点都需要启动
启动命令:hadoop-daemon.sh start journalnode
格式化NameNode:
在hadoop02主节点上格式化操作
命令:hadoop namenode -format
在~/data/hadoopdata/
中会生成集群信息,把hadoopdata文件发送到hadoop03上
scp -r ~/data/hadoopdata/ hadoop@hadoop03:~/data/
格式化ZKFC
在第一台机器上操作即可
命令:hdfs zkfc -formatZK
启动HDFS和YARN集群
命令:start-dfs.sh
start-yarn.sh
查看进程情况
命令:jps
验证和测试
验证
访问HDFSWeb页面:http://hadoop02:50070
、http://hadoop03:50070
hadoop02是Actice状态,hadoop03是standby状态
访问YARNweb页面:http://hadoop04:8088
、http://hadoop05:8088
访问hadoop05 是 standby resourcemanager,会自动跳转到 hadoop04
测试
干掉active namenode的进程,看看集群变化
在上传文件的时候干掉 active namenode, 看看集群有什么变化
干掉 active resourcemanager, 看看集群有什么变化
在执行任务的时候干掉 active resourcemanager,看看集群有什么变化