zookeeper学习笔记

一、zk特性
一致性:数据一致性
原子性:要么成功要么都失败。
单一视图:客户端链接集群中的任意zk节点,数据都一致
可靠性:每次对zk的操作状态都回保存在服务端
实时性:客户端可以读取到zk服务端的最新数据
二、基础问题
1、znode相关概念
引用方式:通过路径引用,路径必须是唯一的、绝对的。/zookeeper用以保存管理信息
结构:即是目录,可以作为路径标识的一部分,也是文件,可以存储数据。最多存储1M数据
由3部分组成:stat–状态信息,描述znode版本权限等信息;data–与该znode关联的数据;children–该znode下的子节点
操作具有原子性。读获取阶段所有相关数据,写替换掉节点所有数据。
每个节点拥有自己的ACL(访问控制列表)这个列表规定了用户的权限
客户端可以在节点上设置watch。节点在进行增删改将会触发watch所对应的操作。当watch被触发,zk会向客户端发送且仅发送一条通知
版本号:对节点的每一个操作都会使者节点的版本号增加。每个节点维护三个版本号:version:节点数据版本号;cversion:子节点版本号;aversion:节点所拥有的ACL版本号
每个对节点的改变都将产生一个唯一的Zxid,这个时间戳全局有序
znode节点属性:https://images0.cnblogs.com/blog/671563/201411/301534569026625.png
2、节点类型
PERSISTENT:持久化目录节点,这个目录节点存储的数据不会丢失;
PERSISTENT_SEQUENTIAL:顺序自动编号的目录节点,这种目录节点会根据当前已近存在的节点数自动加 1,然后返回给客户端已经成功创建的目录节点名;
EPHEMERAL:临时目录节点,一旦创建这个节点的客户端与服务器端口也就是 session 超时,这种节点会被自动删除;
EPHEMERAL_SEQUENTIAL:临时自动编号节点。监控节点变化时,可以监控一个节点的变化,也可以监控一个节点所有子节点的变化。
三、基本数据模型
类似linux的文件目录
每一个节点都称为znode,可以有子节点,也可以有数据
每个节点分为临时节点和永久节点,临时节点在客户端断开后消失
每个zk节点都有各自的版本号,可以通过命令行来显示节点信息
每当节点数据发生变化,那么改节点的版本号会累加(乐观锁)
删除/修改过时节点,版本号不匹配则会报错
每个zk节点存储的数据不宜过大,几k即可(官方推荐)
节点可以设置权限ACL,可以通过权限来限制用户的访问
四、zk数据结构的特点
每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1;
znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录;
znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据;
znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了;
znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2;
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的。
四、应用问题 https://www.cnblogs.com/crazylqy/p/7131881.html
1、zookeeper的典型应用场景
数据的发布订阅
统一命名服务
分布通知、协调
分布式锁
集群管理
队列管理
2、数据的发布订阅
什么是发布订阅?
发布订阅即所谓的配置管理。将数据放在zk的节点上,供订阅者动态获取数据,配置变更时通知到集群的每一台机器。实现配置
的集中管理和动态更新,例如全局配置信息、地址列表等。
应用场景?
① 索引信息和集群中机器节点状态存放在ZK的一些指定节点,供各个客户端订阅使用。
② 系统日志(经过处理后的)存储,这些日志通常2-3天后被清除。
③ 应用中用到的一些配置信息集中管理,在应用启动的时候主动来获取一次,并且在节点上注册一个Watcher,以后每
次配置有更新,实时通知到应用,获取最新配置信息。(应用配置分为启动加载和动态加载,有写配置信息需要重启应用生效)
④ 业务逻辑中需要用到的一些全局变量,比如一些消息中间件的消息队列通常有个offset,这个offset存放在zk上,这样集群中每个
发送者都能知道当前的发送进度。
⑤ 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息。以前通常是暴露出接口,例如JMX接口,有了ZK后,只
要将这些信息存放到ZK节点上即可。
具体应用
Zookeeper很容易实现这种集中式的配置管理,比如将所需要的配置信息放到/Configuration 节点上,集群中所有机器一启动就
会通过Client对/Configuration这个节点进行监控【zk.exist(“/Configuration″,true)】,并且实现Watcher回调方法
process(),那么在zookeeper上/Configuration节点下数据发生变化的时候,每个机器都会收到通知,Watcher回调方法将会
被执行,那么应用再取下数据即可【zk.getData(”/Configuration″,false,null)】。
3、统一命名服务
什么是统一命名服务?
通过zk的树状结构,生成一个有层次的、唯一的、绝对的路径,用来标识zk的节点
应用场景?
通过调用zk创建节点的api,很容易创建一个全局唯一的路径,这个路径可以称为一个名称。被命名的服务通常是集群中的机器,
提供的服务地址,进程对象等。其中较为常见的就是一些分布式服务框架中的服务地址列表
应用举例?
dubbo使用zk作为其命名服务。
在Dubbo实现中: 服务提供者在启动的时候,向ZK上的指定节点/dubbo/ s e r v i c e N a m e / p r o v i d e r s 目 录 下 写 入 自 己 的 U R L 地 址 , 这 个 操 作 就 完 成 了 服 务 的 发 布 。 服 务 消 费 者 启 动 的 时 候 , 订 阅 / d u b b o / {serviceName}/providers目录下写入自己的URL地 址,这个操作就完成了服务的发布。 服务消费者启 动的时候,订阅/dubbo/ serviceName/providersURL/dubbo/{serviceName}/providers目录下的提供者URL地
址, 并向/dubbo/ s e r v i c e N a m e / c o n s u m e r s 目 录 下 写 入 自 己 的 U R L 地 址 。 注 意 , 所 有 向 Z K 上 注 册 的 地 址 都 是 临 时 节 点 , 这 样 就 能 够 保 证 服 务 提 供 者 和 消 费 者 能 够 自 动 感 应 资 源 的 变 化 。 另 外 , D u b b o 还 有 针 对 服 务 粒 度 的 监 控 , 方 法 是 订 阅 / d u b b o / {serviceName} /consumers目录下写入自己的URL地址。 注意,所有向ZK上注册的地址都是临时节点,这 样就能够保证服务提供者和消费者能够自动感应资源的变化。 另外,Dubbo还有针对服务粒度的监控,方法是订 阅/dubbo/ serviceName/consumersURLZKDubbo/dubbo/{serviceName}目录下所有提供者和消费者的信息。
4、分布通知、协调
什么是分布通知、协调?
zk中特有的watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统的通知与协调,实现对数据变更的实时处理。使
用方法通常是不同系统都对zk上同一个znode进行注册,监听znode变化(znode本身以及子节点),其中一个系统对znode做了
变更,其他系统就可以收到通知,然后做响应处理
应用?
① 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过ZK上某个节点关联,大大减少系统耦合。
② 另一种系统调度模式:某系统由控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在
控制台作的一些操作,实际上是修改了ZK上某些节点的状态,而ZK就把这些变化通知给他们注册Watcher的客户端,即推送系统,
于是,作出相应的推送任务。
③ 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到ZK来注册一个临时节点,并且定时将自己的进度进行汇报
(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。
总之,使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。
5、分布式锁
工具类:Apache的开源库Curator,它是一个ZooKeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,acquire
方法用于获取锁,release方法用于释放锁
什么是分布式锁
分布式锁是控制分布式系统之间同步访问共享资源的一种方式。分布式系统中,如果不同系统或者同一个系统的不同集群节点之间
共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰,保持一致性,这种情况就会用到分布式锁
分布式锁种类
保持独占:所有试图获取这把锁的客户端,最终只有一个能获取到锁。通常的做法是把zk上的一个子节点看成是一把锁,所有客
户端都去创建/distribute_lock节点,最终成功创建的客户端拥有了这把锁
控制时序:所有试图获取锁的客户端,最终都会按照全局时序安排执行。做法为/distribute_lock这个节点预先存在,所有客户端
在该节点下创建临时有序子节点,同时父节点维护一份sequence,保证子节点创建的时序行,从而也行程了每个客户端的全局时
序。
分布式锁应用
(1)创建一个目录mylock;
(2)线程A想获取锁就在mylock目录下创建临时顺序节点;
(3)获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁;
(4)线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点;
(5)线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。

6、集群管理
什么是分布式集群管理
在分布式集群环境下,我们需要实时的监控到集群中的机器数量,机器上下线情况,机器运行时状态等信息,此时我们可以通过
zk来实现分布式环境的集群管理
集群管理的实现方式
1)集群机器监控:实时获取集群的信息
首先,如果要对集群进行监控,需要有一个监控中心,监控中心对zk指定节点进行监听,如/test
集群部署时,优先部署Agent(可以理解为机器管理工具),部署后,向zk进行注册,具体做法就是在zk指定节点下创建临时子节
点,如/test/[hostname]。此时,对/test进行watch监听的监控中心会接收到子节点的上下线情况,以及获取到当前机器数量以及
ip列表等。
集群机器状态监控:agent定时将主运行的状态信息写入到[hostname]节点,监控中心通过订阅这些数据节点来间接获取主机运行
时的状态
7、队列管理
zk可以处理的队列类型
同步队列:队列中所有成员都聚齐的时候,队列才可用
FIFO队列:先进先出
同步队列用 Zookeeper 实现的实现思路如下:
创建一个父目录 /synchronizing,每个成员都监控标志(Set Watch)位目录 /synchronizing/start 是否存在,然后每个成员都
加入这个队列,加入队列的方式就是创建 /synchronizing/member_i 的临时目录节点,然后每个成员获取 / synchronizing 目录
的所有目录节点,也就是 member_i。判断 i 的值是否已经是成员的个数,如果小于成员个数等待 /synchronizing/start 的出
现,如果已经相等就创建 /synchronizing/start。
FIFO 队列用 Zookeeper 实现思路如下:
实现的思路也非常简单,就是在特定的目录下创建 SEQUENTIAL 类型的子目录 /queue_i,这样就能保证所有成员加入队列时都是
有编号的,出队列时通过 getChildren( ) 方法可以返回当前所有的队列中的元素,然后消费其中最小的一个,这样就能保证
FIFO。
8、zk负载均衡算法
(跟Dubbo的负载均衡算法类似,可以参考:Dubbo学习(二) Dubbo 集群容错模式-负载均衡模式)
一般来说负载均衡设备都会默认支持多种负载均衡分发策略,例如:
Ø 轮询(RoundRobin)将请求顺序循环地发到每个服务器。当其中某个服务器发生故障,AX就把其从顺序循环队列中拿出,不参加下一次的轮询,直到其恢复正常。
Ø 比率(Ratio):给每个服务器分配一个加权值为比例,根椐这个比例,把用户的请求分配到每个服务器。当其中某个服务器发生故障,AX就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。
Ø 优先权(Priority):给所有服务器分组,给每个组定义优先权,将用户的请求分配给优先级最高的服务器组(在同一组内,采用预先设定的轮询或比率算法,分配用户的请求);当最高优先级中所有服务器或者指定数量的服务器出现故障,AX将把请求送给次优先级的服务器组。这种方式,实际为用户提供一种热备份的方式。
Ø 最少连接数(LeastConnection):AX会记录当前每台服务器或者服务端口上的连接数,新的连接将传递给连接数最少的服务器。当其中某个服务器发生故障,AX就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。
Ø 最快响应时间(Fast Reponse time):新的连接传递给那些响应最快的服务器。当其中某个服务器发生故障,AX就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。
以上为通用的负载均衡算法,还有一些算法根据不同的需求也可能会用到,例如:
Ø 哈希算法( hash): 将客户端的源地址,端口进行哈希运算,根据运算的结果转发给一台服务器进行处理,当其中某个服务器发生故障,就把其从服务器队列中拿出,不参加下一次的用户请求的分配,直到其恢复正常。
Ø 基于策略的负载均衡:针对不同的数据流设置导向规则,用户可自行编辑流量分配策略,利用这些策略对通过的数据流实施导向控制。
Ø 基于数据包的内容分发:例如判断HTTP的URL,如果URL中带有.jpg的扩展名,就把数据包转发到指定的服务器。
继续看图分析,第二个用户207.17.117.21也访问www.a10networks.com,负载均衡设备根据负载均衡算法将第二个用户的请求转发到第二台服务器来处理。

9、zk选举机制
zk选举机制(1)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值