前提:
- 该环境是在上一节全分布式
hadoop
安装的方式基础上进行安装的。 Hadoop3 全分布式安装- 还需在
node02
,node03
,node04
上面安装好zookeeper
集群安装ZooKeeper
搭建环境的角色分配
节点服务器 | NameNode01 | NameNode02 | DataNode | ZooKeeper | ZKFS | JournalNode |
---|---|---|---|---|---|---|
node01 | √ | √ | √ | |||
node02 | √ | √ | √ | √ | √ | |
node03 | √ | √ | √ | |||
node04 | √ | √ |
- Zookeeper :作分布式协调系统,独立于其他集群之外,单独部署,搭建的分布式架构。
- ZKFC :必须与
NameNode
放在一起,避免网络传输波动,造成渐冲检查的不及时,切换的不及时,每一个主节点都有一个ZKFC
物理进程来监控。 - JournalNode :共享两台服务器之间
NameNode
数据进行透穿,存储编辑日志信息,以集群的方式存在。node01
节点作为active
节点,把信息写入JNN
集群中,node02
下载同步相同的信息,从而达到两个节点namenode
信息同步的目的。
一. 备份配置文件
将之前搭建的全分布式安装的配置文件复制一份,以为了以后有需要直接修改配置文件的名称,重新启动。
cp -r /opt/hadoop-3.1.2/etc/hadoop /opt/hadoop-3.1.2/etc/hadoop-full
二. 修改hadoop.env
文件
- 将
HDFS_SECONDARYNAMENODE_USER
用户注释掉。# export HDFS_SECONDARYNAMENODE_USER=root
- 增加角色配置
export HDFS_ZKFC_USER=root export HDFS_JOURNALNODE_USER=root
- 最终的效果展示
三. 修改core-site.xml
文件
- 修改文件目录
<property> <name>hadoop.tmp.dir</name> <value>/var/hadoop/ha</value> </property>
- 增加
staticuser
hadoop.http.staticuser.user
——在网页界面访问数据使用的用户名。 默认值是一个不真实存在的用户,此用户权限很小,不能访问不同用户的数据。这保证了数据安全。也可以设置为hdfs和hadoop等具有较高权限的用户,但会导致能够登陆网页界面的人能看到其它用户数据。实际设置请综合考虑。如无特殊需求。使用默认值就好<property> <name>hadoop.http.staticuser.user</name> <value>root</value> </property>
四. 修改hdfs-site.xml
文件
-
删除
SecondAryNamenNode
节点
将全分布式Hadoop集群中的SecondAryNamenNode
节点删除掉。 -
添加
fds.nameservices -- the logical name for this new nameservice
主节点的服务名称
<property> <name>dfs.nameservices</name> <value>mycluster</value> </property>
-
添加
dfs.ha.namenodes.[nameservice ID] - unique identifiers for each NameNode in the nameservice
包含一个
NN
列表。nameservice ID
是指具体的nameservice
名称,通常就是dfs.nameservices
中配置的。值是预备配置的NN
的ID
。
ID
是自己取的,不重复就可以,例如nn1,nn2
<property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property>
-
添加
dfs.namenode.rpc-address.[nameservice ID].[name node ID] - the fully-qualified RPC address for each NameNode to listen on
NN
的RPC
地址和端口,远程服务调用<property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>node01:8020</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>node02:8020</value> </property>
-
添加
dfs.namenode.http-address.[nameservice ID].[name node ID] - the fully-qualified HTTP address for each NameNode to listen on
NN
的HTTP
地址和端口。0表示任意空闲端口。
浏览器与NameNode
进行通信的HTTP
地址<property> <name>dfsi.namenode.http-address.mycluster.nn1</name> <value>node01:9870</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>node02:9870</value> </property>
-
添加
dfs.namenode.shared.edits.dir - the URI which identifies the group of JNs where the NameNodes will write/read edits
在多个
NN
中共享存储目录,用于存放edits
文件。这个目录,由active
写,由standby
读,以保持命名空间数据一致。此目录不需要是dfs.namenode.edits.dir
中列出的。在非HA
集群中,它不会使用。建议使用qj
方式,可以不关注这个选项
对NameNode
的共享路径,JournalNode
配置集群的地址<property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value> </property>
-
添加
dfs.client.failover.proxy.provider.[nameservice ID] - the Java class that HDFS clients use to contact the Active NameNode
HDFS
客户端找到active NameNode
类名的代理类,如果不配置客户端返回activeNameNode
报错,显示无连接地址<property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property>
-
添加
dfs.ha.fencing.methods - a list of scripts or Java classes which will be used to fence the Active NameNode during a failover
HDFS
的HA
功能的防脑裂方法。可以是内建的方法(例如shell
和sshfence
)或者用户定义的方法。建议使用sshfence(hadoop:9922)
,括号内的是用户名和端口,注意,这需要NN
的2台机器之间能够免密码登陆。
fences
是防止脑裂的方法,保证NN
中仅一个是Active
的,如果2者都是Active
的,新的会把旧的强制Kill
。
使用sshfence时,SSH的私钥文件。 使用了sshfence,dfs.ha.fencing.ssh.private-key-files
这个必须指定<property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property>
-
添加
dfs.journalnode.edits.dir - the path where the JournalNode daemon will store its local state
journalnode
集群放置存储同步日志的路径<property> <name>dfs.journalnode.edits.dir</name> <value>/var/hadoop/ha/journalnode</value> </property>
-
添加
The configuration of automatic failover requires the addition of two new parameters to your configuration. In your hdfs-site.xml file
是否开启自动故障转移。建议开启,true
<property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
-
效果展示
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. See accompanying LICENSE file. --> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>node01:8020</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>node02:8020</value> </property> <property> <name>dfsi.namenode.http-address.mycluster.nn1</name> <value>node01:9870</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>node02:9870</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value> </property> <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> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <name>dfs.journalnode.edits.dir</name> <value>/var/hadoop/ha/journalnode</value> </property> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> </configuration>
五. 配置core-site.xml
文件
- 修改
fs.defaultFS
默认文件系统的名称。URI形式。uri’s的scheme需要由(fs.SCHEME.impl)指定文件系统实现类。 uri’s的authority部分用来指定host, port等。默认是本地文件系统。
HA方式,这里设置服务名,例如:hdfs://mycluster1
HDFS的客户端访问HDFS需要此参数。<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property>
- 添加
ZooKeeper
集群Ha功能,需要一组zk地址,用逗号分隔。被ZKFailoverController使用于自动失效备援failover。
<property> <name>ha.zookeeper.quorum</name> <value>node02:2181,node03:2181,node04:2181</value> </property>
core-site.xml
配置文件<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <!-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. See accompanying LICENSE file. --> <!-- Put site-specific property overrides in this file. --> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/var/hadoop/ha</value> </property> <property> <name>hadoop.http.staticuser.user</name> <value>root</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>node02:2181,node03:2181,node04:2181</value> </property> </configuration>
六. 将hadoop
配置文件的文件夹分发到其他节点上
scp core-site.xml hdfs-site.xml hadoop-env.sh node02:`pwd`
scp core-site.xml hdfs-site.xml hadoop-env.sh node03:`pwd`
scp core-site.xml hdfs-site.xml hadoop-env.sh node04:`pwd`
七. 实现两个NameNode
信息同步透穿
在此之前必须现在(node02,node03,node04)节点上安装好
zookeeper
。Zookeeper安装配置文章
-
启动
JournalNode
分别在
node01,node02,node03
上执行启动命令# 启动 hdfs --daemon start journalnode # 停止 hdfs --daemon stop journalnode
-
在
node01
上格式化主节点hdfs namenode -format
成功的标志:
查看此时的集群ID:
-
观察
Zookeeper
客户端是否挂在主节点
Zookeeper
作用:负责记录两个Namenode
做故障转移,会在其中做注册行为
登录到zkServer.sh
,使用ls /
命令,观察到仅有[zk: localhost:2181(CONNECTED) 0] ls / [zookeeper]
-
node02
主节点数据信息同步a. 启动
node01
上面的主节点# 老命令但还支持 hadoop-daemon.sh start namenode # hadoop3.x 建议命令 hdfs --daemon start namenode
b. 在
node02
上面执行数据信息同步命令hdfs namenode -bootstrapStandby
成功标志:
观察集群ID
,与node01
的namenode
集群ID
相同
观察ZooKeeper节点:
八.ZooKeeper
的格式化
前提:
ZooKeeper
集群已经启动起来
本节的命令在node01
上面执行
hdfs zkfc -formatZK
成功标志:
九. 启动Hadoop
集群
在node01
上执行以下命令:
start-dfs.sh
在各个节点使用jps
命令查看正在运行的Java
进程:
在ZooKeeper
客户端中:
多了两个节点,两个节点下面全部为空,使用get
命令,获取注册节点下面的注册信息get /hadoop-ha/mycluster/ActiveBreadCrumb
,发现第一行显示当前哪个主节点处于活跃状态。
通过Web
界面显示,一个节点active
,另一个节点显示standby
十. 测试Hadoop
集群准备主节点之间的切换
-
测试1:将
node01
中的NameNode
干掉,观察node02
节点服务器中的NameNode
是否变为活跃状态
a. 执行命令,停止NameNode
hdfs --daemon stop namenode
可以观察到,在Web
界面中,node01:9870
无法访问,而node02:9870
由standby
转为active
再观察
ZooKeeper
中的节点,活跃节点已经变成了node02
再重新启动起来node01
上面的NameNode
,通过Web
界面显示Node01
上面的NameNode
已经变成了Standby
状态
b. 将DKFC
停止,将node02
中的DKFC
停止,(前提:node02
的NameNode
为active
)hdfs --daemon stop zkfc
此时,
Web
界面显示,node01
的NameNode
为active
,node02
变为standby
通过这些测试证明,当某一个节点宕机,就会被ZooKeeper
发现,它通过事件监控之后,来通知另一个节点作为Standby
提升自己为主节点。
另外一种情况,NameNode
并没有宕机,但是由于网络原因,与ZooKeeper
通信中断,比如ZKFC
进程断了,此时也造成异常,知识ZooKeeper
让然会通知另一个节点,另一个节点会把当前处于异常的节点,强制降级为standby
(使用sshfance
方法),而把自己提升为active
。