这是我的第43篇原创
先讲一个小故事。有个超级牛人,叫莱斯利兰伯特,拿过图灵奖。他一直在研究分布式领域。分布式环境中的一致性问题一直难以解决,这哥们写了一篇论文,叫“The Part-Time Parliament”也就是“兼职议会”。这个论文中提到了一个Paxos算法,可以解决分布式环境中由于集群中机器随时可能掉线而导致数据不一致问题。但是这位大爷非常的奇葩,把一个算法论文硬生生写成了一个故事--你从论文名字就能看出来--整篇论文中没有一个数学符号。结果可想而知,顶尖的学术期刊压根就不收他的论文。
有兴趣的可以在后台回复:paxos,拜读一下这篇只有11页,没有公式的算法论文。
分布式一致性协议的作用就是让在网络异常的情况下,让所有节点达成共识。无论网络出现什么异常,集群里所有的节点只要通过这个协议之后,就能对某个信息达成一致了。
目前应用比较广的分布式一致性协议有:
- Paxos
- ZBA
- Raft
Paxos协议
Paxos协议需要几个角色来处理相应的任务:
- 提议者 Proposer
- 决策者 Acceptor
- 学习者 Learner
我们在每个节点中都同时设置三个角色。当不同节点的数据/意见不一致的时候,这三个角色将通过以下方达成一致:
- Prepare提案阶段:提议者向决策者发起提案。
- Accept决策阶段:决策者接受提案,并告知所有的学习者。
场景假设:现在刘备、关羽、张飞三员大将统领三军,各自收到军师诸葛亮发来的密信,让他们进攻。刘备和关羽收到的是攻打曹操,张飞收到的是攻打周瑜。这可咋整?注意,这时候信息传输是不稳定的,信使可能被杀掉。
Prepare提案阶段
- Prepare提案阶段:
提案阶段第一步:所有节点的Proposer提议者所有节点中超过一半的Acceptor决策者发起提案,这个提案的主要内容就是一个编号。
跟着刘备的孙乾同时向刘关张三个老大发了一封密信,编号是666;糜竺也发了,编号是555,法正的编号是111。
提案阶段第二步:所有的Acceptor决策者对手上编号最大的提案进行响应。
期间,有两个信使挂了,于是刘备收到了孙乾、糜竺和法正的密信,关羽收到了孙乾和法正的,张飞收到了糜竺和法正的。然后各自对手上编号最大的回了一封信:收到了。
Accept决策阶段
- Accept决策阶段:
决策阶段第一步:收到一半以上决策者 Acceptor回复的提议者 Proposer,将其提案编号和内容再次发送给一半以上的决策者 Acceptor。
孙乾、糜竺和法正三人里,只有孙乾收到了一版以上的反馈,于是他将自己收到的信息再次发送给刘关张。很不幸,这次只有关羽收到了。
决策阶段第二步:只有决策者 Acceptor收到了以前回复的最大编号的决策提案,那他就应该接受该提案。同时,他需要告知所有的学习者 Learner。 - 关羽收到了他之前响应过的提案,这是孙乾发来的攻打曹操的信息,他接受了这个提案,并将提案内容告知所有的学习者(士兵)。这时,所有节点就攻打谁的问题达成了一致,开心的去攻打曹操了。
有人说,怎么这么复杂啊?是的,Paxos是出了名的复杂,这已经是超级简化版的了。上面刘关张的例子其实就是“拜占庭将军问题”的中国翻译版。
但是这是当时乃至于到现在最广泛的分布式一致性解决方案之一。它解决了一个超级难题:在信息传输异常(机器挂掉、消息延迟、丢失、重复、乱序等各种情况)下,如何使集群中各节点达成统一意见。基于上面的基础逻辑,加上各种限定规则,Paxos能保证无论集群内部发生任何异常,都能让整个分布式系统对于某个信息达成一致性决议。
但是Paxos太费劲了,太难理解了,而且节点多了,就非常麻烦。