一、zookeeper概述
1.zookeeper是也给分布式协调服务,就是为用户的分布式程序提供协调服务
2.zookeeper本身也是一个分布式程序
3.zookeeper是为别的分布式程序服务的(只要节点半熟以上存活,zookeeper就能对外提供服务)
3.zookeeper集群包含两个角色:Leader、Floower
二、zookeeper的核心功能
1.管理用户程序提交的数据
2.为用户程序提供数据节点的监听服务
三、zookeeper的应用场景
1.主从协调
2.服务器的动态上下线
3.统一的配置管理
4.分布式共享锁
5.统一的名称服务
四、zookeeper的特性
- zookeeper是由一个leader和多个follower组成的集群
- 全局数据一致性:每一个server都保存了一份相同的数据副本。client无论连接哪个server,数据都是一致的
- 分布式读写,更新请求转发,写请求只能由leader来实现,follower会将请求转发给leader来实施
- 更新请求按顺序进行,所有来自client的更新请求按照发送的先后顺序执行
- 数据更新的原子性:一次数据要么更新成功,要么更新失败
- 实时性:在一定时间范围内,client都能读到最新的数据
五、zookeeper的安装
1.安装前准备
(1)安装Jdk
(2)拷贝Zookeeper安装包到Linux系统下
(3)解压到指定目录
(1)解压
tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/apps
cd /opt/apps
(2)修改权限
chown root:root -R zookeeper-3.4.10
(3)更新配置文件(如下图所示)
export ZOOKEEPER_HOME=/opt/apps/zookeeper-3.4.10
export PATH=$PATH:$ZOOKEEPER_HOME/bin
source /etc/profile
(4)删除 doc、src文件
rm -rf docs src
(5)配置zookeeper的参数
cd zookeeper-3.4.10/conf
将/opt/apps/zookeeper-3.4.10/conf这个路径下的zoo_sample.cfg修改为zoo.cfg
先复制一份文件,再修改文件名
mv zoo_sample.cfg zoo.cfg
修改文件
vi zoo.cfg
修改tmp目录
dataDir=/opt/apps/zookeeper-3.4.10/data
为了做内部通信的数据传输,配置服务器节点,需要配置下面的内容(2888是数据传输的端口,3888是选举端口)内部实现细节如下图(server.1表示第1台服务器的id)
server.1=host01:2888:3888
server.3=host03:2888:3888
server.4=host04:2888:3888
有几台节点选几台
(6)在/opt/apps/zookeeper-3.4.10/这个目录上创建data文件夹(这里必须手动创建,和 hdfs 不同,hdfs 里面的配置不需要手动创建。)
mkdir data
(7)带data目录下配置节点的id,创建 myid 文件:echo "1" >> data/myid
(8)分发安装包
scp -r zookeeper-3.4.10 root@host03:$PWD
scp -r zookeeper-3.4.10 root@host04:$PWD
(9)修改host03和host04的myid内容
host03: echo "3" > data/myid
host04: echo "4" > data/myid
(10)操作Zookeeper
bin/zkServer.sh start
查看状态
bin/zkServer.sh status
或者jps
(11)将/etc/profile分发到另外两台机器host03、host04
(12)启动日志在zookeeper-3.4.10/zookeeper.out中,启动出错可以进去查看
六、选举机制
- 全新集群,第一次启动zookeeper的选举过程(id)大的为老大
先启动第一台机器,选举,第一台机器发送选票,满足不了半数存活要求,LOOKING状态
继续启动第二台机器,选举,第一轮选举,平手,都知道对方的存在。第二轮选举,都选id号大的,则选出2为Leader。。。
只有再启动其他机器就不会再选举leader了,因为已经选举出来了。。。。。。 - 非全新集群选举机制
(1)由数据的version,节点的id、逻辑时钟决定谁是leader
leader挂了,选举过程中,leader又起来了,leader的数据版本号大,但是逻辑时钟小,会忽略本次选举
(2)统一逻辑时钟(参与了多少次选举),数据版本大的节点为大
如果数据版本相同,则id大的为leader
七、命令
zookeeper的数据是全局一致的,每个节点都可以查到相同的文件
启动zookeeper:zkCli.sh
查看命令: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 -- 帮助命令
连接其他结点:connect host02:2181
zonde:znode的数据大小限制在1M以内
zookeeper一般都是用来记录数据的状态信息
ls命令:
ls path [watch] 浏览指定路径包含的子目录
[watch] 开启监听器,每个监听器只监听一次就会失效
查看根目录:ls /
监听内容:ls / watch (处理事件:ls /)
get命令:
get path watch 获取指定文件的的内容状态
[watch] 开启监听器,每个监听器只监听一次就会失效
get /sz2002
监听内容:get /sz2002 watch (处理事件:)
set path data
set /sz2002 8888888
create 命令:
create [-s] [-e] data alc
创建文件夹:create /sz2002 66666
结点状态:
1. ephemeral(短暂):客户端和服务器断开后,创建的节点自己删除。
2. persistent(持久):客户端和服务器断开后,创建的节点不删除(默认情况)
1.创建短暂的结点:
只有创建的客户端存在的情况下存在
如果创建的客户端断开与服务器的连接,则结点会自动删除
create -e /sz222 9999999999999999999
2.创建带序列的结点:(查看下图)
所有的节点在创建的时候都有一个序号,[-s]表示显示在节点名称上
每一个目录下的序号都是从0开始,创建节点
create -s /sz333 1111111111111111111
八、HA的搭建
1.HA概述
1)所谓HA(high available),即高可用(7*24小时不中断服务)。
2)实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3)Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。
4)NameNode主要在以下两个方面影响HDFS集群
NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用
HDFS HA功能通过配置Active/Standby两个nameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
2.HDFS-HA工作机制
1)通过双namenode消除单点故障
2.1 HDFS-HA工作要点
1)元数据管理方式需要改变:
内存中各自保存一份元数据;
Edits日志只有Active状态的namenode节点可以做写操作;
两个namenode都可以读取edits;
共享的edits放在一个共享存储中管理(qjournal和NFS两个主流实现);
2)需要一个状态管理功能模块
实现了一个zkfailover,常驻在每一个namenode所在的节点,
每一个zkfailover负责监控自己所在namenode节点,利用zk进行状态标识,
当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split现象的发生。
3)必须保证两个NameNode之间能够ssh无密码登录。
4)隔离(Fence),即同一时刻仅仅有一个NameNode对外提供服务
3.高可用机制的两个改变
1)元数据的存储方式发生了变化(Qjournal)
2)状态发生了变化(ZKFC监听)
4.预防脑裂两种方式
Active节点处于网络震荡状态,假死状态,Standby就转为Active。等网络震荡过后,就有两个 Active了,这就是脑裂。
ssh kill -9 namenode
自定义脚本
HDFS安装配置规划:
NameNode 2个
DataNode N个
zookeeper 3个
Qjournal 3个
ZKFC 2个
YARN安装配置规划:
ResourceManager N个
NodeManager N个
总结下来就是
zookeeper是单独的集群,3个Qjournal
Active的NameNode是单独一台
Active的ResourceManager单独一台
Standby
DataNode、NodeManager N台
5.配置
- 配置ssh host03到其他结点
之后再拷贝一份备份出来搞,因为后面还要再用hdfs,HA不利于后面学习 - 修改hdfs-sit.xml
vi $HADOOP_HOME/etc/hadoop/hdfs-sit.xml
<configuration>
<!-- 完全分布式集群名称,value可以随便写 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址和端口号 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>host01:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>host03:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>host01:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>host03:50070</value>
</property>
<!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://host01:8485;host03:8485;host04:8485/mycluster</value>
</property>
<!-- 访问代理类:client,mycluster,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
shell(/bin/true)
</value>
</property>
<!-- 使用隔离机制时需要ssh无秘钥登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
<!--这里主要是看自己是什么用户,我是root用户-->
</property>
<!-- 声明journalnode服务器存储目录-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jns/data</value>
</property>
<!--是否开启自动失败切换-->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
- 修改core-site.xml
vi core-site.xml
<configuration>
<!-- 把两个NameNode的地址组装成一个集群mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 把两个NameNode的地址组装成一个集群mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/apps/hadoopdata</value>
</property>
<!--设置依赖的zk集群的地址-->
<property>
<name>ha.zookeeper.quorum</name>
<value>host01:2181,host03:2181,host04:2181</value>
</property>
</configuration>
- 配置完分发其他机器这两个配置文件
scp core-site.xml hdfs-site.xml root@host03:$PWD
scp core-site.xml hdfs-site.xml root@host04:$PWD
scp core-site.xml core-site.xml root@host03:$PWD
scp core-site.xml core-site.xml root@host04:$PWD
HA的第一次启动,有以下两种情况:
- 1、当普通集群已经使用一段时间后,再转为HA,此时,已经存在fsimage文件了。
- 2、在搭建完全分布式时,直接搭建hdfs的HA,此时,还没有生成fsimage文件
方式一、直接升级
1.启动三个节点上的journalnode服务,(请注意,如果集群启动了,先把集群stop掉)
[root@host01 ~]# hadoop-daemon.sh start journalnode
[root@host03 ~]# hadoop-daemon.sh start journalnode
[root@host04 ~]# hadoop-daemon.sh start journalnode
2. 启动以前节点上的namenode进程
[root@host01 ~]# hadoop-daemon.sh start namenode
3. 在新的namenode节点上拉取镜像文件
[root@host03 ~]# hdfs namenode -bootstrapStandby
4. 同步日志到journalnode集群上,再启动集群 --先关namenode
[root@host01 ~]# hadoop-daemon.sh stop namenode --再同步日志 [root@host01 ~]# hdfs namenode -initializeSharedEdits
5. 格式化zkfc -
1、前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@host01 ~]# zkServer.sh start
[root@host03 ~]# zkServer.sh start
[root@host04 ~]# zkServer.sh start
2、选择其中一个namenode节点进行格式化zkfc
[root@host01 ~]# hdfs zkfc -formatZK
6.开启HA集群进行测试了
[root@host01 ~]# start-all.sh
方式二、重新格式化
严格按照以下步骤进行
1. 启动三个节点上的journalnode服务
[root@host01 ~]# hadoop-daemon.sh start journalnode
[root@host03 ~]# hadoop-daemon.sh start journalnode
[root@host04 ~]# hadoop-daemon.sh start journalnode
2. 格式化namenode
- 先删除所有节点的${hadoop.tmp.dir}/tmp/的数据(可选,这一步表示弃用fsimage.)
- 选择其中一个namenode进行格式化
[root@host01 ~]# hdfs namenode -format
- 并启动namenode进程
[root@host01 ~]# hadoop-daemon.sh start namenode
3. 在另一台namenode上拉取已格式化的那台机器的镜像文件(数据的一致性) [root@host03 ~]# hdfs namenode -bootstrapStandby
4. 然后关闭已经启动的namenode
[root@host01 ~]# hadoop-daemon.sh stop namenode
6. 格式化zkfc
1、前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@host01 ~]# zkServer.sh start [root@host03 ~]# zkServer.sh start
[root@host04 ~]# zkServer.sh start
2、选择其中一个namenode节点进行格式化zkfc [root@host01 ~]# hdfs zkfc -formatZK
7. 开启HA集群进行测试了 [root@host01 ~]# start-all.sh
注意:以后开HA集群时,要先开zookeeper服务,再开HDFS。
启动顺序:
1.启动zookeeper
2.启动hdfs
start-dfs.sh
5.HA的管理员命令
[root@host01 ~]# hdfs haadmin -
Usage: haadmin
手动转化namenode的状态为Active
[-transitionToActive [--forceactive] <serviceId>]
手动转化namenode的状态为Standby
[-transitionToStandby <serviceId>]
失败转移
[-failover [--forcefence] [--forceactive] <serviceId> <serviceId>]
查看namenode的状态
[-getServiceState <serviceId>]
检查namenode的健康状态
[-checkHealth <serviceId>]
[-help <command>]
总结HA命令
hadoop fs -
hdfs dfs -
hdfs dfsadmin -
hdfs haadmin -
hdfs namenode -
hdfs zkfc -
hdfs fsck