这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
先不说做专业算法的工程师们,其实广大的研发都应该对算法有所理解和掌握,起码可以通过自己的逻辑,想法,来设计方案,解决遇到的问题。前段时间有所懈怠,也是需求太多的原因,没有经常更新,但看着与日增加的关注人数,倍感惭愧!小弟何德何能啊。所以,我觉得还是应该把日常所得坚持记录一下,几天一悟也好,一周一悟也罢,对我好处不言而喻,万一哪个点让您灵光突显一下呢,那可就阿弥陀佛了!
如今业内常用架构:高并发 -> 异步处理 -> 主/备容灾
最常用的主备措施是使用zookeeper。 然而,zk怎样保证高可用、一致性呢,这就涉及到了其底层使用的一致性协议ZAB(来源于paxos)。曾有人说,paxos算法,是迄今为止唯一正确的一致性算法,其他的算法都是由paxos改进和演变来的。zookeeper也一样,其一致性协议ZAB,虽然和paxos不同,但也有千丝万缕的联系。
概括的说一下,
在协议实现上:ZAB是三阶段的,比paxos是两阶段的多出一个同步阶段,以确保fallower已经对当前周期之前的决议进行提交;
在涉及目的上:ZAB主要用于构建一个高可用的分布式数据主备系统,paxos用于构建一个分布式的一致性状态机系统。今天,就来说说zookeeper中的ZAB。
先来说一下基本paxos算法,他是一种依赖消息传递的一致性算法,包括两个阶段:
1.决议的提出。
当提议者希望提出方案v1,则首先向其他节点(接受者)发送带有序列号sn1的请求。当接受者接受到sn1的提案请求时,检查自己上次回复过的请求的序列号sn0 ,当sn1<sn0时,说明本次接受的提案已过时,直接忽略
如果sn1大,那么检查上次批准过的提议<sn0,v0>,并且回复给该提议者这个决议,如果以前没有批准过其他的提议,那么就直接回复ok
2.决议的批准。
2.1提议者检查收到的回复:
如果多于1半的回复都是ok,那么提议者发出accept请求,内容为提案<sn1,v1>
如果多半的回复中,有<sn2,v2> <sn3,v3>等等,那么就在这些回复中,找到大于一半的那个<snx,vx>,发出accept请求
如果回复不足一半,那么把序列号+1,继续提案。
2.2然后继续检查收到的回复
回复大于一半,则确认v1被接受
回复不足一半,则sn+1 继续提案
paxos算法有可能出现竞争,发生活锁,比如当有三个提案者一起进行提案时,将很难有一个提案者可以有大于一半节点的回复,那么集群就会一直处于第一个阶段
ZAB(fast paxos)算法 是对基本paxos的一个改进。
ZK的两个特点:消息传递(leader选举的新事务广播)和崩溃恢复(leader出问题之后选举leader,恢复系统)。它定义了一个唯一的leader去提出议案,那么按我的理解,问题就变成了对唯一leader的选举和保证。那么,怎样选出leader呢,leader挂了怎么办呢,什么时候发起选举呢,选举中有后进的机器要发起选举怎么办呢,节点挂了又重启了怎么办呢。
何时发起选举?
当节点刚启动时,或者当节点发现leader挂了时发起选举
leader挂了怎么办?
发起选举,进入崩溃恢复模式
节点挂了又重启?
发起投票,但如果发现当前系统中存在leader,那么就进入数据恢复模式,主动连接leader服务器、同步leader信息,加入到消息广播中。
消息广播用来完成leader和fallower之间的交互,采用的是具有先进先出的TCP协议进行网络通信,所以可以很好的确保消息、提案的顺序性。当某一fallower接收到客户端的事务请求时,必须先提交给leader,然后由leader发起广播。
崩溃恢复,在leader失去半数支持者的情况下,重新确定新的leader,确保系统中只有一个”决策者“,并且,确保已经在leader上提交的事务被所有服务器都提交,并确保丢弃只在leader上提出的事务。比如,
leader有行为:p1-->p2-->commit 1-->p3-->comit 2。
leader提出了p1,p2,commit p1,自己提出p3,commit p2,
此时的ZAB,需要让另外N个fallower 也能够正常commit 2。
但是p3是leader自己提出的,又没有commit,则保证另外的fallower丢弃p3,达到数据一致性。