模块八_Zookeeper深入了解

序言:

文章内容输出来源:拉勾教育Java高薪训练营。
本篇文章是学习课程中的一部分课后笔记

一、简介

1、zookeeper 概述
  • 一个开源分布式协调服务,分布式数据一致性解决方案(共享存储)

  • 可实现 数据订阅/发布、负载均衡、命名服务、集群管理、分布式锁、分布式队列等功能

2、基本概念
  1. 集群角色

    • leader :为客户端提供读和写服务
    • follower : 提供读的服务,参与leader选举,写操作的过半写成功策略
    • observer : 提供读的服务
  2. 会话(session)
    客户端和服务端之间的一个tcp长连接,通过这个连接,客户端能够心跳检测与服务端保持有效会话,也能够向服务端发送请求并接受响应,还能接收服务端的watch事件通知

  3. 数据节点(znode)

    • 机器节点 : 集群的机器
    • 数据节点 : 数据模型中的数据单元 , /app/path (内存树 znode tree 中的节点信息)
  4. 版本
    一个stat 的数据结构,记录znode的三个数据版本:

    • version (znode的版本)
    • cversion (znode子节点的版本)
    • aversion (znode 的ACL 版本)
  5. watcher (事件监听器)

    • 允许用户在指定节点注册watcher,在一些特定事件触发的时候,zookeeper 服务端会将事件通知到感兴趣的客户端。
    • 流程:客户端向zookeeper服务器注册的同时,会将watcher对象存储在客户端watcherManager中,当zookeeper触发watcher事件后,会向客户端发送通知,客户端从watcherManager中取出对应的watcher 对象来执行回调逻辑。


      watcher.png
  1. ACL
    采用 ACL( Access Control Lists ) 策略进行权限控制:

    • create :创建子节点权限
    • read :获取节点数据&子节点列表权限
    • write : 更新节点数据权限
    • delete : 删除子节点的权限
    • admin :设置节点ACL的权限

    create & delete 都是针对子节点的权限控制

通常使用"scheme:id:permission" 标识一个有效的acl信息。
权限模式(scheme)、授权对象(id)、权限(permission)

acl.png

二、系统模型

1、zookeeper 数据模型
基本结构.png
2、ZNode 的类型
  1. 持久性节点

    • 节点被创建后会一直存在服务器中,直到删除操作主动清楚
  2. 临时性节点

    • 生命周期和客户端会话绑在一起,客户端会话结束,节点会被删除掉,不能创建子节点
  3. 顺序性节点

    • 附加到持久性节点与临时性节点的属性

三、应用场景

1、数据发布/订阅
  • 一般有两种设计模式:推(push)拉(pull)

例:

  • 配置存储
    将一些初始化配置信息存储到zookeeper上,如:


    配置信息.png
  • 配置获取
    集群中每台机器在启动初始化阶段,首先都会从配置节点中读取信息,同时,客户端还需要在该配置节点注册一个watcher监听,一旦发生节点数据变更,所有订阅的客户端都能得到通知。
  • 配置更新
    只需要对zookeeper上配置的节点内容进行更新,就能将变化的数据通知到各个客户端,客户端同步获取最新数据。
2、命名服务(全局唯一id分配机制)
命名服务.png

生成唯一ID的基本步骤:
1、所有客户端都会根据自己的任务类型,在指定的类型的任务下面通过调用create创建
一个顺序节点。
2 、create()会返回一个完整的节点名。如"job-0000000003"
3、客户端拿到完整的节点名后,拼接上type类型,"type2-job-0000000003",就可以是全局唯一的id了。

3、集群管理

zk的两大特性:

  1. 客户端如果对数据节点注册watcher监听,那么当该数据节点的内容或是其子节点列表发生变更时,zk服务器就会向订阅的客户端发送变更通知。
  2. 对在zk上创建的临时节点,一旦客户端与服务器之间的会话失效,那么临时节点也会被自动删除。

利用其两大特性,就可以实现集群机器存活监控系统。
若监控系统在/clusterServers节点上注册一个watcher监听,那么但凡进行动态的添加机器操作,就会在/clusterServers节点上创建一个临时节点,这样就能实时检测机器的变动情况。

4、分布式锁
  1. 排他锁
  • 如果事务T1对数据对象O1添加了排他锁,那么在整个加锁期间,只允许事务T1对O1进行读取和更新操作,其他事务都不能对O1进行任何类型操作----直到T1释放了排他锁。

ZK实现排他锁
① 定义锁
java中通过synchronized机制与jdk1.5提供的ReentrantLock。
zk通过定义数据节点,定义为一个锁:

定义锁.png

② 获取锁
客户端通过create()来创建临时节点,zk保证了最终只能一个客户端创建成功,其他没成功在该节点注册一个watcher监听,实时监听lock节点的变更情况。

③ 释放锁
情况一:当获取锁的客户端宕机,zk的临时节点就会被移除。
情况二:正常执行完业务逻辑后,客户端会主动删除自己创建的临时节点。

释放锁.png

  1. 共享锁

    • 如果事务T1对数据对象O1加上了共享锁,那么当前事务只能对O1进行读取操作,其他事务也只能对该数据对象加共享锁——直到该对象上的所有共享锁都被释放。

    排他锁&共享锁根本区别

    • 加了排他锁,数据对象只对一个事务可见。
    • 加了共享锁,数据对象对所有事务可见。

    ① 定义锁
    创建临时有序节点

    定义锁.png

    ② 获取锁
    创建临时有序节点,如果是读请求添加R类似的标识,写请求添加W类似标识。
    ZK判断读写顺序

读写顺序.png

③ 释放锁
与排他锁释放机制一样。

  1. 羊群效应
羊群效应.png

当ZK的所有子节点都注册watcher到host1时,当host1移除自己的共享锁之后,除了host2产生影响外(序号最小,进行写操作),其他机器都继续等待。
大量watcher通知和子节点列表获取两个操作会重复运行,影响性能与网络开销。

优化的逻辑核心:关注比自己序号小的那个相关节点的变更情况即可

优化锁逻辑.png

5、分布队列
  1. FIFO先入先出
    类似一个全是写操作的共享锁:


    FIFO.png
  1. Barrier:分布式屏障
    对一个节点数据内容赋值一个数字n代表barrier值,当字节点个数达到n后,才会打开barrier。
    场景: 分布式并行计算,最终的合并计算需要基于很多并行计算的子结果来进行。
    barrier.png

四、ZAB协议

1、ZAB概述

zookeeper Atomic Broadcast (原子消息广播协议),支持崩溃恢复的原子广播协议的分布式一致性算法。

2、ZAB核心
  • 定义了对于那些会改变zk服务器数据状态的事务请求的处理方式。


    ZAB核心.png
3、崩溃恢复

leader服务器出现异常情况,ZAB进入崩溃恢复模式,同时选举产生新的leader服务器。
当集群中已经有过半的机器与该leader服务器完成状态同步(数据同步)之后,ZAB协议就会退出崩溃恢复模式。

4、消息广播(类似二阶提交过程)

当集群中已经有过半的follower服务器完成了和leader服务器的状态同步,整个服务框架就可以进入消息广播模式。
当新加入一台机器,就会进入数据恢复模式,找到leader所在服务器,并与其进行数据同步,然后一起参与到消息广播流程中去。

请求.png

过程.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容