很遗憾,没有一篇文章能讲清楚ZooKeeper
计算会话下次的过期时间 每当客户端连接上服务器都会做激活操作,同时每隔一段时间客户端会向服务器发送心跳检测。 服务器收到激活或者心跳检测以后,会重新计算会话过期时间,根据“分桶策略”进行重新调整。把会话从“老的区块“放到”新的区块“中去。 重新计算过期时间并且调整“分桶策略” 对于超时的会话,SessionTracker 也会做如下清理工作: 标记会话状态为“已关闭”,也就是设置 isClosing 为 True。 发起“会话关闭”的请求,让关闭操作在整个集群生效。 收集需要清理的临时节点。 添加“节点删除”的事务变更。 删除临时节点 移除会话 关闭客户端与服务端的连接 会话关闭以后客户端就无法从服务端获取/写入数据了。 服务群组(Leader,Follower,Observer) 前面提到了客户端如何通过会话与服务端保持联系,以及服务端是如何管理客户端会话(Session)的。 我们继续思考一下,这么多的服务端都依赖一个 ZooKeeper 服务器。一旦服务挂了,客户端就无法工作了。 为了提高 ZooKeeper 服务的可靠性,引入服务器集群的概念。从原来的单个服务器,扩充成多个服务器,即使某一台服务器挂了,其他的服务器也可以顶上来。 ZooKeeper 的服务器集群 这样看起来不错了,新的问题是,存在多个 ZooKeeper 服务器,那么客户端的请求发给哪台呢?服务器之间如何同步数据呢?如果一个服务挂掉了其他的服务器如何替代?这里介绍两个概念 Leader 和 Follower。 Leader 服务器,是事务请求(写操作)的唯一调度者和处理者,保证集群事务处理的顺序性。也是集群内部服务器的调度者。 它是整个集群的老大,其他的服务器接到事务请求都会转交给它,让它协调处理。 Follower 服务器,处理非事务请求(读操作),转发事务请求给 Leader 服务器。参与选举 Leader 的投票和事务请求 Proposal 的投票。 既然 Leader 是集群的老大,那么这个老大是如何产生的。ZooKeeper 有仲裁机制,通过服务器的选举产生这个 Leader,按照少数服从多数的原则。 因此,集群中服务器的个数一般都是奇数,例如:1,3,5。当然这里是建议。关于选举和仲裁都有一定的算法,一起来看看吧。 当众多服务器启动的时候,互相都不知道谁是 Leader,因此都会进入 Looking 状态,也就是在网络中寻找 Leader。 寻找的过程也是投票的过程,每个服务器会将服务器 ID 和事务 ID 作为投票信息发送给网络中其他的服务器。假设称它为投票信息 VOTE,它包括:(ServerID,ZXID)。 其中,ServerID 是服务器注册的 ID,随着服务器启动的顺序自动增加,后启动的服务器 ServerID 就大;ZXID 是服务器处理事物的 ID,随着事物的增加自动增加,同样后提交的事务 ZXID 也大一些。 其他的服务器收到 VOTE 信息以后会和自己的 VOTE 信息(ServerID,ZXID)进行比较。 如果收到的 VOTE(ServerID,ZXID)中的 ZXID 比自己的 ZXID 要大,那么把自己的 VOTE 修改成收到的 VOTE。 如果 ZXID 一样大,那么就比较 ServerID,将大的那个 ServerID 作为自己 VOTE 的 ServerID,转发给其他服务器。 再简单点说,如果事务 ID(ZXID)比自己的事务 ID(ZXID)要大,就把票投给这个服务器。如果事务 ID 一样,就把票投给 ServerID 大的服务器。 来个具体的例子,有三个服务器,他们的投票值分别是: S1 (1,6) S2 (2,5) S3 (3,5) 三个服务器分别把自己的 VOTE 发给其他两台服务器,S2 和 S3 收到 VOTE 以后发现 ZXID 为 6 的来自 S1 的 VOTE 比自己持有的 ZXID 要大,因此把自己的 VOTE 修改为(1,6)投出去,因此 S1 称为 Leader。 Leader 选举实例 同样,如果 S1 作为 Leader,因为某种原因挂掉或者长时间没有响应请求,其他的服务器也会进入 Looking 状态,开启投票仲裁模式寻找下一个 Leader。 成为新 Leader 以后会通过广播的方式将 ZNode 上的数据同步到其他的 Follower。 Leader 有了,整个服务器集群有了领袖,它可以处理客户端的事物请求。客户端的请求可以发给集群中任意一台服务器,无论是哪个服务器都会将事物请求转交给 Leader。 Leader 在将数据写入 ZNode 之前会向 ZooKeeper 的其他 Follower 进行广播。 这里广播用到了 ZAB 协议(Atomic Broadcast Protocol)是 Paxos 协议的实践。说白了就是一个两段提交。 PS:对分布式事务比较了解的同学应该知道两段提交和三段提交。 这里 ZooKeeper 通过以下方式实现两段提交: Leader 向所有 Follower 发送一个 PROPOSAL。 当 Follower 接收到 PROPOSAL 后,返回给 Leader 一个 ACK 消息,表示我收到 PROPOSAL,并且准备好了。 Leader 仲裁数量(过半数)的 Follower 发送的 ACK 后(包括 Leader 自己),会发送消息通知 Follower 进行 COMMIT。 收到 COMMIT 以后,Follower 就开始干活,将数据写入到 ZNode 中。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |