Zookeeper 学习笔记

  • 什么是Zookeeper
    Zookeeper分为服务端和客户端
    一个服务端可以理解为多个节点容器,节点被成为ZNode,一个节点类似于一个文件,用于保存数据,例如字符串。同时,一个节点也可以理解为一个目录,即可以在一个节点下新建其他节点。
    一个Zookeeper集群可以有多个服务端,每个服务端在启动时就已经在配置文件中配置了其他服务端的信息,例如ip和通信端口等。
    在集群中,任意修改某个服务端中的节点数据都会实时同步到其他服务端。即集群中的服务端节点数据始终保持一致
    客户端可以连接任意服务端增加、删除、修改、监听任意节点的变化。可以直接使用客户端的Shell,也可以在项目中引入Zookeeper的依赖,创建一个客户端,类似于JDBC或者Jedis等。

  • 特点

    1. Zookeeper有一个Leader和多个Follower
    2. 集群中只要有半数以上节点存活,Zookeeper季军就能正常服务
    3. 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接哪个Server,数据都是一致的
    4. 更新请求顺序执行,来自同一个Client的更新请求按照其发送顺序依次执行
    5. 数据更新的原子性,一次数据更新要么成功要么失败
    6. 实时性,在一定时间范围内,Client能读到最新的数据
  • 数据结构及存储方式
    Zookeeper数据模型的结构与Unix文件系统类似,整体上可以看作是一棵树,每个节点称作为一个ZNode,每个ZNode默认能够存储1MB的数据,每个ZNode都可以通过其路径唯一标志

    graph
    n --/znode1--> n1
    n --/znode2--> n2
    n1 --/znode1/leaf1--> n3
    n1 --/znode1/leaf2--> n4
    n2 --/znode2/leaf1--> n5
  • 应用场景

    1. 统一命名服务
      在分布式环境下,经常需要对应用或者服务器进行统一命名,便于标识。类似域名和IP
    2. 统一配置服务
      在分布式环境下,配置文件同步非常常见。将配置信息写入Zookeeper上的一个ZNode,每个客户端监听该ZNode,一旦该节点配置发生变化,leader将通知其他节点进行更新
    3. 统一集群管理
      分布式环境中,实时掌握每个节点的状态是必要的。Zookeeper可以实时监控节点状态的变化,可以将节点信息写入Zookeeper上的一个Znode,然后监听这个node获取它实时状态变化
    4. 服务器节点动态上下线
      客户端需要实时洞察服务器的上下线状态
    5. 软负载均衡
      在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器取处理最新的请求
  • 选举机制

    1. 半数机制:集群中半数以上的机器存活,集群可用。所以Zookeeper更适合安装奇数台服务器。
    2. Zookeeper索然在配置文件中没有指定Master和Slave。但是Zookeeper工作时还是有一个节点为Leader,其他则为Follower,Leader是通过内部选举机制产生的。
    3. 举例说明选举过程:
      假设一个Zookeeper集群有五台服务器,他们的ID从1-5,同时他们都是最新启动的,也就是没有历史数据。假设这些服务器依次启动,则每台服务器启动后先选自己,如果没有成为Leader则选择ID号最大的,一旦某台服务器票数超过一半(在服务器启动时,已经在配置文件中配置了所有服务器的信息,故启动时是直到服务器总数的),就确认当选。例如3号服务器启动之后,即当选为Leader,由于票数已经超过了半数,故当4、5号机启动时不在进行选举。
  • 节点类型

    1. 持久型(Perisitent):客户端和服务器端节点断开连接,创建的节点不删除(默认)
      持久型的又分为两类:1)持久化目录节点。2)持久化顺序编号目录节点,即创建znode时设置顺序标识,znode名称后面会加上一个单调增的id。在分布式系统中,顺序号可以被用于所有事件的全局排序,这样客户端可以通过顺序号推断事件的顺序
    2. 短暂型(Ephemeral):客户端和服务器端节点断开连接后,创建的节点自己删除
      同持久型,分两类。该类型一般用于判断服务器上下线。例如将某台应用服务器与某个短暂型节点绑定,一旦该服务器掉线,则该节点也被删除,监听该节点的客户端就能知道该服务器不可用了。
  • 监听器原理

    1. 首先要有一个main()线程
    2. 在main线程中创建Zookeeper客户端,这时就会创建两个线程,一个赋值网络通信(connect),一个负责监听(listener)
    3. 通过connect线程将注册的监听事件发送给Zookeeper(通过getChildren("/", rue)方法)
    4. 在Zookeeper的注册监听器列表中将之策的监听事件添加到列表中
    5. Zookeeper监听到由数据或路径变化,就会将该消息发送到listener线程
    6. listener线程内部调用process(方法)
  • 写数据流程

    1. Client向Zookeeper上的Server1写数据,发送一个写请求
    2. 如果Server1不是Leader,那么Server1就会把接收到的请求进一步转发给Leader,因为每个Zookeeper的Server里面就会有一个时Leader,该Lieader就会将写请求广播给各个Server,各个Server写成功后就会通知Leader
    3. 当Leader收到大多数Server数据写成功了没那么说明数据写成功了。之后Leader会告知Server1数据写成功了。

Leave a Comment