Hadoop-HA高可用集群QJM搭建

1.此教程默认已经搭建好完全分布式

2. Zookeeper 集群搭建

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
配置完全分布式zk集群
---------------------
1.挑选3台主机
cs1 ~ cs3
2.每台机器都安装zk
tar
环境变量

3.配置zk配置文件
cs1 ~ cs3
[/home/ap/apps/zk/conf/zoo.cfg]
...
dataDir=/home/ap/zookeeper

4.在每台主机的/home/centos/zookeeper中添加myid,内容分别是1,2,3
[cs1]
$>echo 1 > /home/ap/zookeeper/myid
[cs2]
$>echo 2 > /home/ap/zookeeper/myid
[cs3]
$>echo 3 > /home/ap/zookeeper/myid

5.启动服务器集群
$>zkServer.sh start

6.查看每台服务器的状态
$>zkServer.sh status
* 注意: 如果有3台机器, 只启动一台的话, 会显示如下, 因为根据配置, 有3台机器, 此时只有一台启动, 没有过半数, 整个集群是挂掉的
* 只有启动的机器数量超过配置的半数, zk 集群才有效.

3.HA 集群搭建

首先声明

笔者用的6台主机, 主机名 cs1-cs6, 用户名为ap, 可以对照改为自己的主机名&用户名

另外, 搭建 HA 不会影响原来的完全分布式, 具体操作会在下面告知.
hadoop 安装目录层级结构:

  • /home/ap/apps/hadoop/etc/hadoop/hdfs-site.xml

data 目录层级结构:

  • cs1: /home/ap/hadoopdata/namenode/current/edits_00....
  • cs2: /home/ap/hadoopdata/datanode/current/BP-15...

可以对照参考


集群结构如下

image-20180622004722436


开始搭建

首先保证 各节点直接的 ssh 免密登录没问题

  • 如果非生产环境, 可以同时把 .ssh删掉后, 全部重新生成 ssh-keygen, 同时相互发送, 这样操作最简单, 效率最高.

其次上代码了

  1. 把原本/home/ap/apps/hadoop/etc/hadoop中的 hadoop目录改为full,意思是完全分布式.
  2. cp -r full ha, 复制一份 full 为 ha, 在这份配置文件中配置 HA
  3. ln -s /home/ap/apps/hadoop/etc/ha /home/ap/apps/hadoop/etc/hadoop, 用一个软链接hadoop 指向 ha
  4. 配置 /home/ap/apps/hadoop/etc/ha/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
[hdfs-site.xml]
------------------------------------------------------------------
<configuration>

<!-- 指定 2个 namenode 的命名空间 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>

<!-- myucluster下的名称节点两个id -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>

<!-- 配置每个nn的rpc地址。 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>cs1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>cs6:8020</value>
</property>

<!-- 配置webui端口 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>cs1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>cs6:50070</value>
</property>

<!-- 名称节点共享编辑目录. -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://cs2:8485;cs3:8485;cs4:8485/mycluster</value>
</property>

<!-- java类,client使用它判断哪个节点是激活态。 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

<!-- 脚本列表或者java类,在容灾保护激活态的nn. -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>
sshfence
shell(/bin/true)
</value>
</property>

<!-- ssh免密登陆 -->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/ap/.ssh/id_rsa</value>
</property>

<!-- 配置 sshfence 隔离机制超时时间(可不配) -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>

<!-- 配置JN存放edit的本地路径。 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/home/ap/hadoopdata/journal</value>
</property>

</configuration>
  1. 配置 core-site.xml, 这里给出完整配置 (目前不包括 Hive 配置)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[core-site.xml]
------------------------------------------------------------
<configuration>

<!-- 指定 hdfs 的 nameservice 为 mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>

<!-- 指定 hadoop 工作目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/home/ap/hadoopdata</value>
</property>

<!-- 指定zk集群访问地址 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>

</configuration>
  1. 配置mapred-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
[mapred-site.xml]
-------------------
<configuration>

<!-- 指定 mr 框架为 yarn 方式 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>

<!-- 设置 mapreduce 的历史服务器地址和端口号 -->
<property>
<name>mapreduce.jobhistory.address</name>
<value>cs1:10020</value>
</property>

<!-- mapreduce 历史服务器的 web 访问地址 -->
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>cs1:19888</value>
</property>

</configuration>
  1. /home/ap/apps/hadoop/etc/*发给其他所有节点 2-6
    • 注意: 软链接scp 的时候会有问题, 最终保证每个节点跟 cs1一样就可以了,可以每个节点单独修改, 也可以写脚本一起修改
    • ln -sfT /home/ap/apps/hadoop/etc/ha /home/ap/apps/hadoop/etc/hadoop
  2. 部署细节
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
0.在 zk 节点启动 zkServer
cs1-cs3: $>zkServer.sh start

1.在jn节点分别启动jn进程
$>hadoop-daemon.sh start journalnode

2.启动jn之后,在两个NN之间进行disk元数据同步
a)如果是全新集群,先format文件系统,只需要在一个nn上执行。
[cs1]
$>hadoop namenode -format

b)如果将非HA集群转换成HA集群,复制原NN的metadata到另一个nn.
1.步骤一
[cs1]
$>scp -r /home/centos/hadoop/dfs ap@cs6:/home/centos/hadoop/

2.步骤二
在新的nn(未格式化的nn)上运行一下命令,实现待命状态引导。
[cs6]
$>hdfs namenode -bootstrapStandby //需要cs1为启动状态,提示是否格式化,选择N.

3.在一个NN上执行以下命令,完成edit日志到jn节点的传输。
$>hdfs namenode -initializeSharedEdits
#查看cs2,cs3,cs4 这几个 jn 节点是否有edit数据.

4.启动所有节点.
[cs1]
$>hadoop-daemon.sh start namenode //启动名称节点
$>hadoop-daemons.sh start datanode //启动所有数据节点

[2,3,4]
$>hadoop-daemon.sh start journalnode

[cs6]
$>hadoop-daemon.sh start namenode //启动名称节点
  1. HA 管理
1
2
3
4
5
6
7
8
9
10
# 查看web 界面, 是否是2个 standby 状态
http://cs1:50070/
http://cs6:50070/

hdfs haadmin : 查看 ha 帮助
-----------------
$>hdfs haadmin -transitionToActive nn1 //切成激活态
$>hdfs haadmin -transitionToStandby nn1 //切成待命态
$>hdfs haadmin -transitionToActive --forceactive nn2//强行激活
$>hdfs haadmin -failover nn1 nn2 //模拟容灾演示,从nn1切换到nn2
  1. 加入 Zookeeper 容灾服务 zkfc
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
<!-- 1.部署容灾 -->
------------------------------
a.停止所有进程
$>stop-all.sh

b.配置hdfs-site.xml,启用自动容灾.
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>

c.配置core-site.xml,指定zk的连接地址.
<property>
<name>ha.zookeeper.quorum</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>

d.分发以上两个文件到所有节点。


<!-- 2.登录其中的一台NN(s201),在ZK中初始化HA状态,
创建 namenode 的 命名空间节点 mycluster -->
------------------------------------
$>hdfs zkfc -formatZK


<!-- 3.启动hdfs进程. -->
$>start-dfs.sh

<!-- 4.查看 webUI, 是否有一台自动切换为 active 状态了 -->
http://cs1:50070/
http://cs6:50070/

<!-- 5.测试自动容灾(如果cs6是活跃节点) -->
$>kill -9 cs6的 namenode进程号
观察 cs1:50070的状态变化
  1. 配置RM的HA自动容灾
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
1.配置yarn-site.xml

<configuration>
<!-- 是否允许高可用 -->
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>

<!-- Identifies the cluster. Used by the elector to ensure an RM doesn’t take over as Active for another cluster. -->
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>cluster1</value>
</property>

<!-- RM 的 id -->
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>

<!-- 2台 RM 的宿主 -->
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>cs1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>cs6</value>
</property>

<!-- 配置web界面 -->
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>cs1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>cs6:8088</value>
</property>

<!-- zookeeper 地址 -->
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>cs1:2181,cs2:2181,cs3:2181</value>
</property>

<!-- YARN 集群为 MapReduce 程序提供的 shuffle 服务(原本的) -->
<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>
------------------------------------------------------------------


2.使用管理命令
<!-- 查看状态 -->
$>yarn rmadmin -getServiceState rm1
<!-- 切换状态到standby -->
$>yarn rmadmin -transitionToStandby rm1

3.启动yarn集群
$>start-yarn.sh

4.hadoop没有启动两个resourcemanager,需要手动启动另外一个
$>yarn-daemon.sh start resourcemanager

5.查看webUI, 点击 About, 查看 active 或 standby
http://cs1:8088
http://cs6:8088

6.做容灾模拟.
kill -9 活跃的 RM 端口号

7.注意: 如果容灾失败, 检查下每台主机时间是否同步
$>sudo ntpdate ntp1.aliyun.com

至此, 大功告成


4.HA 集群的启动/关闭

4.1 HA 的启动

一:单点启动

  1. 启动 zk 服务 QuorumPeerMain, 否则后面 RM 会起不来,连不上 ZK 服务
    cs1-cs3: $> zkServer.sh start

  2. 启动 namenode/datanode
    cs1,cs6: $> hadoop-daemon.sh start namenode
    cs1/cs6: $> hadoop-daemons.sh start datanode
    cs6: $> hadoop-daemon.sh start namenode

  1. 启动 journalnode
    cs2-cs4: $> hadoop-daemon.sh start journalnode
  1. 启动RM (RM 会自动选出一个 active)
    cs1,cs6: $> yarn-daemon.sh start resourcemanager
    cs1/cs6: $> yarn-daemons.sh start nodemanager
  1. 启动 zk 的 DFSZKFailoverController
    cs1,cs6: $> hadoop-daemon.sh start zkfc

  2. 此外可以启动MapReduce 的历史任务服务器

    [ap@cs1]$> mr-jobhistory-daemon.sh start historyserver

    然后访问配置的 http://cs1:19888/jobhistory

二:懒汉启动

  1. 启动 zk 服务 QuorumPeerMain, 否则后面 RM 会起不来,连不上 ZK 服务
    cs1-cs3: $> zkServer.sh start

  2. 执行启动全部

    cs1: $> start-all.sh(RM 节点)

    或者, 使用新的启动方式

    cs1: $> start-dfs.sh(任意节点)

    cs1: $> start-yarn.sh(在 RM 节点)

  3. 另一个 RM 节点不会自己启动,要手动启动

    cs6: $> yarn-daemon.sh start resourcemanager

三: 启动完成后

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
============= cs1 jps =============
5696 QuorumPeerMain
6641 DFSZKFailoverController
6338 NameNode
6756 ResourceManager
6873 Jps
============= cs2 jps =============
10849 Jps
10722 NodeManager
10631 JournalNode
10541 DataNode
127934 QuorumPeerMain
============= cs3 jps =============
630 NodeManager
758 Jps
535 JournalNode
443 DataNode
117503 QuorumPeerMain
============= cs4 jps =============
79589 Jps
79462 NodeManager
79368 JournalNode
79278 DataNode
============= cs5 jps =============
23655 Jps
23529 NodeManager
23423 DataNode
============= cs6 jps =============
35680 Jps
35506 NameNode
35608 DFSZKFailoverController
21455 ResourceManager

4.2 HA 的关闭

在 一台NN 上stop-all.sh, 注意 zk 的 server- QuorumPeerMain不会停掉

5. 在集群实现时间同步(root 用户操作)

思路:

时间同步的方式:找一个机器,作为时间服务器,所有的机器与这台集群时间进行定时的同步,比如,每隔十分钟,同步一次时间。

5.1 在cs1上修改ntp服务

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
1) 检查 ntp 是否安装
#root> rpm -qa|grep ntp
---
ntp-4.2.6p5-10.el6.centos.x86_64
fontpackages-filesystem-1.41-1.1.el6.noarch
ntpdate-4.2.6p5-10.el6.centos.x86_64
# 出现上面的3个文件, 就是安装了; 如果没有的话, 用 yum 装一下
# root> yum inatall -y ntp

2) 修改 ntp 配置文件
#root> vi /etc/ntp.conf

修改内容如下
a)修改1(设置本地网络上的主机不受限制。)
#restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap

restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
b)修改2(设置为不采用公共的服务器)
server 0.centos.pool.ntp.org iburst
server 1.centos.pool.ntp.org iburst
server 2.centos.pool.ntp.org iburst
server 3.centos.pool.ntp.org iburst

#server 0.centos.pool.ntp.org iburst
#server 1.centos.pool.ntp.org iburst
#server 2.centos.pool.ntp.org iburst
#server 3.centos.pool.ntp.org iburst
c)添加3(添加默认的一个内部时钟数据,使用它为局域网用户提供服务。)
server 127.127.1.0
fudge 127.127.1.0 stratum 10

3)修改/etc/sysconfig/ntpd 文件
#root> vim /etc/sysconfig/ntpd
增加内容如下(让硬件时间与系统时间一起同步)
SYNC_HWCLOCK=yes

4)重新启动ntpd
#root> service ntpd status
ntpd 已停

#root> service ntpd start
正在启动 ntpd:

5) 执行开机启动 ntpd 服务
#root> chkconfig ntpd on
查看 ntpd 服务开机启动的状态
#root> chkconfig --list ntpd

5.2 其它机器上

1
2
3
4
5
6
7
8
9
1)在其他所有机器配置10分钟与时间服务器同步一次
#编写定时任务脚本
#root> crontab -e
*/10 * * * * /usr/sbin/ntpdate hadoop102

2) 修改任意机器时间
#root> date -s "2017-9-11 11:11:11"

3) 十分钟后查看机器时间是否与cs1 同步
如果帮到你, 可以给我赞助杯咖啡☕️
0%