中间件知识点(Zookeeper)

Zookeeper

什么是Zookeeper?(解决分布式集群中节点数据一致性问题的分布式协调框架)
解决分布式集群中节点数据一致性问题的分布式协调框架。
ZooKeeper本质上是一个分布式的小文件存储系统(Zookeeper=文件系统+监听机制)。
Zookeeper从设计模式角度来理解:是一个基于观察者模式设计的分布式服务管理框架。
总结:采用类似于文件系统的目录树方式进行节点数据存储,基于观察者模式,监听数据变更。从而进行集群管理、统一命名服务、分布式配置管理、分布式消息队列、分布式锁、分布式协调。

zookeeper一般不用了,是比较旧的分布式协调框架。

CAP中的C表示一致性,一致性分为:
强一致性:又称线性一致性(linearizability )
1.任意时刻,所有节点中的数据是一样的,
2.一个集群需要对外部提供强一致性,所以只要集群内部某一台服务器的数据发生了改变,那么就需要等待集群内其他服务器的数据同步完成后,才能正常的对外提供服务
3.保证了强一致性,务必会损耗可用性
弱一致性:
1.系统中的某个数据被更新后,后续对该数据的读取操作可能得到更新后的值,也可能是更改前的值。
2.即使过了不一致时间窗口,后续的读取也不一定能保证一致。
最终一致性:
1.弱一致性的特殊形式,不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化
2.存储系统保证在没有新的更新的条件下,最终所有的访问都是最后更新的值
顺序一致性:
1.任何一次读都能读到某个数据的最近一次写的数据。
2.对其他节点之前的修改是可见(已同步)且确定的,并且新的写入建立在已经达成同步的基础上。

ZooKeeper does not guarantee that at every instance in time, two different clients will have identical views of ZooKeeper data. Due to factors like network delays, one client may perform an update before another client gets notified of the change. Consider the scenario of two clients, A and B. If client A sets the value of a znode /a from 0 to 1, then tells client B to read /a, client B may read the old value of 0。
https://zookeeper.apache.org/doc/r3.1.2/zookeeperProgrammers.html
zookeeper能保证读到的数据是读的节点的最新数据,但不能保证读到的数据是所以最新的数据。

zookeeper是强一致性(绝对一致性)还是最终一致性?
Zookeeper写入是强一致性(ZAB协议),读取是顺序一致性。所以zookeeper既不能说是强一致性也不能说是最终一致性,应该分开讲。强一致性体现在写数据的时候只有当大多数服务器都成功写入数据后,更新操作才会被认为是成功的。这种机制称为数据的强一致性(而不是等所有服务器都成功写入才叫强一致性)。而顺序一致性是体现在读取数据的时候,因为强一致性意思是只要大多数节点写入就算成功写入,这样就可能某些节点的数据来不及写入,就被读了,这样就相当于读到的信息不算是所有节点中最新的,但是它却是该节点中最新的数据,这就体现了顺序一致性。
不管是强一致性还是最终一致性,都是一致性,都是C。

ZooKeeper数据结构(类似文件系统的树型结构)
ZooKeeper的数据模型是层次模型,层次模型常见于文件系统。层次模型和key-value模型是两种主流的数据模型。ZooKeeper使用文件系统模型主要基于以下两点考虑:

  1. 文件系统的树形结构便于表达数据之间的层次关系
  2. 文件系统的树形结构便于为不同的应用分配独立的命名空间( namespace )
    ZooKeeper的层次模型称作Data Tree,Data Tree的每个节点叫作Znode。不同于文件系统,每个节点都可以保存数据,每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode都可以通过其路径唯一标识,每个节点都有一个版本(version),版本从0开始计数。
    一个znode可以使持久性的,也可以是临时性的
    临时节点+监听机制可以用于实现分布式锁

Zookeeper 节点特性总结

  1. 同一级节点 key 名称是唯一的
    已存在/lock节点,再次创建会提示已经存在
    2.创建节点时,必须要带上全路径
    3.session 关闭,临时节点清除
    4.自动创建顺序节点(即创建的znode的名字是按顺序的)
    5.watch 机制,监听节点变化
    监听事件被单次触发后,事件就失效了。
    6.delete 命令只能一层一层删除。提示:新版本可以通过 deleteall 命令递归删除。

利用 ZooKeeper 顺序节点的特性,制作分布式的序列号生成器,或者叫 id 生成器。(分
布式环境下使用作为数据库 id,另外一种是 UUID(缺点:没有规律)),ZooKeeper 可
以生成有顺序的容易理解的同时支持分布式环境的编号。

监听通知(watcher)机制:
(3.6.0版本之前watch事件是一次性的,3.6.0版本开始watch事件变为了永久性)
一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务器将这个改变发送给设置了Watch的客户端,以便通知它们。
Zookeeper采用了 Watcher机制实现数据的发布订阅功能,多个订阅者可同时监听某一特定主题对象,当该主题对象的自身状态发生变化时例如节点内容改变、节点下的子节点列表改变等,会实时、主动通知所有订阅者。
watcher机制事件上与观察者模式类似,也可看作是一种观察者模式在分布式场景下的实现方式。
watcher的过程:

  1. 客户端向服务端注册watcher
  2. 服务端事件发生触发watcher
  3. 客户端回调watcher得到触发事件情况
    注意:Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发送才会触发监听,通知给客户端。
    Zookeeper 3.6.0版本开始增加了永久性watch,在事件被触发之后,仍然保留,可以继续监听ZNode上的变更。

zookeeper应用场景:
ZooKeeper适用于存储和协同相关的关键数据,不适合用于大数据量存储。
有了上述众多节点特性,使得 zookeeper 能开发不出不同的经典应用场景,比如:
1.注册中心
2.数据发布/订阅(常用于实现配置中心)
ZooKeeper 采用的是推拉结合的方式。
推: 服务端会推给注册了监控节点的客户端 Watcher 事件通知
拉: 客户端获得通知后,然后主动到服务端拉取最新的数据
3.负载均衡
在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求
4.命名服务
在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。
例如:IP不容易记住,而域名容易记住。
利用 ZooKeeper 顺序节点的特性,制作分布式的序列号生成器,或者叫 id 生成器。(分布式环境下使用作为数据库 id,另外一种是 UUID(缺点:没有规律)),ZooKeeper 可以生成有顺序的容易理解的同时支持分布式环境的编号。
5.分布式协调/通知
6.集群管理
7.Master选举
8.分布式锁
9.分布式队列

上面讲的是zookeeper单机模式----
下面讲zookeeper集群模式—

Zookeeper集群
集群角色
Leader: 领导者
事务请求(写操作)的唯一调度者和处理者,保证集群事务处理的顺序性;集群内部各个服务器的调度者。对于create、setData、delete等有写操作的请求,则要统一转发给leader处理,leader需要决定编号、执行操作,这个过程称为事务。也可以处理非事务请求。
Follower: 跟随者
处理客户端非事务(读操作)请求(可以直接响应),转发事务请求给Leader;参与集群Leader选举投票。
Observer: 观察者
对于非事务请求可以独立处理(读操作),对于事务性请求会转发给leader处理。
Observer节点接收来自leader的inform信息,更新自己的本地存储,不参与提交和选举投票。通常在不影响集群事务处理能力的前提下提升集群的非事务处理能力。
Observer应用场景
1.提升集群的读性能。因为Observer不参与提交和选举的投票过程,所以可以通过往集群里面添加observer节点来提高整个集群的读性能。
2.跨数据中心部署。 比如需要部署一个北京和香港两地都可以使用的zookeeper集群服务,并且要求北京和香港客户的读请求延迟都很低。解决方案就是把香港的节点都设置为observer。

集群架构
在这里插入图片描述
leader节点可以处理读写请求,follower只可以处理读请求。follower在接到写请求时会把写请求转发给leader来处理。
observer只可以处理读请求,不参与选举
写操作为事务操作,读操作不是事务操作。
leader、follower都可以参与选举。observer不参与选举。
写操作、读操作,其实是读写的啥?
其实就是节点注册、读取

Zookeeper数据一致性保证
1.全局可线性化(Linearizable )写入∶先到达leader的写请求会被先处理,leader决定写请求的执行顺序。
2.客户端FIFO顺序∶来自给定客户端的请求按照发送顺序执行。

Zookeeper集群Leader 选举相关数据
1.参数:
服务器 ID(myid):编号越大在选举算法中权重越大
事务 ID(zxid):值越大说明数据越新,权重越大
逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加
2.选举状态(即当前节点所处的状态是什么):
LOOKING: 竞选状态
FOLLOWING: 随从状态,同步 leader 状态,参与投票
OBSERVING: 观察状态,同步 leader 状态,不参与投票
LEADING: 领导者状态

Zookeeper集群Leader 选举原理
zookeeper 的 leader 选举存在两个阶段,一个是服务器启动时 leader 选举,另一个是运
行过程中 leader 服务器宕机。

服务器 ID(myid):编号越大在选举算法中权重越大
事务 ID(zxid):值越大说明数据越新,权重越大
逻辑时钟(epoch-logicalclock):同一轮投票过程中的逻辑时钟值是相同的,每投完一次值会增加

投票对比规则
针对每一次投票,服务器都需要将其他服务器的投票和自己的投票进行对比,对比规则如下:
a. 优先比较 epoch
b. 检查 zxid,zxid 比较大的服务器优先作为 leader
c. 如果 zxid 相同,那么就比较 myid,myid 较大的服务器作为 leader 服务器

投票对比完后,开始统计投票:每次投票后,每个服务器统计其收到的所有投票信息,判断是否有过半机器接收到相同的投票信息。如果有,且过半的机器为自己则将自己服务器状态变为LEADING,否则为FOLLOWING。

服务器启动时的 leader 选举
略。
运行过程中的 leader 选举
1.leader宕机后,其他非Oberver服务器将自身服务器状态变更为LOOKING。
2.重新选举(流程和启动流程一致)

Zookeeper 数据同步流程(主要依赖 ZAB 协议来实现分布式数据一致性,即通过实现ZAB协议来实现分布式数据一致性,具体是消息广播(2pc)和崩溃恢复)
1.Zookeeper只通过Leader 来接收和处理客户端所有事务请求。
2.ZAB 协议分为两部分(消息广播和崩溃恢复)
a.消息广播(其实为2pc协议,先预处理,得到ack后再commit)
b.崩溃恢复(即消息广播过程中,leader出现崩溃)
具体崩溃场景:
Leader 服务器将消息 commit 发出后,立即崩溃
Leader 服务器刚提出 proposal 后,立即崩溃
解决策略:
选举 zxid 最大的节点作为新的 leader
新 leader 将事务日志中尚未提交的消息进行处理
3.旧leader崩溃后,旧不能再写数据,需要等到新leader选出来之后才能重新写,避免脑裂。

Zookeeper注册中心
略。

Zookeeper集群Leader选举源码剖析
zookeeper服务端和客户端是用什么通信?默认使用NIO。可配置为Netty。zookeeper新版本已推荐使用Netty。
服务端和服务端节点leader选举用ServerSocket即BIO进行通信。
启动选举服务器ServerSocket后,会通过使用发送和接收队列,并开启发送和接收线程,不断从队列中拿信息进行发送和接收投票信息。
节点1连上了节点2之后,节点2就无需再连接节点1了,因为连接是双向的。且设置了让myid大的节点来连接myid小的节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值