目录
2.2.1 复制出一个zoo.cfg文件(有一个样本 zoo_sample.cfg)
2.4.3 在$ZK_HOME/zkData/目录下添加myid文件,内容为server的id号
4.1 HA(high availability)的使用原因
4.3.4 datanode同时向两个namenode心跳反馈
一.Zookeeper的概述
1.1 Zookeeper是什么
1. zookeeper是一个为分布式应用程序提供的一个分布式开源协调服务框架。是Google的Chubby的一个开源实现,是Hadoop和Hbase的重要组件。主要用于解决分布式集群中应用系统的一致性问题。
2. 提供了基于类似Unix系统的目录节点树方式的数据存储。
3. 可用于维护和监控存储的数据的状态的变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理
4. 提供了一组原语(机器指令),提供了java和c语言的接口
1.2 Zookeeper的特点
1. 也是一个分布式集群,一个领导者(leader),多个跟随者(follower).
2. 集群中只要有半数以上的节点存活,Zookeeper集群就能正常服务。
3. 全局数据一致性:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的。
4. 更新请求按顺序进行:来自同一个client的更新请求按其发送顺序依次执行
5. 数据更新的原子性:一次数据的更新要么成功,要么失败
6. 数据的实时性:在一定时间范围内,client能读到最新数据。
1.3 Zookeeper的数据模型
Zookeeper的数据模型采用的与Unix文件系统类似的层次化的树形结构。我们可以将其理解为一个具有高可用特征的文件系统。这个文件系统中没有文件和目录,而是统一使用"节点"(node)的概念,称之为znode。znode既可以作为保存数据的容器(如同文件),也可以作为保存其他znode的容器(如同目录)。所有的znode构成了一个层次化的命名空间。
- Zookeeper 被设计用来实现协调服务(这类服务通常使用小数据文件),而不是用于大容量数据存储,因此一个znode能存储的数据被限制在1MB以内,
- 每个znode都可以通过其路径唯一标识。
1.4 Zookeeper的应用场景
1. 统一配置管理
2. 集群管理(比如HA)
3. 服务器节点动态上下线感知
4. 软负载均衡等
5. 分布式锁
6. 分布式队列
二.Zookeeper的安装
2.1 环境变量的配置
1. 将zookeeper-3.4.10.tar.gz上传到/root中
2. 解压
[root@xxx01 ~]# tar -zxvf zookeeper-3.4.10.tar.gz -C /usr/local/
3. 更名zookeeper
[root@xxx01 ~]# cd /usr/local/
[root@xxx01 local]# mv zookeeper-3.4.10 zookeeper
4. 配置环境变量
[root@xxx01 local]# vi /etc/profile
.........省略......
export ZOOKEEPER_HOME=/usr/local/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH
5. 使当前会话生效
[root@xxx01 local]# source /etc/profile
6. 检查如下:
如果只检查环境变量是否配置成功,只需要使用tab键进行补全zk,是否zookeeper的相关脚本提示即可。
注意:第七步,只能是
7. 查看zookeeper的版本号
[root@xxx01 local]# echo stat|nc localhost 2181
2.2 独立模式的安装
2.2.1 复制出一个zoo.cfg文件(有一个样本 zoo_sample.cfg)
[root@xxx01 local]# cd zookeeper/
[root@xxx01 zookeeper]# cd conf/ #进入zookeeper的conf目录
[root@xxx01 conf]# cp zoo_sample.cfg zoo.cfg #复制出zoo.cfg文件
2.2.2 修改zoo.cfg文件
[root@xxx01 conf]# vi zoo.cfg
# 定义的时间单元(单位毫秒),下面的两个值都是tickTime的倍数。
tickTime=2000
# follower连接并同步leader的初始化连接时间。
initLimit=10
# 心跳机制的时间(正常情况下的请求和应答的时间)
syncLimit=5
# 修改zookeeper的存储路径
dataDir=/usr/local/zookeeper/zkData
# 客户端连接服务器的port
clientPort=2181
2.3 启动测试
2.3.1 在本地上开启server
[root@xxx01 ~]# zkServer.sh start
2.3.2 使用客户端连接服务
[root@xxx01 ~]# zkCli.sh [-server] [host]
2.3.3 进行一些命令的操作
[zk: localhost:2181(CONNECTED) 0] help
2.3.4 客户端退出
[zk: localhost:2181(CONNECTED) 1] quit/close
2.3.5 服务器退出
[root@xxx01 ~]# zkServer.sh stop
2.4 集群模式的配置
2.4.1 Zookeeper的服务进程布局
xxx01 QuorumPeerMain
xxx02 QuorumPeerMain
xxx03 QuorumPeerMain
2.4.2 修改zoo.cfg文件
[root@xxx01 local]# cd ./zookeeper/conf/
[root@xxx01 conf]# cp zoo_sample.cfg zoo.cfg #复制出zoo.cfg文件
[root@xxx01 conf]# vi zoo.cfg
tickTime=2000 # 定义的时间单元(单位毫秒),下面的两个值都是tickTime的倍数。
initLimit=10 #follower连接并同步leader的初始化连接时间。
syncLimit=5 #心跳机制的时间(正常情况下的请求和应答的时间)
dataDir=/usr/local/zookeeper/zkData #修改zookeeper的存储路径,zkData目录一会要创建出来
clientPort=2181 #客户端连接服务器的port
server.1=xxx01:2888:3888 # 添加三个服务器节点
server.2=xxx02:2888:3888
server.3=xxx03:2888:3888
解析Server.id=ip:port1:port2
id: 服务器的id号,对应zkData/myid文件内的数字
ip: 服务器的ip地址
port1: follower与leader交互的port
port2: 选举期间使用的port
注意:此配置文件中,不支持汉字注释
2.4.3 在$ZK_HOME/zkData/目录下添加myid文件,内容为server的id号
[root@xxx01 conf]# cd ..
[root@xxx01 zookeeper]# mkdir zkData
[root@xxx01 zookeeper]# cd zkData
[root@xxx01 zkData]# echo "1" >> myid
2.4.4 搭建其他两个server节点的环境
1)使用scp命令将zookeeper环境 复制到xxx02和xxx03中
[root@xxx01 zkData]# cd /usr/local
[root@xxx01 local]# scp -r zookeeper xxx02:/usr/local/
[root@xxx01 local]# scp -r zookeeper xxx03:/usr/local/
2) 使用scp命令拷贝/etc/profile到两台机器上(别忘记source一下)
[root@xxx01 local]# scp /etc/profile xxx02:/etc/
[root@xxx01 local]# scp /etc/profile xxx03:/etc/
3) 修改xxx02的myid文件的内容为2
[root@xxx01 ~]# ssh xxx02
[root@xxx02 ~]# echo "2" > /usr/local/zookeeper/zkData/myid
2.4.4.4 修改xxx03的myid文件的内容为3
[root@xxx02 ~]# ssh xxx03
[root@xxx03 ~]# echo "3" > /usr/local/zookeeper/zkData/myid
2.5 启动zookeeper
1)三台机器上都启动zookeeper的服务
[root@xxx01 ~]# zkServer.sh start
再查看一下状态
[root@xxx01 ~]# zkServer.sh status
2) 启动客户端的操作:
zkCli.sh [-server] [ ip:port]
reg:
[root@xxx01 ~]# zkCli.sh #启动客户端,连接本地服务进程
[root@xxx01 ~]# zkCli.sh -server xxx02:2181 #启动客户端,连接xxx02上的服务进程
3)连接成功后:
输入help,查看所有指令,如下
1. ls -- 查看某个目录包含的所有文件
2. ls2 -- 查看某个目录包含的所有文件,与ls不同的是它查看到time、version等信息
3. create -- 创建znode,并设置初始内容,例如:
[zk: 47.0.0.1:2181(CONNECTED) 1] create /test "test"
Created /test
4. get -- 获取znode的数据
5. set -- 修改znode内容
6. delete -- 删除znode
7. quit -- 退出客户端
8. help -- 帮助命令
4)错误集锦
1. java.net.NoRouteToHostException: 没有到主机的路由
原因1: 没有配置/etc/hosts
原因2: 没有关闭防火墙
2.6 节点类型
2.6.1 节点状态
1. ephemeral(短暂):客户端和服务器断开后,创建的节点自己删除。
2. persistent(持久):客户端和服务器断开后,创建的节点不删除(默认情况)
2.6.2 节点类型
1. persistent :断开连接后,该节点依旧存在
2. persistent_sequential :断开连接后,该节点依旧存在。节点名进行顺序编号
3. ephemeral :断开连接后,该节点自动删除
4. ephemeral_sequential :断开连接后,该节点自动删除。节点名进行顺序编号
三. Zookeeper的工作原理
3.1 选举制度
3.1.1 说明:
- 1. 基于节点在半数以上才能正常服务的要求,Zookeeper适合装在奇数台机器。
- 2. Zookeeper没有在配置文件中指定leader和follower,而是使用算法(Paxos)在内部通过选举机制来选择一
个节点为leader,其他节点为follower。
3.1.2 开机启动时的选举过程
假设有五台服务器组成的 zookeeper 集群,它们的 id 从 1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这一点上,都是一样的。假设这些服务器依序启动,来看看会发生什么。
1. 服务器1启动
此时只有它一台服务器启动了,它发出去的投票信息没有任何响应,所以它的选举状态一直是 LOOKING 状态。
2. 服务器2启动
它与最开始启动的服务器 1 进行通信,互相交换自己的选举结果,由于两者都没有历史数据,所以 id 值较大
的服务器 2 胜出,但是由于没有达到超过半数以上的服务器都同意选举它(这个例子中的半数以上是 3),所以
服务器 1、 2 还是继续保持LOOKING 状态。
3. 服务器3启动
根据前面的理论分析,服务器 3 成为服务器 1、 2、 3 中的老大,而与上面不同的是,此时有三台服务器选
举了它,所以它成为了这次选举的 leader。
4. 服务器4启动
根据前面的分析,理论上服务器 4 应该是服务器 1、 2、 3、 4 中最大的,但是由于前面已经有半数以上的
服务器选举了服务器 3,所以它只能接收当小弟的命
了。
5. 服务器5启动
同 4 一样当小弟
3.2 选举制度中的四个概念
- serverid:服务器id
比如有三台服务器,编号分别为1,2,3。编号越大在选择算法中的权重越大
- zxid:数据id
服务器中存放的最大数据ID。值越大说明数据越新,在选举算法中的权重越大
- Epoch:逻辑时钟
也可以称之为每个服务器参加投票的次数。同一轮投票过程中的逻辑时钟值相同
优先级:Epoch > zxid >serverid
- Server状态:选举状态
• LOOKING:竞选状态
• FOLLOWING:随从状态,同步leader状态,参与选票
• OBSERVING:观察状态,同步leader状态,不参与选票
• LEADER:领导者状态
3.3 Zookeeper的监听原理
3.3.1 图解:
1. 首先要有一个main()线程
2. 在main线程中创建Zookeeper客户端, 这时就会创建两个线程, 一个负责网络连接通信(connet),一个负责监听(listener)。
3. 通过connect线程将注册的监听事件发送给Zookeeper。
4. 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。
5. Zookeeper监听到有数据或路径变化, 就会将这个消息发送给listener线程。
6. listener线程内部调用了process() 方法。
3.3.2 用途:
1. 监听节点数据的变化: get /path watch
2. 监听子节点增减的变化 : ls /path watch
3.4 写数据流程
参考上图:
1. Client向Zookeeper的server1上写数据,发送一个写请求
2. 如果server1不是leader,那么server1会把请求进一步转发给leader。
3. 这个leader会将写请求广播给所有server。
4. 各个Server写成功后就会通知leader。
5. 当leader收到半数以上的server写成功的通知,就说明数据写成功了。写成功后,leader会告诉server1数据写成功了。
6. server1会进一步通知Client数据写成功了。这时就认为整个写操作成功。
四.HA的搭建
4.1 HA(high availability)的使用原因
1. 问题所在:
- 计划外的事件,比如:单点故障(SPOF)
- 计划内的事件,比如:namenode上的硬件或软件升级
2. 解决办法:
- 使用两个Namenode:
一个是正在工作的namenode,可以称之为Active节点;另外一个namenode充当备份节点,称之为Standby
节点;当Active节点不能使用了,Standby节点会立即转为Active状态,来接管集群,使之正常工作,这
就是现在的HDFS的高可用性,简称HA。这种状态的切换,对用户来说是透明的。
- 注意:standby节点会执行检查点机制,因此不需要配置secondarynamenode.
4.2 两个Namenode的缺点
4.3 JournalNode集群的功能介绍
4.3.1 每个journalnode节点都存储编辑日志
为了使备用节点保持其状态与活动节点同步,两个节点都与一组称为“ JournalNodes”(JN)的单独守护程序进行通信。当活动节点执行任何命名空间的修改时,它会持久地将修改记录记录到大多数这些JN中。Standby节点会一直监视JN,以查看编辑日志的更改。当“备用节点”看到编辑内容更改后,会将其应用于自己的命名空间。发生故障转移时,备用节点将确保在将自身升级为活动状态之前,已从JounalNodes读取所有编辑内容。这样可确保在发生故障转移之前,名称空间状态已完全同步。
4.3.2 防止脑裂的发生
对于HA群集的正确操作至关重要,一次只能有一个NameNode处于Active状态。否则,名称空间状态将在两者之间迅速分散,从而有数据丢失或其他不正确结果的风险。
为了确保该属性并防止所谓的“裂脑情况”,JournalNode将一次仅允许单个NameNode成为作者。在故障转移期间,变为活动状态的NameNode将仅承担写入JournalNodes的角色,这将有效地防止另一个NameNode继续处于活动状态,从而使新的Active可以安全地进行故障转移。
- 怎么理解脑裂?
就是Active节点处于网络震荡状态,假死状态,Standby就转为Active。等网络震荡过后,就有两个Active
了,这就是脑裂。
4.3.3 journalnode集群正常工作的条件
- 至少3个Journalnode节点
- 运行个数建议奇数个(3,5,7等)
- 满足(n+1)/2个以上,才能正常服务。即能容忍(n-1)/2个故障。
4.3.4 datanode同时向两个namenode心跳反馈
为了提供快速的故障转移,备用节点还必须具有集群中块位置的最新信息。为了实现这一点,DataNodes被配置了两个NameNodes的位置,并向两者发送块位置信息和心跳信号。
4.3.5 journalnode的缺点
在这种模式下,即使活动节点发生故障,系统也不会自动触发从活动NameNode到备用NameNode的故障转移,必须需要人为的操作才行。要是有一个能监视Active节点的服务功能就好了。
这个时候,我们就可以使用zookeeper集群服务,来帮助我们进行自动容灾了。
4.4 HA的自动容灾原理
如果想进行HA的自动故障转移,那么需要为HDFS部署两个新组件:ZooKeeper quorum和ZKFailoverController进程(缩写为ZKFC)。
4.4.1 Zookeeper quorum
Apache ZooKeeper是一项高可用性服务,用于维护少量的协调数据,将数据中的更改通知客户端并监视客户端的故障。HDFS自动故障转移的实现依赖ZooKeeper进行以下操作:
- 故障检测
群集中的每个NameNode计算机都在ZooKeeper中维护一个持久性会话。如果计算机崩溃,则ZooKeeper会话将
终止,通知另一个NameNode应触发故障转移。
- 活动的NameNode选举(HA的第一次启动)
ZooKeeper提供了一种简单的机制来专门选举一个节点为活动的节点。如果当前活动的NameNode崩溃,则另一
个节点可能会在ZooKeeper中采取特殊的排他锁,指示它应成为下一个活动的NameNode。
4.4.2 ZKFC的介绍
ZKFailoverController(ZKFC)是一个新组件,它是一个ZooKeeper客户端,它监视和管理namenode的状态。运行namenode的每台机器都会运行一个ZKFC,该ZKFC负责以下内容:
- 运行状况监视
ZKFC使用运行状况检查命令定期ping其本地NameNode。只要NameNode以健康状态及时响应,ZKFC就会认为该
节点是健康的。如果节点崩溃,冻结或以其他方式进入不正常状态,则运行状况监视器将其标记为不正常。
- ZooKeeper会话管理
当本地NameNode运行状况良好时,ZKFC会在ZooKeeper中保持打开的会话。如果本地NameNode处于活动状
态,则它还将持有一个特殊的“锁定” znode。该锁使用ZooKeeper对“临时”节点的支持。如果会话到期,则锁
定节点将被自动删除。
- 基于ZooKeeper的选举
如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,则它本身将尝试获取该锁。
如果成功,则它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于活动状态。故障转移过程类似于
上述的手动故障转移:首先,如有必要,将先前的活动节点隔离,然后将本地NameNode转换为活动状态。
4.5 HA的配置
- 如果你想从普通的hdfs安全分布式集群改为HA的配置,那么就一步一步的往下看,跟着文档进行配置
- 如果你还没有搭建hdfs完全分布式集群,而是想直接搭建一个HA集群,那么可以直接查看本章节中的4.13小节的内容
4.5.1 守护进程布局
xxx01: namenode journalnode datanode nodemanager resourcemanager QuorumPeerMain
xxx02: namenode journalnode datanode nodemanager QuorumPeerMain
xxx03: journalnode datanode nodemanager QuorumPeerMain
4.5.2 修改hdfs-site.xml里的配置信息
1) 配置名称服务的逻辑名称:
<property>
<name>dfs.nameservices</name>
<value>supercluster</value>
</property>
注意:注意:注意:逻辑名称一旦选定,下面的一些参数设置就必须使用此名称。息息相关。
2) 配置两个namenode的唯一标识符
<property>
<name>dfs.ha.namenodes.supercluster</name>
<value>nn1,nn2</value>
</property>
3) 针对于每一个唯一标识符的namenode,设置完整的rpc地址和端口。
<property>
<name>dfs.namenode.rpc-address.supercluster.nn1</name>
<value>xxx01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.supercluster.nn2</name>
<value>xxx02:8020</value>
</property>
4) 针对于每一个唯一标识符的namenode,配置http协议的地址和端口。
<property>
<name>dfs.namenode.http-address.supercluster.nn1</name>
<value>xxx01:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.supercluster.nn2</name>
<value>xxx02:50070</value>
</property>
5) 配置journalnode的服务器地址和存储目录(数目为奇数个)
<!-- 服务器地址使用分号“;”作为分隔符-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://xxx01:8485;xxx02:8485;xxx03:8485/journalData</value>
</property>
6) 指定客户端连接Active的namenode节点的java类型
<property>
<name>dfs.client.failover.proxy.provider.supercluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
7) 配置防护机制、免密登陆、免密超时时间
<!--为了保证系统的正确性,在任何时间只有一个NameNode处于Active状态,需要配置一个防护机制 -->
<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>/root/.ssh/id_rsa</value>
</property>
<!-- 免密登陆超时时间,超过此时间未连接上,则登陆失败,此配置可选-->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
8) 修改支持自动容灾属性
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
4.5.3 在core-site.xml文件里修改部分属性
1) 修改fs.defaultFS的属性值为名称服务的逻辑名称
<!--注意:是修改,修改,修改原属性的值不是追加,亲-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://supercluster</value>
</property>
2) 定义journalnode进程的数据存储的父路径(目录在上面已经定义好了的:journalData)
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/usr/local/hadoop/tmp</value>
</property>
3) 添加zookeeper服务器
<property>
<name>ha.zookeeper.quorum</name>
<value>xxx01:2181,xxx02:2181,xxx03:2181</value>
</property>
4) 将配置信息分发到其他节点上
[root@xxx01 ~]# scp /usr/local/hadoop/etc/hadoop/* xxx02:/usr/local/hadoop/etc/hadoop/
[root@xxx01 ~]# scp /usr/local/hadoop/etc/hadoop/* xxx03:/usr/local/hadoop/etc/hadoop/
4.6 HA的启动
HA的第一次启动,有以下两种情况:
- 1、当普通集群已经使用一段时间后,再转为HA,此时,已经存在fsimage文件了。
- 2、在搭建完全分布式时,直接搭建hdfs的HA,此时,还没有生成fsimage文件
注意:namenode所在的节点需要安装psmisc软件包 yum -y install psmisc
4.6.1 第一种情况:集群使用一段时间后,转为HA.
1. 启动三个节点上的journalnode服务,(请注意,如果集群启动了,先把集群stop掉)
[root@xxx01 ~]# hadoop-daemon.sh start journalnode
[root@xxx02 ~]# hadoop-daemon.sh start journalnode
[root@xxx03 ~]# hadoop-daemon.sh start journalnode
2. 同步日志到journalnode集群上
[root@xxx01 ~]# hdfs namenode -initializeSharedEdits
3. 启动以前节点上的namenode进程
[root@xxx01 ~]# hadoop-daemon.sh start namenode
4. 在新的namenode节点上拉取镜像文件
[root@xxx02 ~]# hdfs namenode -bootstrapStandby
5. 格式化zkfc
- 1、前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@xxx01 ~]# zkServer.sh start
[root@xxx02 ~]# zkServer.sh start
[root@xxx03 ~]# zkServer.sh start
- 2、选择其中一个namenode节点进行格式化zkfc
[root@xxx01 ~]# hdfs zkfc -formatZK
6. 你就可以快乐的开启HA集群进行测试了
[root@xxx01 ~]# start-all.sh
注意:以后开HA集群时,要先开zookeeper服务,再开HDFS。
4.6.2 第二种情况:搭建集群时,直接搭建HA
1. 启动三个节点上的journalnode服务
[root@xxx01 ~]# hadoop-daemon.sh start journalnode
[root@xxx02 ~]# hadoop-daemon.sh start journalnode
[root@xxx03 ~]# hadoop-daemon.sh start journalnode
2. 格式化namenode
- 先删除所有节点的${hadoop.tmp.dir}/tmp/的数据(可选,这一步表示弃用fsimage.)
- 选择其中一个namenode进行格式化
[root@xxx01 ~]# hdfs namenode -format
- 并启动namenode进程
[root@xxx01 ~]# hadoop-daemon.sh start namenode
3. 在另一台namenode上拉取已格式化的那台机器的镜像文件(数据的一致性)
[root@xxx02 ~]# hdfs namenode -bootstrapStandby
4. 然后关闭已经启动的namenode
[root@xxx01 ~]# hadoop-daemon.sh stop namenode
5. 格式化zkfc
- 1、前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@xxx01 ~]# zkServer.sh start
[root@xxx02 ~]# zkServer.sh start
[root@xxx03 ~]# zkServer.sh start
- 2、选择其中一个namenode节点进行格式化zkfc
[root@xxx01 ~]# hdfs zkfc -formatZK
6. 你就可以快乐的开启HA集群进行测试了
[root@xxx01 ~]# start-all.sh
注意:以后开HA集群时,要先开zookeeper服务,再开HDFS。
4.7 自动容灾的测试
- 1. kill掉Active的namenode,模拟宕机
- 2. 查看另一个Standby的namenode,你会发现已经转为Active了
4.8 相关进程的总结
- QuorumPeerMain:zookeeper服务组件对应的进程
- JournalNode:qjm对应的守护进程
- DFSZKFailoverController:zookeeper对应的自动容灾客户端进程,运行在Namenode节点上
- NameNode:
- ZookeeperMain:手动连接zookeeper服务所产生的客户端进
4.9 HA的手动故障转移命令
hdfs haadmin [-transitionToActive [--forceactive] <serviceId>]
[-transitionToStandby <serviceId>]
[-failover [--forcefence] [--forceactive] <serviceId> <serviceId>]
[-getServiceState <serviceId>]
[-checkHealth <serviceId>]
[-help <command>]
4.10 HA的配置总结
1) 环境准备:
1. 三台虚拟机:xxx01,xxx02,xxx03
2. 保证三台机器的防火墙都是关闭状态
3. 保证三台机器的免密登陆认证
4. 保证三台机器的时间同步
5. 保证三台机器的/etc/hosts文件的域名映射关系配置
6. 保证三台机器安装了jdk和hadoop,并且配置了环境变量且命令好使
2)hadoop/etc/hadoop/core-site.xml
<configuration>
<!-- 指定hdfs的ha的域名,注意这个是hdfs-site.xml文件里配置的逻辑名称 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://supercluster</value>
</property>
<!-- 指定hdfs的数据存储位置,此路径一旦指定,会被其他属性使用和依赖-->
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop/tmp</value>
</property>
<!-- 指定journalnode的数据存储位置-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/usr/local/hadoop/tmp</value>
</property>
<!-- 指定zookeeper集群的服务器节点,如果没有搭建zookeeper,请参考zookeeper知识模块-->
<property>
<name>ha.zookeeper.quorum</name>
<value>xxx01:2181,xxx02:2181,xxx03:2181</value>
</property>
</configuration>
3)hadoop/etc/hadoop/hdfs-site.xml
<configuration>
<!-- 指定块文件的复本个数-->
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<!-- 指定块文件的大小-->
<property>
<name>dfs.blocksize</name>
<value>134217728</value>
</property>
<!-- 节点动态上下线的配置
<property>
<name>dfs.hosts</name>
<value>/usr/local/hadoop/etc/hadoop/include</value>
</property>
<property>
<name>dfs.hosts.exclude</name>
<value>/usr/local/hadoop/etc/hadoop/exclude</value>
</property>
-->
<!-- 指定ha的名称服务:即逻辑名称-->
<property>
<name>dfs.nameservices</name>
<value>supercluster</value>
</property>
<!-- 指定ha的两个namenode的唯一标识符-->
<property>
<name>dfs.ha.namenodes.supercluster</name>
<value>nn1,nn2</value>
</property>
<!-- 指定两个唯一标识符,对应的主机和端口号-->
<property>
<name>dfs.namenode.rpc-address.supercluster.nn1</name>
<value>xxx01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.supercluster.nn2</name>
<value>xxx02:8020</value>
</property>
<!-- 指定两个唯一标识符,对应的web地址的主机和端口号-->
<property>
<name>dfs.namenode.http-address.supercluster.nn1</name>
<value>xxx01:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.supercluster.nn2</name>
<value>xxx02:50070</value>
</property>
<!-- 指定journalnode集群的服务器ip、port和存储目录-->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://xxx01:8485;xxx02:8485;xxx03:8485/journalData</value>
</property>
<!-- 指定客户端联系Active节点的java类-->
<property>
<name>dfs.client.failover.proxy.provider.supercluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 指定防止脑裂的防护机制,注意centos 7很可能会因为少一些内置命令而失效-->
<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.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<!-- start automatic-failover -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
4)hadoop/etc/hadoop/mapred-site.mxl
<configuration>
<!-- 配置执行mr的框架名称 -->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>xxx01:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>xxx01:19888</value>
</property>
</configuration>
5)hadoop/etc/hadoop/yarn-site.xml
<configuration>
<!-- 指定yarn的shuffle技术 -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<!-- 指定resourcemanager的主机名 -->
<property>
<name>yarn.resourcemanager.hostname</name>
<value>xxx01</value>
</property>
</configuration>
6)hadoop/etc/hadoop/hadoop-env.sh
[root@xxx01 hadoop]# vi hadoop-env.sh
................
# The java implementation to use.
export JAVA_HOME=/usr/local/jdk #指定你的jdk路径
..................
7)hadoop/etc/hadoop/slaves
[root@xxx01 hadoop]# vi slaves
# 指定三台datanode节点
xxx01
xxx02
xxx03
8)hadoop/etc/hadoop/yarn-env.sh
[root@xxx01 hadoop]# vi core-site.mxl
........省略........
# some Java parameters
export JAVA_HOME=/usr/local/jdk
........省略........
注意: 配置完后,请先阅读本文档的4.6的第二种情况,然后再进行启动。
(=-=,出来混迟早要还的哦~,正在赶日记中...)