> 技术文档 > 重生之我要学Zookeeper

重生之我要学Zookeeper


1.CAP原则

1.1概述

如今的大型互联网场景,数据量庞大,服务器分散部署,,节点会越来越多,节点故障和网络风险会是常态,那么分区容错是一种解决办法,同时分区容错需要保持数据的一致性,可用性,这就是cap原则。

Consistency(一致性)、 Availability(可用性、及时响应)、Partition tolerance(分区容错

性),三者不可得兼,就说明一定会舍弃其中的一种特性,因为同时满足两个的时候就会出现互斥情况。比如说要保证分区容错性和一致性,那么集群中的数据就需要时间实现同步一致,导致不能立即的响应,舍弃了可用性的特性。

有的公司数据量非常大,需要保障数据的安全和高效,那么一般就需要实现分区容错的需求,另外和传统的项目就可能有所不同,拿银行的转账系统来说,涉及到金钱的对于数据一致性不能做出一丝的让步,C 必须保证,出现网络故障的话,宁可停止服务。而互联网非金融项目普遍都是基于 AP 模式。

2.BASE理论

BASE理论是基于CAP理论产生的,全称 Basically Available(基本可用),Soft state(软状态),和 Eventually consistent(最终一致性)三个短语的缩写,来自 ebay 的架构师提出。

BASE 理论是对 CAP 中一致性和可用性权衡的结果,其来源于对大型互联网分布式实践的总结,是基于 CAP 定理逐步演化而来的。其核 心思想是:

既然无法做到强一致性(Strong consistency),但每个应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性 (Eventual consistency)。

Basically Available(基本可用)

基本可用是指分布式系统在出现故障的时候,允许损失部分可用性(例如响应时间、功能上的可用性)。需要注意的是,基本可用绝不 等价于系统不可用。

响应时间上的损失:正常情况下搜索引擎需要在 0.5 秒之内返回给用户相应的查询结果,但由于出现故障(比如系统部分机房发生断电 或断网故障),查询结果的响应时间增加到了 1~2 秒。

功能上的损失:购物网站在购物高峰(如双十一)时,为了保护系统的稳定性,部分消费者可能会被引导到一个降级页面。

Soft state(软状态)

分布式存储中一般一份数据会有多个副本,可以不及时的同步数据副本,比如一个服务器新增了某个事物请求,而不一定要求集群中所有的服务器都立马得到该请求信息,这是一种软状态。

要求多个节点的数据副本都是一致的,这是一种 “硬状态”。

Eventually consistent(最终一致性)

系统不可能一直是软状态,必须有个时间期限。在期限过后,应当保证所有副本保持数据一致性。从而达到数据的最终一致性。这个时 间期限取决于网络延时,系统负载,数据复制方案设计等等因素。

3.数据的一致性

一些分布式系统通过共享各个集群的数据提高系统的可靠性和容错性,如果出现网络、部分服务器出现故障还能保证系统的正常运行。

强一致性:要求无论更新操作实在哪一个副本执行,之后所有的读操作都要能获得最新的数据。

弱一致性:用户读到某一操作对系统特定数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。

最终一致性:是弱一致性的一种特例,保证用户最终能够读取到某操作对系统特定数据的更新。

从客户端来看,有可能暂时获取的不是最新的数据,但是最终还是能访问到最新的

从服务端来看,数据存储并复制到整个系统超过半数的节点,以保证数据最终一致

4.Paxos算法

4.1概述

  1. Paxos算法是Leslie Lamport宗师提出的一种基于消息传递的分布式一致性算法,使其获得2013年图灵奖。
  2. Paxos在1990年提出,被广泛应用于分布式计算中,Google的Chubby,Apache的Zookeeper都是基于它的理论来实现的
  3. Paxos算法解决的问题是分布式一致性问题,即一个分布式系统中的各个进程如何就某个值(决议)达成一致。
  4. 传统节点间通信存在着两种通讯模型:共享内存(Shared memory)、消息传递(Messages passing),Paxos是一个基于消息传递的一 致性算法。

4.2算法描述

Paxos 描述了这样一个场景:

- 有一个叫做 Paxos 的小岛(Island)上面住了一批居民(Islander);

- 岛上面所有的事情由一些特殊的人决定,他们叫做议员(Senator);

- 议员的总数(Senator Count)是确定的,不能更改;

- 岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编号是一直增长的,不能倒退;

- 每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效(少数服从多数);

- 每个议员只会同意大于当前编号的提议,包括已生效的和未生效的;

- 如果议员收到小于等于当前编号的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上记录的编号,他会不 断更新这个编号;

- 整个议会不能保证所有议员记事本上的编号总是相同的;

- 现在议会有一个目标:保证所有的议员对于提议都能达成一致的看法。

现在议会开始运作,所有议员一开始记事本上面记录的编号都是0。有一个议员发了一个提议:将电费设定为1元/度。他首先看了一下记事本,嗯,当前提议编 号是0,那么我的这个提议的编号就是1,于是他给所有议员发消息:1号提议,设定电费1元/度。其他议员收到消息以后查了一下记事本,哦,当前提议编号是 0,这个提议可接受,于是他记录下这个提议并回复:我接受你的1号提议,同时他在记事本上记录:当前提议编号为1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1号提议生效!收到的议员会修改他的记事本,将1好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法令并告诉对 方:1元/度。

再看冲突的解决:假设总共有三个议员S1-S3,S1和S2同时发起了一个提议:1号提议,设定电费。S1想设为1元/度, S2想设为2元/度。结果S3先收到了S1的

提议,于是他做了和前面同样的操作。紧接着他又收到了S2的提议,结果他一查记事本,咦,这个提议的编号小于等于我的当前编号1,于是他拒绝了这个提议:对不起,这个提议先前提过了。于是S2的提议被拒绝,S1正式发布了提议: 1号提议生效。S2向S1或者S3打听并更新了1号法令的内容,然后他可以选择继 续发起2号提议。

上面这是一个非常简略的版本。

4.3算法模型延伸

如果Paxos岛上的议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大家都没有死,都在动,但是一直解决不了冲突问 题)。Paxos的作者在所有议员中设立一个总统,只有总统有权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。

情况一:屁民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode的数据),议员毫不犹豫的拿出他的记事本(local storage),查 阅法令并告诉他结果,同时声明:我的数据不一定是最新的。你想要最新的数据?没问题,等着,等我找总统Sync一下再告诉你。

情况二:屁民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等着,自己将问题反映给了总统,总统询问所有议员 的意见,多数议员表示欠屁民的钱一定要还,于是总统发表声明,从国库中拿出一万元还债,国库总资产由100万变成99万。屁民乙拿到钱回去了(Client函数 返回)。

情况三:总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期间政府停业,拒绝屁民的请求。

总结

选举产生总统,所有的请求都由总统发布投票,过半通过则生效,然后通知所有人该提议通过。这个总统的数据必须是最全的,也就是PID最大值。解决了其他议员可能提议不全的问题。

5.Raft算法

Raft 适用于一个管理日志一致性的协议,相比于 Paxos 协议 Raft 更易于理解和去实现它。

Raft 将一致性算法分为了几个部分,包括领导选取(leader selection)、日志复制(log replication)、安全(safety)

Raft 算法的官网:https://raft.github.io/

中文版:https://acehi.github.io/thesecretlivesofdata-cn/raft/

英文版:http://thesecretlivesofdata.com/raft/

Raft算法将Server划分为3种状态,或者也可以称作角色:

Leader

负责Client交互和log复制,同一时刻系统中最多存在1个。

Follower

被动响应请求RPC,从不主动发起请求RPC。

Candidate

一种临时的角色,只存在于leader的选举阶段,某个节点想要变成leader,那么就发起投票请求,同时自己变成candidate

6.ZAB协议

Leader:事务请求的唯一调度和处理者,保证集群事务处理的顺序 性集群内部各服务器的调度者。

Follower:它是 Leader 的追随者,其主要工作有三个:处理客户端的非实物请求,转发事务请求给 Leader 服务器参与事务请求 Proposal 的投票参与 Leader 选举投票。

Observer:是 ZooKeeper 自 3.3.0 开始引入的一个角色,它不参与事务请求 Proposal 的投票,也不参与 Leader 选举投票,只提供非事务 的服务(查询),通常在不影响集群事务处理能力的前提下提升集群的非事务处理能力。

Follow 服务器和 Observer 服务器又统称为 Learner 服务器。

在Leader节点奔溃的情况下,ZAB会让议员选举产生新的总统,这个总统依然由获取请求,发送提议,广播提议的作用。

发现:要求 ZooKeeper 集群必须选举出一个 Leader,同时 Leader 会维护一个 Follower 可用列表。将来客户端可以和这些 Follower 节点 进行通信。

同步:Leader 要负责将本身的数据与 Follower 完成同步,做到多副本存储。这样便体现了 CAP 中的一致性和分区容错。Follower 将队列 中未处理完的请求消费完成后,写入本地事务日志中。

广播:Leader 可以接受客户端新的事务 Proposal 请求,将新的 Proposal 请求广播给所有的 Follower。

7.ZooKeeper存储模型和监听机制

7.1存储结构

zookeeper是一个树状结构,维护一个小型的数据节点znode

数据以keyvalue的方式存在,目录是数据的key

所有的数据访问都必须以绝对路径的方式呈现

节点的分类

持久化节点(PERSISTENT)

默认创建的就是持久化节点

临时节点(Ephemral)

只要创建节点的会话有效,节点就不会失效

可以被所有的客户端所查看

事务编号和临时节点编号是一致的

create -e

一旦会话结束,临时节点也会被自动删除,一般这个功能用于判断节点和服务器是否保持连接

序列化节点(Sequential)

在名字的后面添加一个序列号(有序)

create -s

7.2监听机制

通过对锁的监听从而,获取进入服务器的权限。

流程如下