-
- 1.1. Zookeper的典型应用场景
- 1.1.1. 配置中心
- 1.1.2. 命名服务
- 1.1.3. 集群管理
- 1.1.4. 服务注册中心&复杂均衡
- 1.1.5. 集群master的选举
- 1.1.6. 分布式锁
- 1.1.7. 分布式队列
- 1.1. Zookeper的典型应用场景
-
- 2.1. Zookeper的数据结构
- 2.2. Zookeper的节点
- 2.3. Zookeper实现的分布式锁
- 2.4. 📣Zookeper的watch机制是如何工作的?
- 2.5. Zookeper如何保证创建的节点是唯一的?
- 2.6. Zookeper客户端的命令
-
- 3.1. Zookeper集群中的角色有哪些?有什么区别?
- 3.1.1. 领导者Leader
- 3.1.2. 跟随者Follower
- 3.1.3. 观察者Observer
- 3.2. Zookeper是CP的还是AP的?
- 3.3. Zookeper的选举机制是怎样的?
- 3.4. 什么是脑裂?如何解决?
- 3.1. Zookeper集群中的角色有哪些?有什么区别?
Zookeper
1. Zookeper应用场景
1.1. Zookeper的典型应用场景
1.1.1. 配置中心
- 将服务的信息配置到Zookeper的一个节点上
- 应用对该节点注册一个watcher,一旦更新就去该节点上获取最新的配置数据。
1.1.2. 命名服务
- 路径代表地址,比如/myMachine/name
- 节点的数据就是多个节点ip
1.1.3. 集群管理
- 节点信息作为Zookeper的临时节点,通过临时节点监控服务的存活状态
- Zookeper的watcher机制接收控制信息
1.1.4. 服务注册中心&复杂均衡
- 对某一个服务注册一个持久节点作作为对外提供服务的名称
- 服务提供者启动后将自己挂在对应服务的下面,创建的是临时节点,保存自己的调用信息
- 消费者调用服务的时候,去对应的服务下面查出所有的provider。并采用watcher监听服务提供者们的变化。
- 消费者根据服务注册表,用本地负载均衡算法去访问对应的服务
1.1.5. 集群master的选举
-
即从一个集群多个server中选举中一个master完成某个任务
-
采用分布式锁容易实现这个,但是无法检测到server的存活状态。于是使用Zookeper的唯一性(同一路径的节点是唯一的)机制和watcher机制(宕机节点消失,watcher检测到后重新选举)即可。
1.1.6. 分布式锁
- 在一个指定目录下,客户端进行加锁就是加一个顺序临时节点
- 如果是序号最小的,则获取锁成功。如果不是序号最小的,watcher它序号的上一个节点。
- 释放节点的时候会被下一个节点watcher,下一个节点继续获取锁(判断是否是序号最小)
Zookeper支持的分布式锁的种类有排他可重入锁,排他不可重入锁,读写锁,共享锁等
1.1.7. 分布式队列
与分布式锁类似,因为分布式锁本身也是一个阻塞队列实现的
2. Zookeper的实现
2.1. Zookeper的数据结构
- ZK中数据是以目录结构的形式存储的。其中一个存储数据的节点都叫Znode,每个Znode都有唯一路径表示。
- 每一个节点可能有子节点(临时节点除外)。节点中可以存储数据和状态,
- 每个Znode可以配置监视器(watcher),用于监听节点中的数据变化。
- 节点只支持一次性独写
2.2. Zookeper的节点
2.2.1. 临时节点
临时节点的生命周期和客户端会话绑定
2.2.2. 持久节点
一直存在,直到手动删除
2.2.3. 临时顺序节点
临时节点的生命周期和客户端会话绑定,并且会自动加上编号
2.2.4. 持久顺序节点
生命周期永久,并且会自动加上编号。
2.3. Zookeper实现的分布式锁
- 锁可以释放:因为是临时节点
- 阻塞锁:Zookeper实现阻塞的锁,watcher机制监听前一个节点来唤醒。
- 可重入:每次加入新的lock节点之后,判断序号最小的和当前新加的lock的信息是否是一样的,如果是则代表重入
- 单点问题:Zookeper搭集群可以解决单点有效问题
缺点:没有缓存性能高
2.4. 📣Zookeper的watch机制是如何工作的?
客户端ZkWatcherManager,服务端watchManage
- ZkWatchManager创建watcher并注册到客户端,客户端将watcher信息发给服务端
- Zookeper服务端收到客户端发送的watcher信息后,会将该watcher信息交给watchManager处理。watchManager会将该watcher注册到对应的znode节点上,并将watcher相关的信息保存到内存中
- 当znode发生变化,watchServer会通知zookeper server
- zookeeper Server会根据变化的类型通知客户端
- zkWatcherManager会根据watcher的类型触发相应的事件处理方法
2.5. Zookeper如何保证创建的节点是唯一的?
- 写请求都由Leader写
- synchronized + concurrentHashMap
具体的,创建节点的时候先synchronized将父节点锁住,然后判断该节点是否存在,不存在就用concurrentHashMap的线程安全方法put添加node
2.6. Zookeper客户端的命令
2.6.1. ls
因为zookeper是树状的,所以可以查看该层有哪些节点
ls /
查看根节点
ls /dubbo
查看dubbo根节点下面有哪些节点
ls /dubbo/config
同理
ls -s /dubbo
查看节点详细信息
2.6.2. create
- 创建持久化节点
create /appl itheima
创建/appl持久化节点,数据为itheima
- 创建临时节点
create -e /appl itheima
创建/appl临时节点,数据为itheima
- 创建持久化顺序节点
create -s /appl
创建的节点会自动加编号
- 创建临时顺序节点
create -es /appl
2.6.3. get
获取 /appl 节点
get /appl
2.6.4. set
设置 /appl 的值为itcast
set /appl itcast
2.6.5. delete
delete 删除 /appl/p1
delete /appl/p1
3. Zookeper高可用
3.1. Zookeper集群中的角色有哪些?有什么区别?
3.1.1. 领导者Leader
- 事务读和写请求的处理
- 负责投票的发起和决议
3.1.2. 跟随者Follower
- 接受事务写请求转发给Leader,返回请求结果
- 为客户端提供读服务
- 用于客户端请求并响应客户端的返回结果
3.1.3. 观察者Observer
- 可以客户端连接,写请求转发给leader
- 不参与投票,只同步leader的状态
- observer的目的是为了扩展系统,提高系统读取速度
3.2. Zookeper是CP的还是AP的?
CP的,会丢掉可用性A
遇到极端情况,比如集群中网络分割的故障,Zookeper会将它们都从自己的管理范围中删除出去,外界就不能访问这些节点了
3.3. Zookeper的选举机制是怎样的?
可以参考raft算法的投票选举思想
- 在启动阶段或者Leader失效的时候,会发起Leader选举
- 选举就是根据每个节点的zxid比较,如果别人zxid >=自己的就投给它一票
- 选举可能分多轮,如果一轮选不出来(两个票数相同),则重新选举
- Leader选出来以后同步给集群其他节点
3.4. 什么是脑裂?如何解决?
3.4.1. 脑裂出现的原因?
- Zookeper集群中的某些节点无法与其他节点通信时,就会出现网络分区现象。这时,会出现多个主节点。
- 主节点宕机,集群会选出新的主节点。等宕机的主节点恢复后,就会出现两个主节点。
3.4.2. 脑裂的解决?
- 自动恢复。一般会重新选取主节点,并同步给集群。
- 手动恢复:比较复杂
3.4.3. 避免脑裂产生?
- 通过Zookeper的watch机制监听节点的变化,及时发现异常情况
- 设置合适的选举超时时间,设置合适的节点数量