什么是zookeeper
zookeeper是一个用于降低分布式系统开发过程中节点间协调问题开发难度的工具!该工具解决了分布式系统中 , 节点和节点之间的动态感知问题
Zookeeper是一个分布式协调服务;就是为用户的分布式应用程序提供协调服务
zookeeper是为别的分布式程序服务的
Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务)
Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务……
虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能:
管理(存储,读取)用户程序提交的数据;
并为用户程序提供数据节点监听服务;
Zookeeper集群的角色: Leader 和 follower (Observer)
只要集群中有半数以上节点存活,集群就能提供服务(部署服务的时候一般使用奇数,3,5,7)
zookeeper提供的功能有
提供数据注册功能;
提供数据查询功能;
提供数据监听功能;
zookeeper能用来做什么
分布式系统中的主从协调;
分布式系统中的名称服务;
分布式系统中的分布式共享锁;
分布式系统中的配置文件同步;
分布式系统中的服务器负载均衡;
zookeeper的特性
zookeeper本身也是一个分布式系统;
zookeeper是一个高可靠高可用的系统;
半数机制:集群中半数以上机器存活,集群可用。zookeeper适合装在奇数台机器上!!!
1、Zookeeper:一个leader,多个follower组成的集群
2、全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的
3、分布式读写,更新请求转发,由leader实施
4、更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行
5、数据更新原子性,一次数据更新要么成功,要么失败
6、实时性,在一定时间范围内,client能读到最新数据
zookeeper数据结构
层次化的目录结构,命名符合常规文件系统规范
每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识
节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)
客户端应用可以在节点上设置监视器
zookeeper中的数据组织形式
zookeeper中的数据以key-value形式存储,查看
只不过zookeeper中的数据的key很特别:是路径的形式 /aa /aa/bb . value可以是任意二进制数据 byte[ ]
zookeeper中的数据节点有以下模式
永久模式Persistent:一旦被创建,除非客户端主动删除,则一直保存;
临时模式Ephemeral:创建这类节点的客户端必须跟zk集群保持心跳通信,一旦心跳连接中断,zk服务会自动将这个客户端所创建的节点删除;
带序号的模式:一旦创建这类节点,zk会自主在客户端所创建的key上拼接一个序号
为什么要奇数台?以及选举leader的机制
zookeeper这个分布式系统没有固定的主节点(leader),它的主节点是通过集群各节点动态选举出来的。
选举的规则:谁得多数票,谁就当选为leader
初次启动的投票过程(假设集群为3台,每台节点都在配置文中配了自己的 id
集群中n1启动,它会在网络中寻找leader,没有leader,则开始向网络中广播投票(第一次投自己)
集群中n2启动,它会在网络中寻找leader,没有leader,但是收到了n1的票,n2也投票(由于n2的id>n1的id,n2就投自己); n1会收到n2的票后,得知n2的存在以及n2的id,则n1重新投票(投n2);
此时,n2得2票,过半数,则当选为leader,n2将自己的工作状态切换为Leader;n1则将自己的状态从投票状态切换为follower;
启动中n3启动,它会在网络中寻找leader,发现n2是leader,自己主动进入follower状态;
运行过程中leader宕机,其他机器发现leader不在,进入投票选举状态
投票规则:投数据版本最新的节点为leader;如果大家的数据版本一样,则投id大的为leader;
zookeeper自启动脚本
#!/bin/bash
for host in hadoop01 hadoop02 hadoop03
do
ssh $host "source /etc/profile;/root/apps/zookeeper-3.4.6/bin/zkServer.sh start"
done
sleep 3
for host in cts02 cts03 cts04
do
ssh $host "source /etc/profile;/root/apps/zookeeper-3.4.6/bin/zkServer.sh status"
done
zookeeper数据监听功能
zk的客户端可以向zk服务集群注册对某个key的监听;
而且可以选择监听这个key上所发生的事件的类型:key的data变化事件! key的子节点变化事件!
zookeeper的选举机制
全新集群paxos :
以一个简单的例子来说明整个选举的过程.
假设有五台服务器组成的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一样,当小弟.
非全新集群的选举机制(数据恢复)
那么,初始化的时候,是按照上述的说明进行选举的,但是当zookeeper运行了一段时间之后,有机器down掉,重新选举时,选举过程就相对复杂了。
需要加入数据id、leader id和逻辑时钟。
数据id:数据新的id就大,数据每次更新都会更新id。
Leader id:就是我们配置的myid中的值,每个机器一个。
逻辑时钟:这个值从0开始递增,每次选举对应一个值,也就是说: 如果在同一次选举中,那么这个值应该是一致的 ; 逻辑时钟值越大,说明这一次选举leader的进程更新.
选举的标准就变成:
1、逻辑时钟小的选举结果被忽略,重新投票
2、统一逻辑时钟后,数据id大的胜出
3、数据id相同的情况下,leader id大的胜出
根据这个规则选出leader。