Zookeeper概念

  • Zookeeper是分布式协调服务,用于治理大型主机,在分布式环境中协调和治理服务是很简单的过程,Zookeeper通过简略的架构和API解决了这个问题

    Zookeeper实现分布式锁

    分布式锁三要素:          加锁          解锁          锁超时
  • Zookeeper数据结构相似树结构,由节点Znode组成
  • Znode分为四种类型:

    • 长久节点(PERSISTENT): 默认节点类型,创立节点的客户端与Zookeeper断开连接后,节点仍旧存在
    • 长久节点程序节点(PERSISTENT_SEQUENTIAL): 长久节点程序节点就是在创立长久节点时,Zookeeper依据创立节点的工夫程序给节点进行编号
    • 长期节点(EPHEMERAL): 创立节点的客户端与Zookeeper断开连接后,长期节点会被删除
    • 长期节点程序节点(EPHEMERAL_SEQUENTIAL): 长期节点程序节点就是在创立长期节点时,Zookeeper依据创立节点的工夫程序给节点进行编号
    • 利用Zookeeper的长期程序节点,实现分布式锁

Zookeeper与Redis分布式锁比拟:

分布式锁ZookeeperRedis
长处1.有封装好的框架,容易实现
2.有期待锁队列,晋升抢锁的效率
Set和Del指令性能高
毛病增加和删除节点性能低1.实现简单,须要思考原子性,误删,锁超时问题
2.没有期待锁的队列,只能客户端自旋来等锁,效率低

Zookeeper的数据模型

  • 相似数据结构中的树,文件系统中的目录
  • Zookeeper的数据存储基于节点Znode
  • Znode的援用形式是门路援用,每一个Znode节点领有惟一的门路

    Znode中的元素

  • data: Znode存储的数据信息
  • ACL: 记录Znode的拜访权限,即哪些过程和IP能够拜访本节点
  • stat: Znode的各种元数据(数据的数据)
  • child: 以后节点的子节点援用
    Zookeeper的利用场景是读多写少的利用场景:Znode不用来存储大规模的业务数据,用于存储大量的状态和配置信息(Znode存储数据不能超过1MB)

    Zookeeper基本操作

  • 创立节点:create
  • 删除节点:delete
  • 判断节点是否存在:exists
  • 取得一个节点的数据:getData
  • 设置一个节点的数据:setData
  • 获取节点下的所有子节点:getChildren
    exists,getData,getChildren属于读操作,Zookeeper客户端在申请读操作时,能够抉择是否设置watch

    Zookeeper事件告诉

  • Watch能够了解成注册在特定Znode上的触发器
  • 当Znode产生扭转的时候,调用create,delete,setData办法,将会触发Znode上注册的对应事件,申请的Watch的客户端会接管到异步告诉
  • Zookeeper事件告诉的交互过程:

    • 客户端调用getData办法,watch的参数是true,服务端接管到申请,返回节点数据,在对应的Hash表中插入被Watch的Znode门路以及Watcher列表
    • 当被Watch的Znode删除,服务端会查找Hash表,找到该Znode对应的所有Watcher,异步告诉客户端,并且删除Hash表中对应的key-value

      Zookeeper的一致性

  • Zookeeper Service集群是一主多从构造
  • 在更新数据时,首先更新到主服务器,再同步到从服务器
  • 在读数据时,间接读取任意节点
  • 采纳ZAB协定,为了保障主从节点数据的一致性

    ZAB协定

  • ZAB(Zookeeper Automic Broadcast): 解决Zookeeper集群解体复原,主从数据同步问题
  • ZAB三种节点状态:

    • Looking:选举状态
    • Following:Following节点(从节点)所处的状态
    • Leading:Leading(主节点)所处的状态
  • 最大ZXID: 节点本地的最新事务编号,蕴含epoch计数两局部

    ZAB集群解体复原

  • 当Zookeeper的主节点服务器宕机后,集群就会进行解体复原,分成三个阶段:

    • Leader election(选举阶段):

      • 集群中的节点处于Looking状态,各自向其它节点发动投票,投票当中蕴含本人服务器的ID和最新事务ID(ZXID)
      • 节点用本身的ZXID和其它节点收到的ZXID作比拟,如果发现其它节点的ZXID比本身大,即数据比本人新,就从新发动投票,投票给目前已知最大ZXID所属节点
      • 每次投票后,服务器都会统计投票数量,判断是否某个节点失去半数以上的投票,这样的节点将会成为准Leader,状态变为Leading,其它节点状态变为Following
    • Discovery(发现阶段):

      • 在从节点发现最新的ZXID和事务日志,目标是为了避免在意外状况,选举产生多个Leader
      • Leader接管所有Follower发送的最新的epoch值,Leader从中选出最大的epoch,基于此值+1,生成新的epoch分发给各个Follower
      • 各个Follower接管到最新的epoch,返回ACK(响应码)给Leader,带上各自最大的ZXID和历史事务日志,Leader选出最大的ZXID,并更新本身历史日志
    • Synchronization(同步阶段):

      • 将Leader收集失去的最新历史事务日志,同步给集群中的所有Follower,只有当半数Follower同步胜利,这个准Leader能力成为正式Leader.集群解体复原正式实现

        ZAB主从数据同步

  • Broadcast
    Zookeeper惯例状况下更新数据的时候,由Leader播送到所有的Follower:

    • 客户端收回写入数据申请给任意的Follower
    • Follower把写入数据申请转发给Leader
    • Leader采取二阶段提交形式:(先保留提交日志,再提交数据)先发送Propose播送给Follower
    • Follower接管到Propose音讯,写入日志胜利后,返回ACK音讯给Leader
    • Leader接管到半数以上的ACK音讯,返回胜利给客户端,并且播送commit申请给Follower

      数据一致性:    强一致性    弱一致性    程序一致性:Zookeeper,依附事务ID和版本号,保证数据的更新和读取是有序的

      Zookeeper利用场景

  • 分布式锁: 利用Zookeeper的长期程序节点,实现分布式锁
  • 服务注册与发现: 利用Znode和Watcher,实现分布式服务注册与发现,如Dubbo
  • 共享配置和状态信息: Redis的分布式解决方案Codls,利用Zookeeper存放数据路由表和codls-proxy节点元信息,同时colds-config发动的命令都会通过Zookeeper同步到各个存活的codls-proxy
  • 高可用实现: Kafka,HBase,Hadoop都依附Zookeeper同步节点信息,实现高可用

    基于Docker创立Zookeeper

    1.创立docker-compose.ymlzoo:  image: zookeeper  restart: always  hostname: zoo  ports:      - 2181:2181  environment:      - ZOO_MY_ID: 1      - ZOO_SERVER: server.1(id)=zoo(IP):2888:38882.执行docker-compose up -d

    Zookeeper三种工作模式

  • 单机模式: 存在单点故障
  • 集群模式: 在多台服务器上部署Zookeeper集群
  • 伪集群模式: 在同一台服务器上运行多个Zookeeper实例,依然有单点故障问题,其中配置的端口号要错开

    Zookeeper三种端口号

  • 2181: 客户端连贯Zookeeper集群应用的监听端口号
  • 3888: 选举Leader应用
  • 2888: 集群内机器通信应用(Leader和Follower之间数据同步应用的端口号,Leader监听此端口)