Zookeeper 集群角色、原理

Zookeeper 的集群角色

集群中的 server 分为三种角色:leader, follower, observerhtml

file

  • 其中observer是配置zoo.cfg明肯定义的,角色leader 在一个zookeeper集群中有且只能有一个,是经过内部的选举机制临时产生的。
  • leader 是集群中最重要的角色。负责响应集群的全部对Zookeeper数据状态变动的请求。它会将每一个状态更新请求进行顺序管理,以便保证整个集群内部消息处理的 FIFO,遵循了顺序一致性(Sequential Consistency)。
    • leader 内部维护 session ,来自客户端的链接和断开链接,都会被统一followerobserver 转发给leader处理。
    • leader 内部维护单调递增的 Zxid(ZooKeeper Transaction Id),针对客户端链接,断开链接,节点的写操做都会分配一个全局惟一的Zxid,同时这些操做是原子性的,而且是严格顺序性的,遵循ZAB原子广播一致性协议完成事务(transaction)操做。若是客户端的全部写操做,都会被 follower 统一转发给leader处理。
  • follower 具备选举权。负责提供给客户端读写服务,须要响应leader的提议
  • observer 没有选举权。主要提供给客户端读服务,不提供写服务,也不须要响应leader的提议。也不须要日志文件,由于没有写服务,没有持久化的须要。
Server状态
  • LOOKING,竞选状态。
  • FOLLOWING,随从状态,同步leader状态,参与投票决策提案。
  • OBSERVING,观察状态,同步leader状态,不参与投票决策提案。
  • LEADING,领导者状态,发起正常消息的提案。

Zookeeper 的存储

zookeeper中的znode数据都是在内存中优先维护和提供读服务,当事务被提交以及最终提交都会持久化到磁盘的日志文件中。node

Zookeeper 的内部网络拓扑

Zookeeper 在内部网络中如何实现两两链接的?算法

file

这里暂且使用 10.0.2.30,10.0.2.31,10.0.2.32,10.0.2.33 替代 node1,node2,node3,node4,并依次启动 zookeeper。shell

  • zoo.cfg配置文件
server.1=10.0.2.30:2888:3888
server.2=10.0.2.31:2888:3888
server.3=10.0.2.32:2888:3888
server.4=10.0.2.33:2888:3888

依次使用 netstat 查看网络链接状况apache

  • node1

file

能够看出来 node1做为服务节点,由 node2,node3,node4 经过 3888端口创建链接进来。
node1 做为客户端链接 node3 (目前node3是leader) 的2888端口。编程

  • node2

file

能够看出来 node2做为服务节点,由 node3,node4 经过 3888端口创建链接进来。
可是 node2 做为客户端链接node1的3888端口。
node2 做为客户端链接 node3 (目前node3是leader) 的2888端口。数组

  • node3

file

能够看出来 node3做为服务节点,由 node4 经过 3888端口创建链接进来。
可是 node3 做为客户端链接node1,node2 的3888端口。
node3 做为leader节点,由 node1,node2 ,node4 经过 3888端口创建链接进来。
至于为何 node3能当选 leader 呢?能够在下面的 选举过程当中 获得进一步详细的阐述。服务器

  • node4

file

能够看出来 node4 做为客户端链接node1,node2 ,node3 的3888端口。
node4 做为客户端链接 node3 (目前node3是leader) 的2888端口。微信

  • 结论
    Zookeeper 在内部网络中如图所示,依据zoo.cfg的配置后续的server都逐个链接前面的server的3888端口,这样就造成了两两链接的拓扑,同时也不冗余。
    而当leader当选时,会开放2888端口,其余follower链接其2888端口。

ZAB(原子广播,Zookeeper Atomic Broadcast

https://zookeeper.apache.org/doc/current/zookeeperInternals.html网络

ZAB(Zookeeper Atomic Broadcast)原子广播是 Paxos分布式一致性协议算法(http://zh.wikipedia.org/zh-cn/Paxos) 的一个简化版本。

首先有如下概念,咱们须要了解:

  • 数据包(Packet):经过 FIFO Channel 发送的字节数组。
  • 提案(Proposal):协议的单位。经过与ZooKeeper中的法定server交换数据包来达成协议。大多数提案都包含消息,可是 NEW_LEADER Proposal 提案是不包含消息。
  • 消息(Message):要自动广播到全部ZooKeeper服务器的字节数组。消息被包含在一个提案(Proposal)中,而且只有在提案(Proposal)被经过后消息才会最终交付delivered(提交到事务日志和更新内存的统一视图)。
  • 法定人员 (Quorum):有 Zookeeper集群中非observer 角色的全部服务器节点组成,具备投票经过提案(Proposal)的权力。

在 Zookeeper 中提供如下的保证数据的严格顺序:

  • 传递可靠性:若是一个消息被一个server最终交付delivered,那么这个消息最终也被其余全部的server最终交付delivered,这里指最终一致性。
  • 顺序全局性:若是一个消息a先于b被一个server最终交付delivered,那么消息a也是先于b被其余全部的server最终交付delivered
  • 顺序传递性:若是消息a先于b被发送到server,消息b先于c被发送到server,那么消息a也是先于c被server接收的。

如上所述,ZooKeeper保证消息的总顺序,也保证建议的总顺序。

ZooKeeper使用ZooKeeper transaction id (zxid) ,这是一个全局的惟一的ID。提出提案(Proposal)时,全部提案都将附上zxid,进而保证全局的顺序性。

  • leader 将提案(Proposal)将发送到全部ZooKeeper服务器。

  • 在法定人员(Quorum)收到后,会确认(acknowledge)回复这个提案(Proposal)给leader

其中确认acknowledge提案(Proposal)表示服务器已将提案(Proposal)持久化到日志中。

稍微注意一下:法定人员(Quorum)收到提案(Proposal),只存在确认(acknowledge),或者由于网络等缘由超时响应,不存在反对(reject)。

  • 只要一但知足半数以上(大于全部法定人员的一半)确认acknowledge后,leader就会进入正式提交(Commit)。

  • 若是提案(Proposal)中包含一条消息,则在提交时将最终交付delivered该消息。

ZooKeeper消息传递包括两个阶段:

  • leader选举(Leader activation):在此阶段,leader被选举出来,集群开始变为对外可用状态,并准备开始提出提案(Proposal)。
  • 活动消息传递(Active messaging):在此阶段,leader开始接受消息(Message),并发起提案(Proposal),协调和决策以提交(Commit)提案(Proposal)。

leader选举

leader产生的条件:

  • 具备最新的 Zxid,若是 存在多个server都有最新的Zxid,在投票过程当中选取创建网络链接中 myid最大的。
  • leader 和其链接的follower的个数必须知足半数以上(大于全部法定人员的一半)。

file

当集群中任意具备选举权的server发现leader挂了:

  • 该 server 会触发NEW_LEADER Proposal 提案,给本身投票,并经过 ZAB 广播给全部链接的 server。
  • 接受到 NEW_LEADER Proposal 提案的server,若是有被选举权,则会触发它的投票行为:
    • 先比较zxid,最新的胜出,若是zxid相同,再比较myid,最大的胜出。
    • 最后将胜出的内容,经过 ZAB 广播给全部链接的 server。
  • 最终知足leader条件的server,将被选出,同时 follower也被广播得到 Proposal 的提交。

以上中的 网络拓扑 为何 node3能当选 leader 呢?

  • node1 启动时,给本身投票,由于其余server尚没启动,由于 node1 依然在LOOKING竞选状态。
  • node2 启动完,给本身投票,同时与 node1 交换了Zxid和myid,node2 胜出,但由于没有达到半数以上法定人员,因此node1,node2 依然处于LOOKING竞选状态。
  • node3 启动完,给本身投票,同时与 node1 ,node2 交换了Zxid和myid,node3 胜出,也达到半数以上法定人员(3 > 4/2),所以 node3 被选举为 leader
  • node4 启动完,给本身投票,同时与 node1 ,node2 ,node3交换了Zxid和myid,node3的Zxid最新,所以 node4 追随 node3。

活动消息传递

消息的传递通常指写请求。

file

  • follower 接收到 客户端的 写请求后,会转发给 leader顺序处理。
  • leader 收到写请求,会检查数据问题,如无问题,建立一个新的提案proposal加入toBeApplied FIFO 队列,内容是写请求的消息,并附上全局的ZXid。
  • leader每次toBeApplied FIFO 队列头部取到一个提案proposal,经过 ZAB 广播给全部的 follower,处于 pending 等待回复。
  • follower 收到提案proposal后,记录提案proposal持久化到磁盘的日志文件中,而后确认(acknowledge)回复这个提案(Proposal)给leader
  • leader处于 pending 等待回复,一旦收到follower 加上本身的确认(acknowledge)超过半数法定人员(Quorum),就会触发 Commit阶段,发送commit请求给全部的follower,发送info请求全部的observer
    同时,leader将提案proposal放入 committedRequest 队列,并从toBeApplied FIFO 队列移出该 提案proposal
  • follower 收到 Commit后,会更新本身的内存数据,统一数据视图。
  • observer收到info后,会更新本身的内存数据,统一数据视图。

file

针对客户端的读请求,则不须要转发给leader处理。
固然若是是客户端的sync命令,则会触发客户端链接的followerobserverleader请求同步数据状态。

@SvenAugustus(https://www.flysium.xyz/)
更多请关注微信公众号【编程不离宗】,专一于分享服务器开发与编程相关的技术干货:

相关文章
相关标签/搜索