分布式理论与ZooKeeper相关概念
Posted oahaijgnahz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式理论与ZooKeeper相关概念相关的知识,希望对你有一定的参考价值。
分布式理论与ZooKeeper相关概念
文章目录
一、分布式系统与CAP、BASE理论
1.1 分布式系统和集群
分布式是指通过网络连接的多个组件,通过交换信息协作而形成的系统。而集群是指同一种组件的多个实例,形成的逻辑上的整体。
分布式系统也可以是一个集群,例子就是说的zookeeper(既是集群又是分布式系统),它的特征是服务之间会互相通信协作。
是分布式系统不是集群的情况,就是多个不同组件构成的系统。
是集群不是分布式系统的情况,比如多个经过负载均衡的HTTP服务器,它们之间不会互相通信,如果不带上负载均衡的部分的话,一般不叫做分布式系统。
来源于知乎用户 剑灵 的回答
而分布式事务就是指,事务的参与者、管理者、资源服务器等分别位于分布式系统的不同节点上,这就需要分布式一致性协议来实现分布式业务,后文会将介绍。
1.2 CAP理论
CAP是指一致性、可用性和分区容忍性。这个理论指出一个系统最多只能满足其中的两个。
要说的是,分布式系统就一定要有分区容错性,所以“P”是一定要选择的,那么就需要考虑在A和C中选择一个的问题了。像网站这样的架构,必须要保证可用性,可用性是网站对用户的基本保障,但也就损失了数据的一致性。而nosql数据库作为数据库要保证数据的一致性,那么选择了CP。
1.3 BASE理论
BASE理论是指基本可用(BA)、软状态(S)、最终一致性(E)。BASE理论的思想是放松CAP理论中的约束,比如分布式网站的架构放松某一时刻数据的一致性要求,来换取系统整体的伸缩性和性能上的改观,最终去实现数据的一致性。
二、分布式一致性协议
2.1 2PC和3PC
即两阶段提交和三阶段提交。但无论是二阶段提交还是三阶段提交都无法彻底解决分布式的一致性问题。Google Chubby的作者Mike Burrows说过:“ there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是Paxos算法的不完整版。所以直接介绍Paxos算法。
2.2 Paxos算法
Paxos算法的主要角色是:Proposer(提议者)、Accepter(决策者)、Learner(学习者)。
算法主要分为三步:
贿选:正如其名,多个Proposer向多个Accepter发送编(每个Proposer编号唯一),可以将每个角色看作一个线程,并发进行。Accepter只会响应编号更大的Proposer请求(贿赂,谁大就偏向谁的提案),对于目前偏向的提案编号更小的将忽略。只有获得多数Accepter响应(成为多数派)的Proposer能够进入下一阶段(由于并发的原因,Proposer编号小的提案先到达并成功贿选,然后编号大的Proposer到达也成功贿选,所以通常情况下会有多个Proposer会通过贿选)。
提议:提议时会有以下情况。第一种,ProposerA在第一阶段贿选后对应Accepter仍然保持最大编号,那么A就被Accepter定为主要Proposer(编号最大就先入为主);第二种,ProposerA在向某个Accepter提议时,发现其编号已经比自己大了,则需要重新贿选;第三种,ProposerA重新贿选时找到的Accepter发现其主要Proposer是B,那么ProposerA会将提议改为ProposerB(趋同)。这样最终会有一个Proposer提议过半,得到最终的提议。
获取提案:通过主Learner从Acceptor获得通过的提案,同步到其他Learner,为了防止单点故障,主Learner采用集合的方式。
整个过程:成为多数派,抢占提议,主要提议传染完成议案选举
三、ZAB——ZooKeeper的分布式一致性协议
ZAB,ZooKeeper原子消息广播协议,实现一种主备模式框架下集群中各个副本间数据一致性。
所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为leader服务器,而余下的其他服务器则成为follower服务器。leader服务器负责将一个客户端事务请求转换成一个事务proposal并分配一个全局单调递增的唯一ZXID(包含周期和计数信息),并将该proposal分发给集群中所有的follower服务器。之后leader服务器需要等待所有follower服务器的反馈,一旦超过半数的follower服务器进行了正确的反馈后,那么leader就会再次向所有的follower服务器分发commit消息,要求其将前一个proposal进行提交。
3.1 ZAB协议原理
在正常运行过程中,ZAB协议会一直运行于广播阶段来反复进行消息广播流程,如果出现崩溃或其他原因导致Leader缺失(接收不到Follower的心跳消息),那么此时ZAB协议会再次进入发现阶段,选举新的Leader。
- 发现阶段:要求ZK集群必须选举出一个Leader进程,同时Leader维护一个可用Follower列表。(见后文Leader选举内容)
- 同步阶段:Leader负责将自身的数据与Follower完成同步,做到多副本存储(AP)。
- 广播阶段:Leader可以接受客户端新的proposal请求,新的proposal请求广播给所有Follower。
ZAB协议的主要过程:(广播类似Paxos中的贿选、commit类似Paxos中的提议)
- 消息广播:Leader服务器为每个事务请求生成对应的proposal,并为这个proposal分配一个全局单调递增的唯一ZXID(高32位时周期,每次Leader选举后更新这个值,低32位从每个周期开始从0开始计数)。Leader将proposal广播给所有Follower服务器,Follower服务器以事务日志的形式将proposal写入磁盘,完成落盘后给Leader一个ACK响应。当Leader服务器收到半数以上Follower的ACK响应后,开始广播commit消息,Leader、Follower服务器完成对事务的提交。
- 崩溃恢复:Leader服务器出现故障后,会进入崩溃恢复阶段。这里ZAB协议后如下的要求——需要确保那些已经在Leader服务器上提交的事务最终被所有服务器都提交 或者 需要确保丢弃那些只在Leader服务器上被提出但是没有被提交的事务。由此,有限选择拥有最大ZXID的proposal的服务器作为新的Leader。
- 数据同步:Leader产生后将自己最大ZXID的proposal发送给所有Follower,各个Follower进行数据同步来保证集群间数据的一致性。
比较下Paxos和ZAB:
- Paxos算法没有leader的概念,通过accepter多数通过提案来实现数据一致性,适合分布式一致性状态机系统。
- ZAB协议有Leader和Follower概念,通过事务和广播来实现Follower向Leader的数据一致性,适合分布式主备模式系统。
四、ZK的架构与数据模型
4.1 ZooKeeper的架构
- 每个Server在内存中存储了一份数据;
- Zookeeper启动时,将从实例中选举一个Leader;
- Leader负责处理数据更新等操作(Zab协议);
- 一个更新操作成功,当且仅当半数以上Server在内存中成功修改数据。
Server根据其身份分为:
以上可以看出,ZK本身是一个高可用的实现分布式数据一致性的集群,由此对外分布式系统提供主备切换、分布式锁、集群监控等功能。
4.2 ZooKeeper的数据结构
-
数据模型Znode:
Zookeeper的数据节点称为ZNode,ZNode是Zookeeper中数据的最小单元,每个ZNode都可以保存数据,同时还可以挂载子节点,因此构成了一个层次化的命名空间(树)。
节点根据其特性可以分为持久性节点、持久性顺序节点、临时节点、临时顺序节点。其中,临时节点跟客户端会话绑定,会话结束则临时节点删除;顺序节点是为各个子节点添加的顺序按递增数字命名来维护一个顺序。
在Zookeeper中,事务是指能够改变Zookeeper服务器状态的操作,一般包括节点创建与删除,数据节点内容更新和客户端会话创建与失效,对于每个事务请求,Zookeeper都会为其分配一个全局唯一的事务ID,用ZXID表示,通常是64位的数字,每个ZXID对应一次更新操作,从这些ZXID中可以间接地识别出Zookeeper处理这些更新操作请求的全局顺序。
-
版本控制:
每个Znode都会带有自己的版本信息(数据内容版本version、子节点版本cversion、ACL版本aversion),版本可以用于节点操作的版本控制(类似CAS,只有预期版本号与当前真实版本号对应后,对节点的数据操作才是成功的)。
-
ACL权限控制:
Zookeeper提供了一套完善的ACL权限控制机制来保障数据的安全(Znode级别的权限控制)。
体现在ACL权限控制可以避免假死Leader导致同时有两个Leader对ZK数据进行修改的脑裂情况
我们可以从三个方面来理解ACL机制:权限模式(Scheme)、授权对象(ID)、权限(Permission),通常使用"scheme: id :permission"来标识一个有效的ACL信息。(比如可以用IP地址来进行权限控制)
-
Watcher监听机制:
watcher的特点是:一次出发、客户端串行执行、传输轻量。
- 客户端注册Watcher到服务端(客户端将需要watch的状态和路径封装成对象,发送至服务端注册)
- 服务端发生数据变更(每个节点的变化都会检查、取出并删除节点的Watcher——一次性的体现)
- 服务端通知客户端数据变更(封装对应的Watcher发送给客户端)
- 客户端回调对应Watcher的process方法处理变更应对逻辑(想要持续监听可以在回调中再注册Watcher,边缘触发是基于场景考虑的,如果是水平的这种一直触发那么需要显示注销Watcher)
实际上述底层上无非是,客户端将要监听的节点、事件类型封装通过网络发送给ZK服务端。客户端需要保存路径和Watcher的映射(Map),服务端也需要用WatcherManager进行Watcher的对应存储。当服务端的节点触发事件时,需要检查注册在节点上的Watcher,取得对应Watcher并删除(单次触发)将其封装后发送给客户端。客户端获取对应Watcher从映射关系中找到对应Watcher并调用其process方法(回调)。
4.3 ZooKeeper的Leader选举过程
当服务器初始化或者原Leader服务器出现故障,整个系统会进入发现状态(LOOKING),进行Leader选举。
ZK的Leader选举通过存活服务器进行投票成为多数派来实现。
- 第一次群体投票:每个机器都会投给自己,各个服务器相互接受选票,根据接收到的选票进行选票变更。
- 选票变更:每个选票都带有对应服务器的SID和ZXID,选票变更优先变更为ZXID较大的服务器,ZXID相同则变更为SID较大的服务器。
- 第二次群体投票:将选票变更结果再次投出,每个服务器都收到了变更后的结果,如果某台服务器发现投给自己的票超过半数,此服务器就成为Leader,否则还是Follower。
以上是关于分布式理论与ZooKeeper相关概念的主要内容,如果未能解决你的问题,请参考以下文章