分布式架构的一致性维持

痞子三分冷 提交于 2019-11-28 14:49:28

在实际开发中,我们的大型项目都需要设计分布式架构,同时对高并发的场景进行管理,而在高并发环境中,我们通过使用redis集群来管理和控制该场景,同时,我们需要保证数据库与缓存的双写一致性,同时因为在常见的高并发场景中,我们对于微服务的控制并不能很好的应对该场景,如spring cloud和docker的结合并不能很好的解决该问题,因此我们需要相应的算法和协议来维持分布式架构的一致性。

如图所示,我们在分布式架构中,通常对于服务器的管理,我们通过观察是否存在特洛伊问题来决定使用哪种方法来解决分布式架构一致性。

在非特洛伊问题中,我们使用paxos和raft协议来维持分布式架构一致性,例如,在使用spring+spring MVC+Mybatis的开发中,我们经常使用@RequestBody 注解来返回一个json格式的网络状态,在常用的消息队列中,例如RabbitMQ,我们使用消息中间件的特性来进行程序的解耦削峰异步,通过消息中间件的作用,我们使传统RPC的方式变为了分布式,从而解决了系统的耦合性,但是对于大型业务场景,消息中间件会产生消息丢失,消息转发失败等系统问题,所以我们在设计架构的时候,通过会使用消息队列锁定算法来维持消息的稳定性,但对于高并发场景一味的使用synchronized或者乐观锁是不现实的,所以我们会使用分布式锁,自旋锁等高级锁来保持高并发场景的读写一致性。

但同样重要的时,在大型项目中使用大量的锁是现实的,这会影响系统性能,所以我们会使用paxos协议,paxos协议是针对非特洛伊问题下的分布式架构的一致性问题协议,它的底层使用的时SOAP协议,简单对象管理协议。我们使用该协议,可以在非特洛伊问题下,保持分布式架构的稳定性,同时在文献《spring core Request》一文中,其author就说明了,在非特洛伊问题下的场景管理,首先一点,spring 最主要的核心是ioc 控制反转和aop面向切面,比如我们会使用@AutoWrited @Service 注解来自动注入bean,自动加载bean,但是身为一个架构师,我们不应该仅仅限于一般的业务场景,我们更应该注重大规模的业务场景,所以我们才会引入这个话题。

paxos

Paxos算法是Leslie Lamport在1990年提出的一种基于消息传递的一致性算法。由于算法难以理解,起初并没有引起大家的重视,Lamport在1998年将论文重新发表到TOCS上,即便如此Paxos算法还是没有得到重视,2001年Lamport用可读性比较强的叙述性语言给出算法描述。

06年Google发布了三篇论文,其中在Chubby锁服务使用Paxos作为Chubby Cell中的一致性算法,Paxos的人气从此一路狂飙。

基于Paxos协议的数据同步与传统主备方式最大的区别在于:Paxos只需超过半数的副本在线且相互通信正常,就可以保证服务的持续可用,且数据不丢失。

Basic-Paxos

Basic-Paxos解决的问题:在一个分布式系统中,如何就一个提案达成一致。

需要借助两阶段提交实现:

Prepare阶段:

Proposer选择一个提案编号n并将prepare请求发送给 Acceptor。
Acceptor收到prepare消息后,如果提案的编号大于它已经回复的所有prepare消息,则Acceptor将自己上次接受的提案回复给Proposer,并承诺不再回复小于n的提案。

Accept阶段:

当一个Proposer收到了多数Acceptor对prepare的回复后,就进入批准阶段。它要向回复prepare请求的Acceptor发送accept请求,包括编号n和根据prepare阶段决定的value(如果根据prepare没有已经接受的value,那么它可以自由决定value)。
在不违背自己向其他Proposer的承诺的前提下,Acceptor收到accept请求后即接受这个请求。

Mulit-Paxos

Mulit-Paxos解决的问题:在一个分布式系统中,如何就一批提案达成一致。

当存在一批提案时,用Basic-Paxos一个一个决议当然也可以,但是每个提案都经历两阶段提交,显然效率不高。Basic-Paxos协议的执行流程针对每个提案(每条redo log)都至少存在三次网络交互:1. 产生log ID;2. prepare阶段;3. accept阶段。

所以,Mulit-Paxos基于Basic-Paxos做了优化,在Paxos集群中利用Paxos协议选举出唯一的leader,在leader有效期内所有的议案都只能由leader发起。

这里强化了协议的假设:即leader有效期内不会有其他server提出的议案。因此,对于后续的提案,我们可以简化掉产生log ID阶段和Prepare阶段,而是由唯一的leader产生log ID,然后直接执行Accept,得到多数派确认即表示提案达成一致(每条redo log可对应一个提案).

Raft和Multi-Paxos的区别

Raft是基于对Multi-Paxos的两个限制形成的:

发送的请求的是连续的, 也就是说Raft的append 操作必须是连续的, 而Paxos可以并发 (这里并发只是append log的并发, 应用到状态机还是有序的)。
Raft选主有限制,必须包含最新、最全日志的节点才能被选为leader. 而Multi-Paxos没有这个限制,日志不完备的节点也能成为leader。

Raft可以看成是简化版的Multi-Paxos。

Multi-Paxos允许并发的写log,当leader节点故障后,剩余节点有可能都有日志空洞。所以选出新leader后, 需要将新leader里没有的log补全,在依次应用到状态机里。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!