ZooKeeper安装

安装前准备

安装JDK

拷贝apache-zookeeper-3.7.1-bin.tar.gz安装包到Linux系统下

解压到指定目录

1
[Moss@hadoop51 software]$ tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /opt/module/

修改名称

1
[Moss@hadoop51 module]$ mv apache-zookeeper-3.7.1-bin zookeeper-3.7.1 

配置修改

将/opt/module/zookeeper-3.7.1/conf这个路径下的zoo_sample.cfg修改为zoo.cfg

1
[Moss@hadoop51 conf]$ mv zoo_sample.cfg zoo.cfg

打开zoo.cfg文件,修改dataDir路径:

1
[Moss@hadoop51 zookeeper-3.7.1]$ vim zoo.cfg

修改如下内容:

1
dataDir=/opt/module/zookeeper-3.7.1/zkData

在/opt/module/zookeeper-3.7.1/这个目录上创建zkData文件夹

1
[Moss@hadoop51 zookeeper-3.7.1]$ mkdir zkData

配置服务器编号

在/opt/module/zookeeper-3.7.1/zkData目录下创建一个myid的文件

1
[Moss@hadoop51 zkData]$ vi myid

在文件中添加与server对应的编号(注意:上下不要有空行,左右不要有空格)。

1
2
3
4
1
~
~
~

拷贝配置好的zookeeper到其他机器上

1
[Moss@hadoop51 module ]$ my_sync.sh zookeeper-3.7.1

并分别在hadoop52、hadoop53上修改myid文件中内容为2、3

配置zoo.cfg文件

打开zoo.cfg文件

1
2
3
4
5
6
7
8
[atguigu@hadoop102 conf]$ vim zoo.cfg
#修改数据存储路径配置
dataDir=/opt/module/zookeeper-3.7.1/zkData
#增加如下配置
#######################cluster##########################
server.1=hadoop51:2888:3888
server.2=hadoop52:2888:3888
server.3=hadoop53:2888:3888

配置参数解读

1
2
3
4
5
6
server.A=B:C:D
A是一个数字,表示这个是第几号服务器;
集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,ZooKeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
B是这个服务器的地址;
C是这个服务器Follower与集群中的Leader服务器交换信息的端口;
D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

同步zoo.cfg配置文件

1
[Moss@hadoop51 conf]$ my_sync.sh zoo.cfg

集群操作

分别启动ZooKeeper

1
2
3
[Moss@hadoop51 zookeeper-3.7.1]$ bin/zkServer.sh start
[Moss@hadoop52 zookeeper-3.7.1]$ bin/zkServer.sh start
[Moss@hadoop53 zookeeper-3.7.1]$ bin/zkServer.sh start

ZK集群启动停止脚本

在hadoop51的/home/Moss/bin目录下创建脚本

1
[Moss@hadoop51 bin]$ vim zk.sh

在脚本中编写如下内容

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
#!/bin/bash

case $1 in
"start"){
for i in hadoop51 hadoop52 hadoop53
do
echo ---------- zookeeper $i 启动 ------------
ssh $i "/opt/module/zookeeper-3.7.1/bin/zkServer.sh start"
done
};;
"stop"){
for i in hadoop51 hadoop52 hadoop53
do
echo ---------- zookeeper $i 停止 ------------
ssh $i "/opt/module/zookeeper-3.7.1/bin/zkServer.sh stop"
done
};;
"status"){
for i in hadoop51 hadoop52 hadoop53
do
echo ---------- zookeeper $i 状态 ------------
ssh $i "/opt/module/zookeeper-3.7.1/bin/zkServer.sh status"
done
};;
esac

增加脚本执行权限

1
[Moss@hadoop51 bin]$ chmod u+x zk.sh

ZooKeeper集群启动脚本

1
[Moss@hadoop51 module]$ zk.sh start

ZooKeeper集群停止脚本

1
[Moss@hadoop51 module]$ zk.sh stop

Hadoop HA 高可用

HDFS-HA搭建

配置core-site.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<configuration>
<!-- 把多个NameNode的地址组装成一个集群mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/ha/hadoop-3.3.4/data</value>
</property>
<!-- 指定zkfc要连接的zkServer地址 -->
<property>
<name>ha.zookeeper.quorum</name> <value>hadoop51:2181,hadoop52:2181,hadoop53: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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<configuration>

<!-- NameNode数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/name</value>
</property>

<!-- DataNode数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/data</value>
</property>

<!-- JournalNode数据存储目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jn</value>
</property>

<!-- 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>

<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2,nn3</value>
</property>

<!-- NameNode的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>hadoop51:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>hadoop52:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn3</name>
<value>hadoop53:8020</value>
</property>

<!-- NameNode的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>hadoop51:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>hadoop52:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn3</name>
<value>hadoop53:9870</value>
</property>

<!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://hadoop51:8485;hadoop52:8485;hadoop53:8485/mycluster</value>
</property>

<!-- 访问代理类:client用于确定哪个NameNode为Active -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>

<!-- 使用隔离机制时需要ssh秘钥登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/Moss/.ssh/id_rsa</value>
</property>
<!-- 启用nn故障自动转移 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>

同步更新其他节点的配置信息,分发配置文件

1
[Moss@hadoop51 opt]$ my_sync.sh ha/

启动HDFS-HA集群

在各个JournalNode节点上,输入以下命令启动journalnode服务

1
2
3
[Moss@hadoop51 ~]$ hdfs --daemon start journalnode
[Moss@hadoop52 ~]$ hdfs --daemon start journalnode
[Moss@hadoop53 ~]$ hdfs --daemon start journalnode

在[nn1]上,对其进行格式化,并启动

1
2
[Moss@hadoop51 ~]$ hdfs namenode -format
[Moss@hadoop51 ~]$ hdfs --daemon start namenode

在[nn2]和[nn3]上,同步nn1的元数据信息

1
2
[Moss@hadoop52 ~]$ hdfs namenode -bootstrapStandby
[Moss@hadoop53 ~]$ hdfs namenode -bootstrapStandby

启动[nn2]和[nn3]

1
2
[Moss@hadoop52 ~]$ hdfs --daemon start namenode
[Moss@hadoop53 ~]$ hdfs --daemon start namenode

在所有节点上,启动datanode

1
2
3
[Moss@hadoop51 ~]$ hdfs --daemon start datanode
[Moss@hadoop52 ~]$ hdfs --daemon start datanode
[Moss@hadoop53 ~]$ hdfs --daemon start datanode

格式化zkfc

1
[Moss@hadoop51 ~]$ hdfs zkfc -formatZK

在所有nn节点启动zkfc

1
2
3
[Moss@hadoop51 ~]$ hdfs --daemon start zkfc
[Moss@hadoop52 ~]$ hdfs --daemon start zkfc
[Moss@hadoop53 ~]$ hdfs --daemon start zkfc

第二次启动可以通过脚本启动和关闭集群

1
2
[Moss@hadoop51 ~]$ start-dfs.sh
[Moss@hadoop51 ~]$ stop-dfs.sh

YARN-HA配置

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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>

<!-- 启用resourcemanager ha -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>

<!-- 声明两台resourcemanager的地址 -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster-yarn1</value>
</property>

<!--指定resourcemanager的逻辑列表-->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2,rm3</value>
</property>
<!-- ========== rm1的配置 ========== -->
<!-- 指定rm1的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>hadoop51</value>
</property>

<!-- 指定rm1的web端地址 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>hadoop51:8088</value>
</property>

<!-- 指定rm1的内部通信地址 -->
<property>
<name>yarn.resourcemanager.address.rm1</name>
<value>hadoop51:8032</value>
</property>

<!-- 指定AM向rm1申请资源的地址 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm1</name>
<value>hadoop51:8030</value>
</property>

<!-- 指定供NM连接的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm1</name>
<value>hadoop51:8031</value>
</property>

<!-- ========== rm2的配置 ========== -->
<!-- 指定rm2的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>hadoop52</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>hadoop52:8088</value>
</property>
<property>
<name>yarn.resourcemanager.address.rm2</name>
<value>hadoop52:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address.rm2</name>
<value>hadoop52:8030</value>
</property>

<property>
<name>yarn.resourcemanager.resource-tracker.address.rm2</name>
<value>hadoop52:8031</value>
</property>

<!-- ========== rm3的配置 ========== -->
<!-- 指定rm1的主机名 -->
<property>
<name>yarn.resourcemanager.hostname.rm3</name>
<value>hadoop53</value>
</property>
<!-- 指定rm1的web端地址 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm3</name>
<value>hadoop53:8088</value>
</property>
<!-- 指定rm1的内部通信地址 -->
<property>
<name>yarn.resourcemanager.address.rm3</name>
<value>hadoop53:8032</value>
</property>
<!-- 指定AM向rm1申请资源的地址 -->
<property>
<name>yarn.resourcemanager.scheduler.address.rm3</name>
<value>hadoop53:8030</value>
</property>
<!-- 指定供NM连接的地址 -->
<property>
<name>yarn.resourcemanager.resource-tracker.address.rm3</name>
<value>hadoop53:8031</value>
</property>
<!-- 指定zookeeper集群的地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>hadoop51:2181,hadoop52:2181,hadoop53:2181</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>
<!-- 环境变量的继承 -->
<property>
<name>yarn.nodemanager.env-whitelist</name>
<value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
</property>
</configuration>

同步更新其他节点的配置信息,分发配置文件

1
[Moss@hadoop51 conf]$ my_sync.sh yarn-site.xml

启动YARN

1
[Moss@hadoop51 ~]$ start-yarn.sh

查看服务状态

1
2
3
[Moss@hadoop51 ~]$ yarn rmadmin -getServiceState rm1
[Moss@hadoop51 ~]$ yarn rmadmin -getServiceState rm2
[Moss@hadoop51 ~]$ yarn rmadmin -getServiceState rm3