1)文件系统:由znode组成
2)通知机制:客户端可以监听znode子目录或znode中存储的内容,一旦监听的东西发生变化,会收到zookeeper的通知,客户端从而可以做出相应反应。
1、zookeeper是server组成的集群,会从server选举出一个leader其余为follower。
1)leader负责投票的发起和决议,更新服务系统状态。
2)follower负责在选举leader过程中参与投票,接收客户端请求并向客户端返回结果。
2、集群只要有半数以上节点存活,zookeeper集群就能正常服务。
3、全局数据一致。
每个server存储相同的数据,客户端无论连接哪个server,看到的数据都是一样的。
4、数据更新原子性
一次数据更新要么成功,要么失败。
5、更新请求顺序进行
来自同一个客户端的更新请求按其发送顺序依次执行。
6、实时性
客户端能读到最新的数据(在一定的时间范围内)。
操作:zookeeper节点类型 - Forever77 - 博客园
客户端与zookeeper断开连接后,该节点依旧存在。
该节点创建时,名称进行顺序编号,客户端与zookeeper断开连接后,该节点依旧存在。
客户端与zookeeper断开连接后,该节点删除。
该节点创建时名称进行顺序编号,客户端与zookeeper断开连接后,该节点删除。
单数机制:2N+1 (安装奇数台)
10台服务器:3台
20台服务器:5台
100台服务器:11台
这里选取3台机器组成的集群为例,在集群初始化的阶段,当有一台服务器Server1启动时,其单独无法进行Leader的选举。
当第二台服务器Server2启动时,此时两台机器可以相互通信,每台机器都试图找到Leader,于是进入了Leader选举过程,选举过程如下:
【1】每一个Server发出一个投票
由于是初始情况,Server1和Server2都会将自己作为Leader服务器进行投票,每次投票包含所有推举的服务器的SID和ZXID,使用(sid,zxid)来标识,此时Server1的投票为(1,0),Server2的投票为(2,0),然后各个将这个投票发给集群中的其他机器。
【2】接收来自各个服务器的投票
集群的每个服务器收到投票后,首先判断该投票的有效性,如检查是否是本轮投票,是否来自LOOKING状态的服务器。
【3】变更投票
针对每一个投票,服务器都需要将别人的投票和自己的投票进行PK,PK规则如下:
优先检查ZXID,ZXID较大的服务器作为Leader;ZXID相等的,SID大的作为Leader。
对于Server1而言,它的投票是(1,0),接收Server2的投票为(2,0),首先会比较两者的ZXID,server1的sid=server2的sid;再比较SID,此时Server2的SID 对于Server2而言,不做任何处理。 【4】选举Leader 当集群中有一台机器收到了半数以上的投票,该投票的sid即为Leader。其他为Follower。此时,Server2为Leader,Server1,Server3为Follower。 Leader变更自己的状态为LEADING;FOLLOWER变更自己的状态为FOLLOWING。 此种情况一般都是某台机器启动得比较晚,在其启动之前,集群已经在正常工作,对于这种情况,该机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器而言,仅仅需要和Leader节点建立起连接,并进行状态同步即可。 【1】第一次投票。 无论是哪种情况导致Leader选举,集群的所有机器都处理试图选举出一个Leader的状态,即LOOKING状态。LOOKING机器向所有其他机器发送信息,该消息称为投票,投票中包含了SID(服务器的唯一标识)和ZXID(事务ID),(SID,ZXID)形式标识一次投票信息。 假定zookeeper由5台机器组成,SID分别为1,2,3,4,5;ZXID为9,9,9,8,8并且此时SID为2的机器为Leader,某一刻1,2所在的机器出现故障,因此集群开始进行Leader选举。在第一次投票时,每台机器都会将自己作为投票的对象,于是SID为3,4,5的机器投票情况为(3,9) (4,8) (5,8)。 【2】接收投票 接收到来自每个服务器的投票。 【3】变更投票 每台机器发出投票后,也会收到其他机器的投票,每台机器根据一定的规则来处理其他机器的投票,并以此来决定是否需要变更自己的投票,这个规则也是整个Leader选举算法的核心所在,其中术语描述如下: vote_sid:接收到的投票中所推举Leader服务器的SID vote_zxid:接收到的投票中所推举Leader服务器的ZXID self_sid:当前服务器自己的SID self_zxid:当前服务器自己的ZXID 每次对接收到的投票的处理,都是对(vote_sid,vote_zxid)和(self_sid,self_zxid)对比的过程。 规则一:如果vote_zxid大于self_zxid,就认可收到的投票,并再次将投票发送出去。 规则二:如果vote_zxid小于self_zxid,那么坚持自己的投票,不做任何处理。 规则三:如果vote_zxid=self_zxid那么就对比两者的SID,如果vote_sid>selft_sid那么就认可当前收到的投票,并再次将投票发送出去。 规则四:如果vote_zxid=self_zxid,并且vote_sid 【4】确定Leader 经过第二轮投票后,集群中每台机器都会再次接收到其他机器的投票,然后开始统计投票,如果一台机器收到了超过半数的相同投票,那么这个投票对应的sid机器即为Leader,此时Server3将成为Leader。 【5】注 zxid由两部分组成 高32位为epoch(纪元):每当zookeeper的Leader发生一次变换epoch+1 低32位为counter(计数器):每当数据更新一次counter+1
main()方法对应一个main线程
create、get、ls
2、服务器运行时期Leader选举
1)集群中已经存在Leader
2)集群中不存在Leader
六、监听
1、程序的入口
2、在该main线程中创建zookeeper客户端
3、通过sendThread线程将注册的监听事件发送给zookeeper
getChildren("/",true) 第一个参数为监听的路径,第二个参数为true表示开启监听.
4、将注册监听事件添加到zookeeper的注册监听器列表中。
5、当zookeeper监听到变化时,就会将这个消息发送给eventThread线程。
6、eventThread线程内部调用了precess()方法进行业务处理
七、常用命令