日常生活中,网络购物、在线支付、地图导航等便捷的应用,人们已经习以为常,以至于我们几(jǐ)乎不会关注其背后的技术。这自然离不开通信网络的飞跃发展,而那些功能的实现则要归功于分布式系统的进步。本文通过网络购票的实例,简要介绍分布式系统的概念,包括其核心的Paxos算法,以及它如何应对网络断开的挑战。
撰文 | 陈清扬
一年一度的春运又到了,据估计,今年铁路客运量或超5.1亿人次,日均1275万人次,人们在比拼手速抢票的背后,12306的计算机系统是如何快速响应海量的请求的呢?单台服务器由于有限的计算能力无法快速响应成千上万的请求,想象一下线下的购票大厅只有一个售票窗口却有一万人排队的场景,人们恐怕都要(yào)带(dài)上(shàng)睡(shuì)袋(dài)来(lái)排(pái)队(duì)了(le)。
那(nà)如(rú)何(hé)加(jiā)速(sù)售(shòu)票(piào)的(de)过(guò)程(chéng)来(lái)减(jiǎn)少(shǎo)人(rén)们(men)的(de)等(děng)待(dài)时(shí)间(jiān)呢(ne)?首(shǒu)先(xiān)窗(chuāng)口(kǒu)的(de)工(gōng)作(zuò)人(rén)员(yuán)可(kě)以(yǐ)加(jiā)快手速,以极快的速度进行操作,但是单个工作人员的手速再快也有一个上限;另一个办法就是在大厅开设多个窗口,同时进行售票。网络售票系统也是一样的,单台服务器处理不过来,就使用多台服务器来进行协同处理,这就需要“分布式系统”登场了!
什么是分布式系统?
通俗地说,分布式系统是指,一群计算机共同完成一个任务。这些计算(suàn)机(jī)也(yě)可(kě)称(chēng)为(wèi)节(jié)点(diǎn),它(tā)们(men)通(tōng)过(guò)网(wǎng)络(luò)连(lián)接(jiē)在(zài)一(yī)起(qǐ),分(fēn)工(gōng)合(hé)作(zuò),但(dàn)对(duì)用(yòng)户(hù)表(biǎo)现(xiàn)得(de)像(xiàng)一(yī)个(gè)整(zhěng)体(tǐ)。不(bù)仅(jǐn)仅(jǐn)是(shì)12306售(shòu)票(piào)系(xì)统(tǒng),你(nǐ)刷(shuā)视频时看(kàn)到(dào)的(de)(de)推(tuī)(tuī)荐(jiàn)(jiàn)、搜(sōu)(sōu)索(suǒ)(suǒ)引(yǐn)(yǐn)擎(qíng)(qíng)给(gěi)(gěi)出(chū)(chū)的(de)(de)搜(sōu)(sōu)索(suǒ)(suǒ)结(jié)(jié)果(guǒ)(guǒ)、外(wài)(wài)卖(mài)(mài)平(píng)台(tái)的(de)订(dìng)单(dān)分(fēn)配(pèi),背(bèi)后(hòu)都(dōu)是(shì)分(fēn)布(bù)式(shì)系(xì)统(tǒng)在(zài)默(mò)默(mò)运(yùn)行(xíng)。相(xiāng)比(bǐ)单(dān)个(gè)服(fú)务(wu)器(qì),使(shǐ)用(yòng)分(fēn)布式系统既能提高系统的性能(néng)、响(xiǎng)应(yīng)请(qǐng)求(qiú)的(de)速(sù)度,又能提供更好的可靠性,部分节点宕机或者断网了,整个系统依然能继续提供服务。
分布式系统虽有这些好处,但是它带来的复杂性也给计算机系统设计提出了挑战。这里就涉及并发(concurrency)以及数据一致(consistency)的问题。以售票为例,试想以下场景,人在北京的张三和人在广州的李四在抢同一张票,张三的抢票请求被分发到了华北地区的某台服务器,而李四的请求被分给了华南地区的某服务器,这俩服务器现在可以同时并行地处理两个人的抢票请求,系统整体的响应速度很快,但是系统如何恰当地协作使得票不会被卖重呢?
此外,分布式系统的另一大特点是存在部分失效(partial failure)的可能性,顾名思义,就是系统部分出现故障,但系统(tǒng)其(qí)他部分仍可运行。分布式系统由众多计算机构成,而且通过网络连接。显然,不管是计算机还是网络本身都有可能出现故障,譬如某处停电了、网线断了,又或是某台计算机操作系统故障,等等。即使一台机器发生故障的概率很低,然而当计算机的数量多了,对于整个系统来说,故障会非常频繁。
我们可(kě)以做一个简单的计算,假设系统中有1000台计算机,每台平均一年只出一次故障(故障可能由任何原因导致),即每天出现故障的概率是1/365;反之,每天不出现故障概率是1-1/365,约等于0.99726。这看起来是一个很大的概率,但是对整个系统而言,每天所有机器都不出故障的概率则是0.99726的1000次方 ,约为0.064。这里还未考虑网络问题,所以对于系统来说,不出故障几乎是不可能的。
因此,在分布式系统的设计中,如何在部分节点故障或者网络断开的情况下,依然提供正常的服务是必须考虑的问题。
分布式系统的基石——共识算法(consensus algorithm)
共识算法(fǎ)在(zài)分(fēn)布(bù)式(shì)系(xì)统(tǒng)中扮演着核心角色,它使得系统在没有共享的内存,只能通过发送消息通信,并且部分节点可能失效的情况下,整个系统依然能够就某个问题达成共识。譬如某一个(gè)特定的座位到底是卖了还是没卖,是卖给了张三还是李四等等,需要系统达成共识才能继续执行。
分布式系统先驱、著名图灵奖得主Leslie Lamport于1990年提出了现代共识算法的基础——Paxos算法。Lamport用Paxos这个名字的缘由很有意思。Paxos本是希腊伊奥尼亚海有着悠久历史的小岛,Lamport想象,考古学家发现在远古时代小岛上有一(yī)个(gè)“业(yè)余(yú)议(yì)会(huì)”(part-time parliament),议(yì)员(yuán)们(men)通(tōng)过(guò)信(xìn)使(shǐ)传(chuán)递(dì)消(xiāo)息(xi)对(duì)议(yì)案(àn)进(jìn)行(xíng)表(biǎo)决(jué),但是信使不可靠,消息可能传递不到或者被延迟,而且议员本身也有不来开会的可能性,在这种情况下,议员们如何对某议案达成一致?在论文中,Lamport使用这个虚构在Paxos小岛的议会为框架,提出了一个在不可靠通信的情况下实现共识的算法,并给出了严格的数学证明。1990年Lamport将论文提交给ACM Transactions on Computer Systems,审稿人表示论文还算是有趣,但看起来并不很重要,而且关于Paxos故事的部分建议去掉。Lamport表示,审稿人怎么这么一点幽默感都没有,并拒绝对论文做任何修改。后来,分布式系统的另一位先驱Butler Lampson读懂了论文,并和Nancy Lynch等(děng)领(lǐng)域大(dà)佬(lǎo)一(yī)起(qǐ)发(fā)表(biǎo)了(le)他(tā)们(men)自(zì)己(jǐ)的(de)证(zhèng)明(míng),此(cǐ)时(shí)Lamport再(zài)次(cì)考(kǎo)虑(lǜ)将(jiāng)论(lùn)文发(fā)表(biǎo),最(zuì)终(zhōng)在(zài)一(yī)众(zhòng)同(tóng)行(xíng)的(de)推(tuī)动(dòng)下(xià),论(lùn)文于(yú)1998年(nián)发(fā)表(biǎo),现(xiàn)在(zài)已(yǐ)经(jīng)成(chéng)为(wèi)分(fēn)布(bù)式(shì)系(xì)统(tǒng)的(de)基(jī)石(shí)。

分(fēn)布(bù)式(shì)系(xì)统(tǒng)先(xiān)驱(qū)Leslie Lamport 丨(gǔn)图(tú)片(piàn)来(lái)源(yuán):wiki
下(xià)面(miàn)我(wǒ)们(men)以(yǐ)卖(mài)票(piào)系(xì)统(tǒng)为(wèi)例(lì),简(jiǎn)述(shù)一(yī)下(xià)Paxos算(suàn)法(fǎ)的(de)思(sī)想(xiǎng),以(yǐ)及(jí)它(tā)如(rú)何(hé)在(zài)节(jié)点(diǎn)失效的情况依然达成共识。为了简化,假设系统中只有3台服务器(节点;3个节点是演示Paxos算法所需的(de)最(zuì)小(xiǎo)数(shù)量),并且只卖一张票(卖多张票也可以理解成反复卖一张票的过程)。此外,我们还需要先简述一下算法的假定。
首先,Paxos算法假定一个节点如果故障则完全停止响应,而不会继续在网络发送错(cuò)误(wù)的(de)消(xiāo)息(xi)以(yǐ)干(gàn)扰(rǎo)系(xì)统(tǒng),它被修复之后会回到系统中继续响应,这种类(lèi)型(xíng)的(de)失(shī)效(xiào)被(bèi)称(chēng)为(wèi)fail-stop(失(shī)败(bài)终(zhōng)止(zhǐ)),即(jí)fail后(hòu)就(jiù)stop了(le)。其(qí)次(cì),Paxos是(shì)一(yī)个(gè)基(jī)于(yú)多(duō)数(shù)派(pài)投(tóu)票(piào)的(de)算(suàn)法(fǎ),即(jí)需(xū)要(yào)多(duō)数(shù)节(jié)点(diǎn)投(tóu)票(piào)通(tōng)过(guò)才(cái)被(bèi)认(rèn)为(wèi)是(shì)共(gòng)识(shi);Paxos需(xū)要(yào)2m+1个(gè)节(jié)点(diǎn)才(cái)能(néng)容(róng)纳(nà)m个(gè)节(jié)点(diǎn)失(shī)效(xiào)。也(yě)就(jiù)是(shì)说(shuō),要(yào)能(néng)够(gòu)容(róng)纳(nà)1个(gè)节(jié)点(diǎn)失(shī)效(xiào),至(zhì)少(shǎo)系(xì)统(tǒng)需(xū)要(yào)有(yǒu)3个(gè)节(jié)点(另外两个正常运行)。如(rú)果(guǒ)超(chāo)出(chū)半(bàn)数(shù)的(de)节(jié)点(diǎn)都(dōu)失(shī)效(xiào),那Paxos算法将无法正常运转。
现在我们给这三台服务器分配一个全局的序号以示区分:1号节点、2号节点和3号节点。Paxos算法会为每个节点分配一个角色,这里假设1号节点是提议者(proposer)也是接受者(acceptor);2号和3号节点是接受者,只接受,不提议。现在1号节点收到了来自张三的购票请求,它开始了算法的第一步:PREPARE-PROMISE。
提议者1号节点首先会为它的提议proposal(即卖票给张三)分配一个唯一的序号(hào)(proposal number)。系(xì)统中所有的提议都会有一个自己独特的序号,一种简单的实现方式是这样:每个节点自(zì)己(jǐ)维(wéi)护(hù)一(yī)个(gè)计(jì)数(shù)器(qì)(counter),初始值为0,每次自己提出新的提议时,计数器加1;新提议的序号设定为由计数器的数值和该节(jié)点(diǎn)的(de)全局(jú)ID所(suǒ)拼(pīn)接(jiē)构(gòu)成(chéng)的(de)小(xiǎo)数(shù),两(liǎng)者(zhě)中(zhōng)间(jiān)用(yòng)小(xiǎo)数(shù)点(diǎn)做(zuò)间(jiān)隔(gé),即(jí){counter}.{ID}。比(bǐ)如(rú)1号(hào)节(jié)(jié)点(diǎn)(diǎn)的(de)(de)第(dì)(dì)一(yī)(yī)个(gè)(gè)提(tí)(tí)议(yì)(yì)的(de)(de)序(xù)(xù)号(hào)(hào)为(wèi)(wèi)1.1,第(dì)(dì)二(èr)(èr)个(gè)提(tí)议(yì)的(de)序(xù)号(hào)则(zé)是(shì)2.1。类似的,2号节点的第一个提议序号为1.2,它的第二个提议的序号则是2.2,以此类推。按照这种序号的设计方式,当提议者1号节点收到张三的请求以后,它首先会发送一条PREAPRE消息给其他所有节点,并且附上提议的序号1.1,这里写作PREPARE(1.1)。
收到提议的接受者们按照以下逻辑进行响应:
1. 查看收到的PREPARE消息所附带的提议序号。
2. 将收到的提议号与自己本地的max_id进行对比。如果更大,则将本地的max_id更新为这个收到的提议号,并返回一条PROMISE消息,相当于告诉提议者:我收到你的消息了,目前你的提议号是最大的哦,准备提议吧,我承诺将不再接受比你的序号小的提议。
3. 如果收到的提议序号小于它本地的max_id,该接受者就不做回复,或者回复一条fail消息,即告诉提议者:你的提议失败。
如果提议者(1号节点)收到了(le)来(lái)自(zì)大(dà)多(duō)数(shù)接(jiē)受(shòu)者(zhě)(自(zì)己(jǐ)也(yě)算(suàn)一(yī)个(gè))返(fǎn)回(huí)的(de)PROMISE消(xiāo)息(xi),这(zhè)时(shí)候(hou)它(tā)就(jiù)知(zhī)道(dào),大(dà)家(jiā)已(yǐ)经(jīng)做(zuò)好(hǎo)准(zhǔn)备(bèi)接(jiē)受(shòu)它(tā)的(de)提(tí)议(yì)了(le)。如(rú)果(guǒ)没(méi)有(yǒu)得(de)到(dào)多(duō)数(shù)人(rén)的(de)答(dá)复(fù),或(huò)者(zhě)收(shōu)到(dào)了(le)一(yī)个(gè)fail消(xiāo)息(xi),提(tí)议(yì)者(zhě)就(jiù)只(zhǐ)能(néng)放(fàng)弃本轮的提议,它可以将自己本地counter加1,然后再次提出新一轮的提议(由于counter加了1,提议号也会加1),重新尝试。当1号节点收到了来自多数节点的PROMISE消息后,它就进入第二步:PROPOSE-ACCEPT。
在第二步中,1号节点会发送一条PROPOSE消息,并且附带上刚才的提议号,以及具体的值(value),这里的值value就是大家希望达成共识的东西,在本文买票的例子中,它的内容就是“张三”,代表票卖给张三。所以1号节点发送的消息是这样:
PROPOSE(1.1, “张三”)
收到消息的接受者们现在要做一个判断,是否接受这个提议,它们的逻辑是这样的:
1. 如(rú)果(guǒ)PROPOSE消(xiāo)(xiāo)息(xi)(xi)里(lǐ)(lǐ)附(fù)(fù)带(dài)的(de)提(tí)议(yì)号(hào)依(yī)然(rán)是(shì)我(wǒ)目(mù)前(qián)收(shōu)到(dào)的(de)最(zuì)大(dà)的(de)(即(jí)和(hé)自(zì)己(jǐ)的(de)max_id进(jìn)行(xíng)对(duì)比(bǐ)),那(nà)就(jiù)接(jiē)受(shòu)这(zhè)个(gè)提(tí)议(yì),并(bìng)且(qiě)返(fǎn)回(huí)一(yī)条(tiáo)ACCEPTED消息;
2. 否则就不返回消息,或者返回fail消息,告诉提议者:提议失败。
如果提议者收到来自大多(duō)数(shù)节点的ACCEPTED消息,那它就知道共识已经达成了。假设现在2号和3号都正常收到了PROPOSE消息,并正常返回了ACCEPTED消息,则所有节点就“票卖给张三”这一状态达成了一致。
总结一下,这里达成共识一共用了两步。第一步的目标在于获得多数人的同意,相当于提议者对每个人喊话:我要进行修改数据了啊,你们同意不同意?只有当获得了多数人的同意之后,才会进行第二步——提议者真正发出要propose的值。
试(shì)想(xiǎng),如(rú)果(guǒ)算(suàn)法(fǎ)跳(tiào)过(guò)第(dì)一(yī)步(bù),直(zhí)接(jiē)发(fā)送(sòng)要(yào)propose的(de)值(zhí),不(bù)同(tóng)的(de)接(jiē)受(shòu)者(zhě)就(jiù)可(kě)能(néng)会(huì)收(shōu)到(dào)来(lái)自(zì)不(bù)同(tóng)提(tí)议(yì)者(zhě)的(de)值(zhí)。而(ér)这(zhè)个(gè)时(shí)候(hou)又(yòu)因(yīn)为(wèi)没(méi)有(yǒu)事(shì)先(xiān)征(zhēng)求(qiú)多(duō)数(shù)的(de)同(tóng)意(yì),最(zuì)后(hòu)接(jiē)收(shōu)者(zhě)也(yě)不(bù)知(zhī)道(dào)自(zì)己(jǐ)收(shōu)到(dào)的(de)值(zhí)是(shì)否(fǒu)就(jiù)代(dài)表(biǎo)了(le)大(dà)多(duō)数(shù)的(de)意(yì)见(jiàn),系(xì)统(tǒng)中(zhōng)可(kě)能(néng)会(huì)有(yǒu)多(duō)个(gè)子(zi)群(qún)体(tǐ)大(dà)家(jiā)各(gè)自(zì)有(yǒu)自(zì)己(jǐ)的(de)值(zhí),这(zhè)(zhè)样(yàng)全局(jú)的(de)共(gòng)识(shi)就(jiù)没(méi)有(yǒu)了(le)。
完(wán)整(zhěng)的(de)Paxos算(suàn)法(fǎ)逻(luó)辑(ji)
到(dào)此(cǐ)为(wèi)止(zhǐ),算(suàn)法(fǎ)的(de)(de)运(yùn)行(xíng)一(yī)切(qiè)正(zhèng)常(cháng),现(xiàn)在(zài)我(wǒ)们(men)再(zài)来(lái)看(kàn)看(kàn)一(yī)些(xiē)更(gèng)加(jiā)复(fù)杂(zá)的(de)情(qíng)况(kuàng)。
假(jiǎ)设(shè)不(bù)光(guāng)1号(hào)节(jié)点(diǎn)是(shì)提(tí)议(yì)者(zhě),2号(hào)节(jié)点(diǎn)因(yīn)收(shōu)到(dào)了(le)李(li)(li)四(sì)(sì)的(de)(de)请(qǐng)(qǐng)求(qiú)(qiú),也(yě)(yě)成(chéng)(chéng)为(wèi)(wèi)了(le)(le)一(yī)(yī)个(gè)(gè)提(tí)(tí)议(yì)(yì)者(zhě)(zhě)(注(zhù)(zhù)意(yì)(yì)所(suǒ)(suǒ)有(yǒu)(yǒu)节(jié)(jié)点(diǎn)(diǎn)都(dōu)是(shì)接(jiē)受(shòu)者(zhě)),现(xiàn)在(zài)系(xì)统(tǒng)里(lǐ)就(jiù)有(yǒu)了(le)两(liǎng)个(gè)不(bù)同(tóng)的(de)提(tí)议(yì)者(zhě),它(tā)们(men)发(fā)送(sòng)的(de)消(xiāo)息(xi)可(kě)能(néng)以(yǐ)任(rèn)何(hé)的(de)方(fāng)式(shì)交(jiāo)织(zhī)在(zài)一(yī)起(qǐ)。
假(jiǎ)设(shè)3号(hào)节(jié)点(diǎn)可(kě)能先收到了来自(zì)1号(hào)节(jié)点(diǎn)的(de)PREPARE消(xiāo)息(xi)(张(zhāng)三(sān)购(gòu)票(piào)),即(jí)PREPARE(1.1),并(bìng)且(qiě)返(fǎn)回(huí)了(le)PROMISE。就(jiù)在(zài)这(zhè)时(shí),它(tā)又(yòu)收(shōu)到(dào)了(le)2号(hào)节(jié)点(diǎn)的(de)PREPARE消(xiāo)息(xi)(李(li)四(sì)购(gòu)票(piào)),即(jí)PREPARE(1.2),因(yīn)为(wèi)提(tí)议(yì)号(hào)1.2大(dà)于(yú)1.1,于(yú)是(shì)它(tā)又(yòu)会(huì)给(gěi)2号(hào)节(jié)点(diǎn)(diǎn)返(fǎn)(fǎn)回(huí)(huí)PROMISE,并(bìng)(bìng)且(qiě)(qiě)将(jiāng)(jiāng)自(zì)(zì)己(jǐ)(jǐ)的(de)(de)max_id更(gèng)(gèng)新(xīn)(xīn)为(wèi)(wèi)1.2。注(zhù)(zhù)意(yì)(yì),1号(hào)(hào)节(jié)(jié)点(diǎn)(diǎn)会(huì)(huì)进(jìn)行(xíng)第(dì)二(èr)步(bù)继(jì)续(xù)发(fā)送PROPOSE消息,PROPOSE(1.1, “张三”) ,但此时3号节点已经不会再接受它的提议了,因为现在对它而言,1.2是更新的提议。只有当2号节点的PROPOSE消息发过来时它才会接受。
再(zài)考(kǎo)虑(lǜ)另(lìng)一(yī)种(zhǒng)情(qíng)况(kuàng)(kuàng),假(jiǎ)(jiǎ)设(shè)(shè)李(li)(li)四(sì)(sì)的(de)(de)操(cāo)(cāo)作(zuò)(zuò)比(bǐ)(bǐ)张(zhāng)(zhāng)三(sān)(sān)慢(màn)(màn)了(le)(le)那(nà)(nà)么(me)(me)一(yī)(yī)点(diǎn)(diǎn)点(diǎn)(diǎn),当(dāng)(dāng)2号(hào)(hào)节(jié)(jié)点(diǎn)(diǎn)成为提议者,并且发送PREPARE(1.2)的时候,3号节点已经接受1号节点的提议了(提议号为1.1),即ACCEPTED消息已经发送。而这时2号节点因为各种原因还没有收到1号节点的PREPARE消息,浑然不知1号和3号已达成共识(票卖给张三(sān))。那(nà)么(me)根(gēn)据(jù)Paxos算(suàn)法,当3号节点收到来自2号的PREPARE(1.2) 消息时,由于1.2是3号见过的最大的提议号,所以它的确会向2号返回一个PROMISE消息,但是因为3号又已经接受此前的提议1.1了,所以在它返回的PROMISE消息中,会附上之前所接受提议(yì)的(de)序(xù)号(hào)以(yǐ)及(jí)值(zhí),即(jí)PROMISE(1.1, “张(zhāng)三(sān)”),即(jí)告(gào)诉(su)2号(hào):我(wǒ)收(shōu)到(dào)你(nǐ)的(de)提(tí)议(yì)号(hào)了(le),它(tā)的(de)确(què)是(shì)最(zuì)新(xīn)的提议,但是我此前已经接受过序号为1.1的提议了,它的内容是“张三”。2号收到该消息,了解到票已经卖出,此时根据Paxos算(suàn)法(fǎ),2号(hào)必(bì)须(xū)将(jiāng)自己要propose的值更改为“张三”,然后继续发送PROPOSE消息,于是所有(yǒu)的(de)节(jié)点(diǎn)依(yī)然(rán)是(shì)达(dá)成(chéng)了(le)共(gòng)识(shi)。
最(zuì)终(zhōng)客(kè)户(hù)端(duān)的李四看到的结果便是:票已售罄。事实上,提议者可能会收到多个带此前接受值的PROMISE消息,它将会选取这些所有PROMISE里面提议序号最大的那个对应的值,作为自己要propose的值,如果没有任何PROMISE消息里带有此前接受的提议信息,提议者则继续用自己原本想propose的值。更新后的接受者和提议者的完整逻辑分别如下图所示。


PREPARE-PROMISE 过程。
这便是完整的Paxos算法。最后我们再来简单考虑下断网或者节点宕机的情况,看看Paxos如何在故障情况下依然能正确运行。
网络或节点失效下的Paxos
不管是提议者还是接受者都有宕机的可能性。当接收者宕机时,实际上对系统运行影响不大,这正是分布式系统的优势:哪怕有一些节点不对PREPARE消息或者PROPOSE消息做任何反应,只要有多数的节点依然在线,系统依然能做出反应,提议者依然能得到多(duō)数(shù)人(rén)的(de)回(huí)复(fù),于(yú)是(shì)算(suàn)法(fǎ)运(yùn)行(xíng)。而(ér)当(dāng)宕(dàng)机的节点死而复生后,他们终究也会通过其他节点发来的带有此前已接受提议信息的PROMISE消息来了解到自己错过的共(gòng)识(shi),在(zài)自(zì)己(jǐ)本(běn)地(de)也(yě)进(jìn)行(xíng)更(gèng)新(xīn)。
那如果提议者(譬如1号节点)宕机呢?分为三种情(qíng)况(kuàng):
1. 假(jiǎ)如(rú)它(tā)在(zài)发(fā)送(sòng)PREPARE消息之前(qián)宕(dàng)机(jī),那(nà)相(xiāng)当(dāng)于(yú)系(xì)统(tǒng)里(lǐ)面(miàn)什(shén)么(me)也(yě)没(méi)有(yǒu)发(fā)生(shēng)。其(qí)他(tā)节(jié)点(diǎn)接(jiē)收(shōu)用(yòng)户(hù)的(de)需(xū)求(qiú)时(shí)会(huì)变(biàn)为(wèi)新(xīn)的(de)提(tí)议(yì)者(zhě);
2. 如(rú)果(guǒ)提(tí)议者在发送PREPARE消息之后宕机,还没来得及发送PROPOSE,如我们刚所说,它的提议会被之后更新的PREPARE所取代(由新的提议者所发出);
3. 如果提议者已经完成了第一步PREPARE-PROMISE,进入了第二步,但是在给部分节点发送PROPOSE消息后宕机,譬如1号在给3号发送完PROPOSE之后宕机,没来得及发给2号;那它的提议将会被3号接受,而2号最终还是会了解到1号和3号达成的共识。因为2号在某时会成为提议者,它终究会收到3号返回的带有此前已接受提议信息的PROMISE消息,并据此来更新自己(jǐ)本(běn)地(de)的(de)信(xìn)息(xi),于(yú)是(shì)与(yǔ)1号(hào)、3号(hào)保(bǎo)持(chí)了(le)一(yī)致(zhì)。
所(suǒ)以(yǐ)最(zuì)后(hòu)回(huí)到(dào)抢(qiǎng)票(piào)上(shàng),当(dāng)我(wǒ)们(men)从(cóng)客(kè)户(hù)端(duān)发(fā)出(chū)买(mǎi)票(piào)请(qǐng)求(qiú)以(yǐ)后(hòu),它(tā)会(huì)和(hé)背(bèi)后(hòu)复(fù)杂的分布式系统进行交互,大家如果(guǒ)抢(qiǎng)不(bù)到(dào)票(piào)并(bìng)不(bù)一(yī)定(dìng)因(yīn)为(wèi)自(zì)己(jǐ)手(shǒu)速(sù)不(bù)够(gòu)快(kuài)(kuài),还(hái)(hái)有(yǒu)(yǒu)可(kě)(kě)能(néng)(néng)是(shì)(shì)网(wǎng)(wǎng)络(luò)延(yán)迟(chí)、连(lián)接(jiē)的(de)服(fú)务(wu)器(qì)宕(dàng)机(jī),或者和系统算法本身的运作有关。
结语
分布式系统作为现代计算机系统的基石,能够支持12306购票这样的高负载、高并发场景。本文讨论了分布式系统中关于一致性与容错性的一些基本概念与技术实现。事实上,分布式系统的应用不只是线上网购,在加密领域,分布式系统为区块链技术提供了基础支持,确保数据的安全性和一致性;在科学计算领域,分布式系统也被用来解决更大规模的问题。这些领域都展示了分布式系统在我们日常生活和技术发展中发挥着不可或缺的作用。最后,春节马上到了,祝大家:春节快乐,阖家幸福!
注:本文封面图(tú)片(piàn)来(lái)自(zì)版(bǎn)权(quán)图(tú)库(kù),转(zhuǎn)载(zài)使(shǐ)用(yòng)可(kě)能(néng)引(yǐn)发(fā)版权纠纷。

特 别 提 示
1. 进入『返朴』微信公众号底部菜单“精品专栏“,可查阅不同主题系列科普文章。
2. 『返朴』提供按月检索文章功能。关注公众号,回复四位数组成的年份+月份,如“1903”,可获取2019年3月的文章索引,以此类推。
版权说明:欢迎个人转发,任何形式的媒体或机构未经授权,不得转载和摘编。转载授权请在「返朴」微信公众号内联系后台。