Hadoop HA集群搭建

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集群环境搭建的准备条件,集群规划:

hadoop02hadoop03hadoop04hadoop05
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>
<!-- 指定 hdfs 的 nameservice 为 myha01 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://myha01/</value>
</property>
<!-- 指定 hadoop 工作目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/data/hadoopdata/</value>
</property>
<!-- 指定 zookeeper 集群访问地址 -->
<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>
<!--指定 hdfs 的 nameservice 为 myha01,需要和 core-site.xml 中保持一致-->
<property>
<name>dfs.nameservices</name>
<value>myha01</value>
</property>
<!-- myha01 下面有两个 NameNode,分别是 nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.myha01</name>
<value>nn1,nn2</value>
</property>
<!-- nn1 的 RPC 通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn1</name>
<value>hadoop02:9000</value>
</property>
<!-- nn1 的 http 通信地址 -->
<property>
<name>dfs.namenode.http-address.myha01.nn1</name>
<value>hadoop02:50070</value>
</property>
<!-- nn2 的 RPC 通信地址 -->
<property>
<name>dfs.namenode.rpc-address.myha01.nn2</name>
<value>hadoop03:9000</value>
</property>
<!-- nn2 的 http 通信地址 -->
<property>
<name>dfs.namenode.http-address.myha01.nn2</name>
<value>hadoop03:50070</value>
</property>
<!-- 指定 NameNode 的 edits 元数据在 JournalNode 上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop02:8485;hadoop03:8485;hadoop04:8485/myha01</value>
</property>
<!-- 指定 JournalNode 在本地磁盘存放数据的位置 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/hadoop/data/journaldata</value>
</property>
<!-- 开启 NameNode 失败自动切换 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置失败自动切换实现方式 value值不要换行-->
<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>
<!-- 使用 sshfence 隔离机制时需要 ssh 免登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- 配置 sshfence 隔离机制超时时间 -->
<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>
<!-- 指定 mr 框架为 yarn 方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<!-- 设置 mapreduce 的历史服务器地址和端口号 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>hadoop02:10020</value>
</property>
<!-- mapreduce 历史服务器的 web 访问地址 -->
<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>
<!-- 开启 RM 高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<!-- 指定 RM 的 cluster id -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</value>
</property>
<!-- 指定 RM 的名字 -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<!-- 分别指定 RM 的地址 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop04</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop05</value>
</property>
<!-- 指定 zk 集群地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop02:2181,hadoop03:2181,hadoop04:2181</value>
</property>
<!-- 要运行 MapReduce 程序必须配置的附属服务 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 开启 YARN 集群的日志聚合功能 -->
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
<!-- YARN 集群的聚合日志最长保留时长 -->
<property>
<name>yarn.log-aggregation.retain-seconds</name>
<value>86400</value>
</property>
<!-- 启用自动恢复 -->
<property>
<name>yarn.resourcemanager.recovery.enabled</name>
<value>true</value>
</property>
<!-- 制定 resourcemanager 的状态信息存储在 zookeeper 集群上-->
<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:50070http://hadoop03:50070

hadoop02是Actice状态,hadoop03是standby状态

访问YARNweb页面:http://hadoop04:8088http://hadoop05:8088

访问hadoop05 是 standby resourcemanager,会自动跳转到 hadoop04

测试

干掉active namenode的进程,看看集群变化

在上传文件的时候干掉 active namenode, 看看集群有什么变化

干掉 active resourcemanager, 看看集群有什么变化

在执行任务的时候干掉 active resourcemanager,看看集群有什么变化