Zookeeper,一个开源的分布式协调服务,可以用其进行配置管理,名称服务等,在Zookeeper中,数据是以节点形式存储,如果在Zookeeper中做配置管理,那么就需要在里面创建指定的配置,

比如创建两个节点 /geekbang 和 /geekbang/time

create /geekbang 123

create /geekband/time 456

分别创建了节点和对应的值 123 456

那么,在zookeeper中,能够利用Multi-Paxos,实现各个节点数据的共和一致吗

那么,兰伯特的Multi-Paxos能保证共识后的值不再改变,但是无法保证各个值的顺序性,这就是Zookeeper没有用Multi-Paxos,而是用了ZAB协议解决的问题所在

首先看ZAB的一道思考题

假设节点A B C组成一个分布式集群,要设计一个算法,保证指令 X Y的顺序性,比如指令X在指令Y之前执行,如何设计这个算法呢?

图片

首先我们看下,如果是使用Multi-Paxos,如何保证的操作的顺序性,

首先所有的节点的选定指令,最大序号都是100,那么新提议的指令对应的序号就是101

A是领导者,提议了指令 X Y,那么分别是101 和 102

但是A发生了网络故障,导致只复制到了A节点

图片

发出消息石沉大海,没回应

然后当选的领导者B,节点B当选领导者后,查看已经选定到哪里了,节点B发现最大的序号是100,那么就从101开始提议,这时候,接受到了客户端的Z指令,被成功复制到了节点B C

图片

假设这时候节点B故障了,节点A生效了,那么101已经被使用了,只能使用102了,达成了原本102的Y值,如下所示

图片

原本指令是X Y,最后变成了Z Y,导致了不能达到想要的结果

再回到开头的问题,ZooKeeper中使用了兰伯特的Multi-Paxos,就可能存在先创建/geekbang/time在创建/geebang的问题,导致创建失败了

ZAB的问题是使用了Multi-Paxos问题,导致的无法保证操作的顺序性,Multi-Paxos只保证达成一系列的值,不关心最终达成的值是什么,也不关心值的顺序,这就是问题

这个顺序性的保证,就是实现了ZAB

ZAB就是一个基于主备的,能够保证顺序性,假设节点A是主节点,BC是备份节点

图片

当主节点收到了写的请求后,会基于这个写请求的指令,创建一个提案(x,y)

并使用唯一的一个ID来标识这个提案,这里的唯一ID就是指事务标识符ID,(zxid)

图片

在实际中,事务标识符是64位的long型的变量,有任期编号epoch和计数器counter两部分组成,高32位为任期编号,低32位为计数器

任期编号,创建提案的时候的领导者的任期编号,新领导者当选的时候,任期编号增加,计数器会重新归零

计数器,具体标识提案的整数,每次创建新的提案的时候,计数器会递增,比如,前一个提案的值为1,新的一个提案的值就是为2

这样,创建完成提案后,主节点基于TCP,将顺序发送提案到其他的节点,保证先发送的消息,

图片

X就能在Y之前到达了B C

主节点接收到指定提案的大多数的确认响应后,会处于提交的状态,主节点会通知备份节点提交这个提案

图片

主节点提交提案是有顺序的,主节点根据实物大小,按照顺序提交提案,如果前一个提案没有提交,此时后一个提案是不会提交的,这样保证了指令X会在指令Y之前提交

最后,主节点返回执行成功的响应给节点B,节点B再转发给客户端,就实现了操作的顺序性,保证了指令X一定在指令Y之前执行

最后,在写操作完成后,执行读操作,但是Zookeeper也没有实现强一致性,而是最终一致性,读操作可以在任何节点上执行,客户端会读到旧数据

图片

Zookeeper提供了一个解决方案,就是使用sync命令,在读操作之前,先进行sync,读到最新的数据

本章主要是说了Multi-Paxos无法实现操作的顺序性,ZAB协议如何保证的

Multi-Paxos只考虑如何达成共识,并没说明各个共识的值之间的顺序性

ZAB通过一切以领导者为准的强领导者模型,和严格按照顺序进行处理,提交提案,完成了操作的顺序性

最后,ZAB到底是不是Multi-Paxos算法呢?

ZAB可以理解为Multi-Paxos算法,Raft算法和ZAB协议很类似,都是能够实现一系列的值,并且保证值的顺序,Multi-Paxos还能指代多次执行Basic Paxos的算法

而且,在Gossip协议中,谣言传播是其中的一个属性,同时反熵也是其中的一个特性

主节点是基于TCP协议来广播消息,并保证消息的接收的顺序性,那么ZAB使用的是UDP的协议,能保证消息接收的顺序性吗?

1.首先消息的前后性不能保证,因为TCP本质上是在接收和发送的两端都维护了一个栈的机制,模拟出了一条数据流,从而做到了顺序的传输,而UDP是无序的,可以在网上到处开车,可能导致消息前后错乱

2.但是消息的前后性我感觉可以从别的地方保证,可以从几点来分析下,对于失败重传,这个可以由发收双方进行手段性质的保证

而且在主节点不故障的情况下,是可以知道发送的消息,那么X不会的时候,Y也不会先提交

而且对于跟随者,只收到了Y的提交,估计也要等X的提交消息才能生效吧,不然即使是两个消息有依赖性,但是两个消息也不一定在一个TCP里面提交啊

最后,即使故障了,任期编号自然会更新,不会出现编号错乱的问题

发表评论

邮箱地址不会被公开。 必填项已用*标注