• [zookeeper]介绍|特点|节点的类型|服务器几个节点|选举机制|监听原理|常用命令


    一、介绍

    1.zookeeper是分布式协调工具

    2.zookeeper=文件系统+通知机制

    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 - 博客园

    1、持久化目录节点(persistent)

    客户端与zookeeper断开连接后,该节点依旧存在。

    2、持久化顺序目录节点(persistent_sequential)

    该节点创建时,名称进行顺序编号,客户端与zookeeper断开连接后,该节点依旧存在。

    3、临时目录节点(ephemeral)

    客户端与zookeeper断开连接后,该节点删除。

    4、临时顺序目录节点(ephemeral_sequential)

    该节点创建时名称进行顺序编号,客户端与zookeeper断开连接后,该节点删除。

    四、zookeeper几个服务器节点

    单数机制:2N+1 (安装奇数台)

    10台服务器:3台

    20台服务器:5台

    100台服务器:11台

    五、选举机制

    1、zookeeper服务器启动时期的Leader选举

    这里选取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。

    2、服务器运行时期Leader选举

    1)集群中已经存在Leader

    此种情况一般都是某台机器启动得比较晚,在其启动之前,集群已经在正常工作,对于这种情况,该机器试图去选举Leader时,会被告知当前服务器的Leader信息,对于该机器而言,仅仅需要和Leader节点建立起连接,并进行状态同步即可。

    2)集群中不存在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 

    六、监听

    1、程序的入口

    main()方法对应一个main线程

    2、在该main线程中创建zookeeper客户端

    1. new Zookeeper(),创建客户端的同时会创建两个线程:
    2. 1)sendThread:发送注册监听事件的线程
    3. 2)eventThread:发送变化通知给客户端的线程

    3、通过sendThread线程将注册的监听事件发送给zookeeper

    getChildren("/",true) 第一个参数为监听的路径,第二个参数为true表示开启监听.

    4、将注册监听事件添加到zookeeper的注册监听器列表中。 

    5、当zookeeper监听到变化时,就会将这个消息发送给eventThread线程。

    6、eventThread线程内部调用了precess()方法进行业务处理

    1. 注:zookeeper一共有3个方法可以实现Watch:
    2. 1)getData:该方法仅监控对应节点数据的一次变化,可以是该节点中该数据的修改或对该节点的删除。
    3. 2)exists(final String path,boolean watcher) 判断该Znode是否存在
    4. 开启监听时与getData的作用一毛一样
    5. 3)getChildren(String path,boolean watch)
    6. 该方法用于获取某一路径下所有的直接子节点,第一个参数为路径,第二个参数为是否监听直接子目录节点的增删,该方法仅监控对应及诶单直接子目录的一次变化,且只监听直接子目录下节点的增减情况,不会监控数据的变化。

    七、常用命令

    create、get、ls

     

  • 相关阅读:
    行为型模式-中介者模式
    编译buildroot出错,这个怎么解决呢,感谢
    HC32L110 系列 M0 MCU 介绍和Win10下DAP-Link, ST-Link, J-Link方式的烧录
    深度学习基础之BatchNorm和LayerNorm
    Linux编译器-gcc/g++使用和动静态库的对比
    048:vue+openlayers鼠标click显示企业名片(代码示例)
    Mysql 详解所有的数据类型
    day23
    你知道MySQL是如何解决幻读的吗?
    相关性质和条件变量-ReentrantLock详解(2)-AQS-并发编程(Java)
  • 原文地址:https://blog.csdn.net/qq_35896718/article/details/127632954