ZooKeeper相关原理

‌**ZooKeeper(zk)服务端与客户端的关系是通过TCP长连接建立的,这种连接保证了ZooKeeper服务端与客户端之间的通信和Watch事件的通知。**‌

ZooKeeper是一个开源的分布式协调服务框架,它为分布式系统提供一致性服务。在ZooKeeper中,客户端通过TCP长连接连接到服务集群,这种连接从客户端第一次连接到服务端开始建立,并通过心跳检测机制来保持有效的会话状态。通过这个连接,客户端可以发送请求并接收响应,同时也可以接收到Watch事件的通知。这种连接机制确保了ZooKeeper服务端与客户端之间的紧密联系和高效的通信‌1。

此外,ZooKeeper的服务端与客户端之间的通信还涉及到一些关键概念,如会话(Session)超时时间(SessionTimeOut)。会话是指客户端会话,是客户端连接服务端的一个TCP长连接。服务端的Watch事件通知也是通过该TCP连接进行的。会话从第一次连接开始就已经建立,之后通过心跳检测机制来保持有效的会话状态。超时时间的设置是为了在网络故障或客户端主动断开等情况下,只要在会话超时时间之内重新建立连接,则之前创建的会话依然有效‌。

综上所述,ZooKeeper服务端与客户端的关系是通过TCP长连接建立的,这种连接机制保证了服务端与客户端之间的高效通信和Watch事件的通知,是ZooKeeper实现其分布式协调服务功能的基础‌

ZAB协议(Atomic Broadcast 原子广播协议)

1 崩溃可恢复的

当服务框架启动或者Leader崩溃,网络中断或者重启,我们会选举新的Leader,当超过半数follower与Leader数据同步完成之后(保证数据状态一致)。此时恢复完成,退出恢复模式。

2 原子消息广播算法

核心原理(数据同步机制):leader将我们应用服务器的请求转换成一个事务Proposal,并且广播到集群中所有的Follower当中只要有超过半数(n/2+1)的Follower 进行了正确的反馈之后,Leader会再次向所有的Follower分发Commit消息,要求其将前一个事务提交。

基于TCP协议,可以保证消息发送与接收的顺序性。

  • 事务ID:ZXID,单调递增的唯一ID,在Leader广播事务之前会进行创建。

  • 64位的数字

    • 低32位,应用服务器每产生一次事务请求,就+1

    • 高32位代表Leader的周期编号,每选举一个Leader,会从其中找出其本地日志中最大的ZXID,取高32位然后就+1;重新选举之后,低32位清零

  • 保证了当前Leader不会以之前的Leader的ZXID,去提交与之前Leader ZXID 不同的事务请求的。如 Leader1提交了 ZXID1, 此时Leader1挂了,选举出Leader2,Leader2也不会使用ZXID1去提交新的事务

  • 选举算法:Leader不可用,从其他Follower选举出 ZXID最大的机器作为Leader,他已经具有所有最新的事务提案。

Leader选举

选举算法中的zxid是从内存数据库中取的最新事务id ,事务操作是分两阶段的(提出阶段和提交阶段)

  1. 提交阶段:leader生成提议并广播给followers , follower收到提议后先将事务**写到本地事务日志**,然后反馈ACK
  2. 提交阶段:leader收到半数以上的ACK后,再**广播commit消息**,同时将事务操作应用到内存中。

可见,选主只是选出了内存数据是最新的节点,仅仅靠这个是无法保证已经在leader服务器上提交的事务最终被所有服务器都提交。

比如leader发起提议P1,并收到半数以上follower关于P1的ACK后,在广播commit消息之前宕机了,选举产生的新leader之前是follower,未收到关于P1的commit消息,内存中是没有P1的数据。

而ZAB协议的设计是需要保证选出leader后,P1是需要应用到集群中的 。这块的逻辑是通过选举后的数据同步来弥补。

zookeeper分布式锁

- 独占锁:

  • 创建锁:在zk上**创建一个临时节点**/exclusive_lock/lock,会保证同时只有一个一台服务器能够创建成功

  • 其他没有获取的服务器会就需要到/exclusive_lock上**注册一个子节点变更的Watcher(时间通知机制)**。

  • 释放锁:

  • 1 执行完正常业务之后

  • 2 创建临时节点的服务器发生宕机

- 共享锁

  • 创建锁:只能读不能写、写完只能在共享锁结束。 多个客户端请求共享锁都会创建一个**节点序号**

  • 读请求:先来的序列号小,如果前面序列号都是读请求,那么同步执行读操作

  • 如果前面序号有写请求,则需要等待

  • 写请求:如果自己是最小的序列号,则执行

应用场景

数据发布与订阅

zk采用的时候推拉结合的方式 :应用服务器想zk注册自己需要关注的节点,一旦节点数据发生变更,zk会主动的向应用服务器发送Watcher事件通知,应用服务器接受到这个消息之后,主动向zk拉取对应的最新的配置

Watcher事件通知:客户点可以在服务端创建一个Watcher事件监听,监听节点的变化:节点被创建,删除,数据更新,都会通知到客户端。

  • 这里的客户端可以指比如:我们的开发服务端,zkCli.sh进行测试
  • Watcher注册是一次性的,每次触发之后都需要重新进行注册

方法exists可以监听节点是否存在,然后做一项负载均衡的事情

配置可以是:机器列表,运行时开关配置,数据库配置信息等

负载均衡

心跳检测,自动移除节点

当服务器宕机,zookeeper因为没有检测到心跳,自动把该节点移除 ,并通知其他服务器,其他服务器得知该机器已宕机,在分配连接时,不会分配到这台机器上,这点也是标题说的在负载均衡中用到zookeeper的原因

命名服务

使用分布式全局唯一ID的分配机制,如 type-job-0000000003,可以来唯一标识一个API接口

分布式协调/通知

zk中特有的Watcher注册与异步通知机制,能够很好的实现分布式系统下的不同机器的,不同系统的协调与通知

  • 实现对数据变更 的**实时处理**

  • 实现的方式:**所有的应用服务器都会在zk上同一个数据节点注册一个监听器Watcher**,

如果数据发生变动之后,zk会主动告知所有监听的服务器有数据变更,他们就会主动拉取这种变更。

Zookeeper 集群节点为什么要部署成奇数

超过半数 quorum=(n/2+1)

1个:quorum = 1

2个:quorum = 2

如果有2个zookeeper,那么只要有1个死了zookeeper就不能用了,因为1没有过半,所以

2个zookeeper的死亡容忍度为0;一个就完全别想!!!避免单点问题哦。

所有说最少是3个节点适宜。

3->1;三个zookeeper,最多1个zookeeper可以不可用(2个超过3个的半数)。 4->1;四个zookeeper,最多1个zookeeper可以不可用(3个超过4个的半数)。 5->2;五个zookeeper,最多2个zookeeper可以不可用。 6->2;两个zookeeper,最多0个zookeeper可以不可用。

结论

会发现一个规律,2n和2n-1的容忍度是一样的,都是n-1,所以为了更加高效,何必增加那一个不必要的zookeeper呢。

zookeeper的选举策略也是需要半数以上的节点同意才能当选leader,如果是偶数节点可能导致票数相同的情况。

选举算法细节

重点:选举出zxid最大的节点即可,如果zxid相同的话,选举出sid 服务器id最大的节点。

相关推荐
SUGERBOOM6 分钟前
华为eNSP使用详解
网络·华为
洁洁!31 分钟前
【计算机网络】数据链路层深度解析
网络·网络协议·计算机网络
Aomnitrix3 小时前
网络协议全景:Linux环境下的TCP/IP、UDP
linux·运维·网络·c++·网络协议·tcp/ip·运维开发
哲伦贼稳妥3 小时前
网络运维故障处理
运维·网络·经验分享·职场和发展
bite_joker_xue3 小时前
HCIA--实验十六:ACL通信实验(2)
网络
物联网菜鸟3 小时前
linux网络编程1
网络
无衣同学9 小时前
HCIP--<OSPF2>
网络
awonw10 小时前
[网络][CISCO]CISCO IOS升级
网络·ios
Lill_bin10 小时前
Ribbon简介
分布式·后端·spring cloud·微服务·云原生·ribbon
snow@li11 小时前
AI问答-HTTP:理解 Content-Disposition
网络·网络协议·http