Files
zfoo/doc/zookeeper/zookeeper.md
T
2021-07-09 22:18:03 +08:00

257 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## 一.分布式系统
#### 分布式系统的定义:
- 分布式系统是一个硬件或软件组分布在不同的网络计算机上,彼此之间仅仅通过消息传递进行通信和协调的系统。
#### 分布式系统的特点:
1. 分布性
分布式系统中的多台计算机在空间上随意分布,不同城市,不同机房,不同机柜
2. 对等性
没有主/从之分,没有控制整个系统的主机,也没有被控制的从机,分布式系统所有的计算机节点都是对等的
3. 并发性
银行转账A转B问题
#### 分布式系统的各种问题:
1. 通信异常
单机内存访问的延时在纳秒量级(通常10ns),而一次网络通信的延迟在0.1-1ms左右,相当于内存访问延时的100多倍
2. 网络分区
网络由于发生异常,导致分布式系统中部分节点之间的网络延时不断增大,最终导致分布式系统中只有部分节点能保持正常通行,将这个现象称为网络分区。
这时会出现小集群,在极端情况下,这些小集群需要完成整个分布式系统所要完成的工作。
3. 三态
分布式系统中每一次的请求与相应,都存在三态,成功,失败,超时。 出现超时现象无法确定当前请求是否被成功处理
4. 节点故障
每个节点都有可能会出现故障,并且每天都在发生
5. 缺乏全局时钟
很难定义两个时间谁先谁后
## 二.分布式一致性算法
#### 事务(Transaction
- ACID
1. 原子性(Atomicity)[ˌætəˈmɪsɪti] 要么做要么不做
2. 一致性(Consistency)事务的执行不能破坏数据库的完整性和一致性
3. 隔离性(Isolation[ˌaɪsəˈleʃən] 在标准的SQL规范中有4个事务隔离级别
未授权读取,授权读取,可重复读取,串行化。
![Image text](../image/zookeeper/isolation.png)
4. 持久性(Durability[djʊərə'bɪlətɪ] 事务一旦提交,它对数据库的状态变更就应该是永久性的。
#### CAP定理(CAP theorem /ˈθɪərəm/
- C:一致性(Consistency),所有节点在同一时间具有相同的数据
- A:可用性(Availability),保证每个请求在一定时间内,不管成功或者失败都有响应
- P:分区容错性(Partition tolerance),系统中任意信息的丢失或失败不会影响系统的继续运作,一般指增加删除节点导致网络分区,不同分区依然可用
```
CA
CA要求在多个节点满足数据的严格一致性,且延迟较低。
如果要满足P,则可以容忍数据丢包,因为数据在跨节点传输时有可能会丢包,如果丢包就无法满足一致性。
所以CA一般单点集群,传统的数据库系统就是具有CA特征的数据库,所以在可扩展性上不强,水平扩展能力比较差。
CP
满足一致性,分区容忍性的系统,因为P会导致系统的节点无线延长,也就无法在一定时间内保证可用性。
通常性能不是特别高。
AP
满足可用性,分区容忍性的系统,就要放弃强一致性,保证最终一致性。因为为了保证可用性,有时候节点就会用自己的本地数据,导致数据不一致性。
因为是分布式系统,所以应用必然需要部署到不同的节点中,因此必然出现子网络,所以P是分布式系统首先需要满足的。
系统架构师往往把精力花在如何根据业务特点在C和A之间寻求平衡。
```
#### BASE理论:
```
Basically Available(基本可用),运行损失部分可用性,如响应时间加长,或者功能上的损失,如双11服务降级
Soft state(软状态),允许在不同节点的数据副本之间进行数据同步的过程中存在延时
Eventually consistency(最终一致性),系统中的副本,在经过一段时间的同步后,最终能够达到一个一致的状态
三个短语的简写即为BASE,BASE是对CAP中一致性和可用性权衡的结果,核心思想是即使无法做到强一致性(Strong consistency),但每个业务可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。
```
#### 分布式一致性协议:
当一个事务需要跨多个分布式节点的时候,为了保持事务处理的ACID特性,就需要引入一个称为“协调者”的组件来统一调度所有分布式节点的执行逻辑,来保证一致性。
2PCTwo Phase Commit,二段提交协议,大多数关系型数据库都是采用的这个协议来完成分布式事务的
![Image text](../image/zookeeper/transaction.png)
3PCThree Phase Commit,三阶段提交协议
#### Paxos:分布式一致性算法
Proposer(提议者),Acceptor(决策者),Client(产生议题者),Learner(最终决策学习者)
现在通过一则故事来学习paxos的算法的流程(2阶段提交),有2个Client(老板,老板之间是竞争关系)和3个Acceptor(政府官员)
现在需要对一项议题来进行paxos过程,议题是“A项目我要中标!”,这里的“我”指每个带着他的秘书Proposer的Client老板。
Proposer当然听老板的话了,赶紧带着议题和现金去找Acceptor政府官员。作为政府官员,当然想谁给的钱多就把项目给谁。
Proposer-1小姐带着现金同时找到了Acceptor-1~Acceptor-3官员,1与2号官员分别收取了10比特币,找到第3号官员时,没想到遭到了3号官员的鄙视,3号官员告诉她,Proposer-2给了11比特币。
不过没关系,Proposer-1已经得到了1,2两个官员的认可,形成了多数派(如果没有形成多数派,Proposer-1会去银行提款在来找官员们给每人20比特币,这个过程一直重复每次+10比特币,直到多数派的形成),
满意的找老板复命去了,但是此时Proposer-2保镖找到了1,2号官员,分别给了他们11比特币,1,2号官员的态度立刻转变,都说Proposer-2的老板懂事,这下子Proposer-2放心了,搞定了3个官员,
找老板复命去了,当然这个过程是第一阶段提交,只是官员们初步接受贿赂而已。故事中的比特币是编号,议题是value。
这个过程保证了在某一时刻,某一个proposer的议题会形成一个多数派进行初步支持。
===============华丽的分割线,第一阶段结束================ 现在进入第二阶段提交,现在proposer-1小姐使用分身术(多线程并发)
分了3个自己分别去找3位官员,最先找到了1号官员签合同,遭到了1号官员的鄙视,
1号官员告诉他proposer-2先生给了他11比特币,因为上一条规则的性质proposer-1小姐知道proposer-2第一阶段在她之后又形成了多数派(至少有2位官员的赃款被更新了);
此时她赶紧去提款准备重新贿赂这3个官员(重新进入第一阶段),每人20比特币。刚给1号官员20比特币, 1号官员很高兴初步接受了议题,还没来得及见到2,3号官员的时候,
这时proposer-2先生也使用分身术分别找3位官员(注意这里是proposer-2的第二阶段),被第1号官员拒绝了告诉他收到了20比特币,
第2,3号官员顺利签了合同,这时2,3号官员记录client-2老板用了11比特币中标,因为形成了多数派,所以最终接受了Client2老板中标这个议题,对于proposer-2先生已经出色的完成了工作;
这时proposer-1小姐找到了2号官员,官员告诉她合同已经签了,将合同给她看,proposer-1小姐是一个没有什么职业操守的聪明人,觉得跟Client1老板混没什么前途,
所以将自己的议题修改为“Client2老板中标”,并且给了2号官员20比特币,这样形成了一个多数派。顺利的再次进入第二阶段。由于此时没有人竞争了,顺利的找3位官员签合同,
3位官员看到议题与上次一次的合同是一致的,所以最终接受了,形成了多数派,proposer-1小姐跳槽到Client2老板的公司去了。
#### ZAB:原子消息广播协议算法
ZABZookeeper Atomic Broadcast,原子消息广播协议,Zookeeper分布式一致性的核心算法。包括两部分:崩溃恢复和消息广播(类似二阶段的提交过程)。
具体一点可以分为三个阶段:发现(Leader选举),同步(Leader和Follower之间的同步),广播(接受客户端新的事务请求)。
每个节点都可能处在三种状态,lookingleader选举阶段,followingfollower服务器和leader保持同步状态,leading:Leader服务器作为主进程领导状态。
Paxos和ZAB的本质区别在于两者的设计目标不太一样。前者用于构建一个分布式的一致性状态机系统,而后者用于构建一个高可用的分布式数据主备系统。
## 三.Zookeeper基本说明
#### Zookeeper的定义:
- Zookeeper是一个高可用的分布式数据管理与协调框架
#### Zookeeper应用范围:
分布式应用可以基于Zookeeper实现如分布式一致性特性,数据发布/订阅,负载均衡,命名服务,分布式协调/通知,集群管理,Master选举,分布式锁,分布式队列
#### Zookeeper特点
- 高性能:Zookeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,因此它尤其适用于以读操作为主的应用场景。Zookeeper性能压测在100%读请求的场景下可以达到12-13W的QPS。
- 顺序访问:对于每一个客户端的请求,Zookeeper都会生成一个全局唯一的递增序号,这个序号反映了所有事务操作的先后顺序,应用程序可以使用这个特性来实现更高层次的同步原语。
- Leader服务器在产生一个新的事务的时候,会生成一个序列号ZXIDZookeeper Transaction ID,这个ID有64位,前32位代表事务编号,每个事务加1,后32位代表发给客户端的计数器,每发给客户端计数器加1。
![Image text](../image/zookeeper/zookeeper-function.png)
#### Zookeeper的三种选举算法:LeaderElectionAuthFastLeaderElectionFastLeaderElection
默认的算法是FastLeaderElection
启动时的选举算法如下:
1. 目前有5台服务器,每台服务器均没有数据,它们的编号分别是1,2,3,4,5,按编号依次启动,它们的选择举过程如下:
2. 服务器1启动,给自己投票,然后发投票信息,由于其它机器还没有启动所以它收不到反馈信息,服务器1的状态一直属于Looking。
3. 服务器2启动,给自己投票,同时与之前启动的服务器1交换结果,由于服务器2的编号大所以服务器2胜出,但此时投票数没有大于半数,所以两个服务器的状态依然是LOOKING。
4. 服务器3启动,给自己投票,同时与之前启动的服务器1,2交换信息,由于服务器3的编号最大所以服务器3胜出,此时投票数正好大于半数,所以服务器3成为领导者,服务器1,2成为小弟。
5. 服务器4启动,给自己投票,同时与之前启动的服务器1,2,3交换信息,尽管服务器4的编号大,但之前服务器3已经胜出,所以服务器4只能成为小弟。
6. 服务器5启动,后面的逻辑同服务器4成为小弟。
崩溃恢复时的选举算法:
![Image text](../image/zookeeper/zookeeper-leader-election.png)
![Image text](../image/zookeeper/zookeeper-process.png)
## 四.Zookeeper的应用
#### 数据发布/订阅
- 发布/订阅一般有两种设计模式,Zookeeper采用推拉结合的方式,一旦节点数据发生变化,服务端就会向客户端发送Watcher事件通知,客户端自己拉取想要的数据
```
服务器主动推(Push):服务器主动将数据更新发送给所有订阅的客户端,这种数据量在短时间可能会很大
客户端主动拉(Pull):客户端主动发起请求获取最新的数据,通常采用定时轮询的方式,这种缺点就是空轮询,客户端开销大
```
- 试用的场合
```
数据量比较小
数据内容在运行时会发生动态变化
集群中各机器共享,配置一致
```
#### 负载均衡
- 可分为硬件负载均衡和软件负载均衡
四层通过虚拟IP+端口接收请求,然后再分配到真实的服务器,如四层的负载均衡,就是通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,
对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。 以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN
请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。
TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。
在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。
七层通过虚拟的URL或主机名接收请求,然后再分配到真实的服务器,七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征。
比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。
举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。
以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,
然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。
负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。
负载均衡器通常称为四层交换机或七层交换机。四层交换机主要分析IP层及TCP/UDP层,实现四层流量负载均衡。七层交换机除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息。
1、负载均衡分为L4 switch(四层交换),即在OSI第4层工作,就是TCP层啦。此种Load Balance不理解应用协议(如HTTP/FTP/MySQL等等)。例子:LVSF5。
2、另一种叫做L7 switch(七层交换),OSI的最高层,应用层。此时,该Load Balancer能理解应用协议。例子: haproxyMySQL Proxy。
![Image text](../image/zookeeper/load-balance.png)
#### 命名服务
- 集群中全局唯一ID的生成,用Java自带的UUID生成的是一长串没有意义的ID,在Zookeeper中创建一个顺序生成节点可以方便的生成全局唯一ID
#### 分布式协调/通知
- 在绝大多数的分布式系统中,系统机器间的通讯无外乎心跳检测,工作进度汇报和系统调度这三种类型
1. 心跳检测
```
传统的方案是一段时间A通ping到B,来判断A和B是否相连。
基于Zookeeper的心跳检测,A可以在Zookeeper注册一个临时节点,B监听这个节点的变化判断是否相连,这样可以极大的解耦合
```
2. 工作进度汇报
```
注册一个临时节点,节点的内容为自己的任务
```
3. 系统调度
```
通过临时节点的数据变化,控制其它监听该节点的系统
```
#### 集群管理
- 机器的上下线,机器监控
#### Master选举
- 集群中所有的节点同事注册一个/master的临时节点,哪个注册成功哪个就是master节点
#### 分布式锁
- 排它锁
```
获取锁:所有的客户端同事创建一个/lock临时节点,Zookeeper保证所有的客户端只有一个能创建成功,就认为这个客户端获取了锁,其它客户端注册监听,以便释放锁的时候重新获取锁
释放锁:获取锁的节点宕机,临时节点就会被移除;正常的执行业务逻辑后,主动释放锁,即删除这个临时节点
```
- 共享锁,又称为读锁
```
加上共享锁的对象,只能对锁中的内容进行读取操作,其它的事物也只能对该对象加共享锁
```
#### 分布式队列
- FIFO分布式队列
- Barrier分布式屏障