參考:http://www.infoq.com/cn/articles/raft-paper#
領(lǐng)導(dǎo)選舉:
當(dāng)服務(wù)器啟動(dòng)時(shí)绪励,它們會(huì)初始化為追隨者汤求。
追隨者服務(wù)器會(huì)一直保持追隨者的狀態(tài)只要它們能夠收到來(lái)自領(lǐng)導(dǎo)人或者候選人的有效 RPC。
領(lǐng)導(dǎo)人會(huì)向所有追隨者周期性發(fā)送心跳(heartbeat呀伙,不帶有任何日志條目的 AppendEntries RPC)來(lái)保證它們的領(lǐng)導(dǎo)人地位。
如果一個(gè)追隨者在一個(gè)周期內(nèi)沒(méi)有收到心跳信息,就叫做選舉超時(shí)(election timeout),然后它就會(huì)假定沒(méi)有可用的領(lǐng)導(dǎo)人并且開(kāi)始一次選舉來(lái)選出一個(gè)新的領(lǐng)導(dǎo)人日丹。
為了開(kāi)始選舉,一個(gè)追隨者會(huì)自增它的當(dāng)前任期并且轉(zhuǎn)換狀態(tài)為候選人蚯嫌。然后哲虾,它會(huì)給自己投票并且給集群中的其他服務(wù)器發(fā)送 RequestVote RPC丙躏。
一個(gè)候選人會(huì)一直處于該狀態(tài),直到下列三種情形之一發(fā)生:
- 它贏得了選舉束凑;
- 另一臺(tái)服務(wù)器贏得了選舉晒旅;
- 一段時(shí)間后沒(méi)有任何一臺(tái)服務(wù)器贏得了選舉
情況1:一個(gè)候選人如果在一個(gè)任期內(nèi)收到了來(lái)自集群中大多數(shù)服務(wù)器的投票就會(huì)贏得選舉。按照先到先服務(wù)原則汪诉,一臺(tái)服務(wù)器最多能給一個(gè)候選人投票废恋。一旦有一個(gè)候選人贏得了選舉,它就會(huì)成為領(lǐng)導(dǎo)人扒寄。然后它會(huì)像其他服務(wù)器發(fā)送心跳信息來(lái)建立自己的領(lǐng)導(dǎo)地位并且組織新的選舉鱼鼓。
情況2:當(dāng)一個(gè)候選人等待別人的選票時(shí),它有可能會(huì)收到來(lái)自其他服務(wù)器發(fā)來(lái)的聲明其為領(lǐng)導(dǎo)人的 AppendEntries RPC旗们。如果這個(gè)領(lǐng)導(dǎo)人的任期(包含在它的 RPC 中)比當(dāng)前候選人的當(dāng)前任期要大蚓哩,則候選人認(rèn)為該領(lǐng)導(dǎo)人合法,并且轉(zhuǎn)換自己的狀態(tài)為追隨者上渴。如果在這個(gè) RPC 中的任期小于候選人的當(dāng)前任期岸梨,則候選人會(huì)拒絕此次 RPC, 繼續(xù)保持候選人狀態(tài)稠氮。
情形3:是一個(gè)候選人既沒(méi)有贏得選舉也沒(méi)有輸?shù)暨x舉:如果許多追隨者在同一時(shí)刻都成為了候選人曹阔,選票會(huì)被分散,可能沒(méi)有候選人能獲得大多數(shù)的選票隔披。當(dāng)這種情形發(fā)生時(shí)赃份,每一個(gè)候選人都會(huì)超時(shí),并且通過(guò)自增任期號(hào)和發(fā)起另一輪 RequestVote RPC 來(lái)開(kāi)始新的選舉奢米。然而抓韩,如果沒(méi)有其它手段來(lái)分配選票的話,這種情形可能會(huì)無(wú)限的重復(fù)下去鬓长。
每一個(gè)候選人在開(kāi)始一次選舉的時(shí)候會(huì)重置一個(gè)隨機(jī)的選舉超時(shí)時(shí)間谒拴,在超時(shí)進(jìn)行下一次選舉之前一直等待。
選舉是一個(gè)理解性引導(dǎo)我們?cè)O(shè)計(jì)替代算法的一個(gè)例子涉波。最開(kāi)始時(shí)英上,我們計(jì)劃使用一種排名系統(tǒng):給每一個(gè)候選人分配一個(gè)唯一的排名,用于在競(jìng)爭(zhēng)的候選人之中選擇領(lǐng)導(dǎo)人啤覆。如果一個(gè)候選人發(fā)現(xiàn)了另一個(gè)比它排名高的候選人苍日,那么它會(huì)回到追隨者的狀態(tài),這樣排名高的候選人會(huì)很容易地贏得選舉窗声。但是我們發(fā)現(xiàn)這種方法在可用性方面有一點(diǎn)問(wèn)題(一個(gè)低排名的服務(wù)器在高排名的服務(wù)器宕機(jī)后相恃,需要等待超時(shí)才能再次成為候選人,但是如果它這么做的太快嫌佑,它能重置選舉領(lǐng)帶人的過(guò)程)豆茫。我們對(duì)這個(gè)算法做了多次調(diào)整侨歉,但是每次調(diào)整后都會(huì)出現(xiàn)一些新的問(wèn)題。最終我們認(rèn)為隨機(jī)重試的方法是更明確并且更易于理解的揩魂。
日志復(fù)制
一旦選出了領(lǐng)導(dǎo)人幽邓,它就開(kāi)始接收客戶端的請(qǐng)求。每一個(gè)客戶端請(qǐng)求都包含一條需要被復(fù)制狀態(tài)機(jī)(replicated state machine)執(zhí)行的命令火脉。領(lǐng)導(dǎo)人把這條命令作為新的日志條目加入到它的日志中去牵舵,然后并行的向其他服務(wù)器發(fā)起 AppendEntries RPC ,要求其它服務(wù)器復(fù)制這個(gè)條目倦挂。當(dāng)這個(gè)條目被安全的復(fù)制之后(下面的部分會(huì)詳細(xì)闡述)畸颅,領(lǐng)導(dǎo)人會(huì)將這個(gè)條目應(yīng)用到它的狀態(tài)機(jī)中,并且會(huì)向客戶端返回執(zhí)行結(jié)果方援。如果追隨者崩潰了或者運(yùn)行緩慢或者是網(wǎng)絡(luò)丟包了没炒,領(lǐng)導(dǎo)人會(huì)無(wú)限的重試 AppendEntries RPC(甚至在它向客戶端響應(yīng)之后)直到所有的追隨者最終存儲(chǔ)了所有的日志條目。
參考:http://blog.csdn.net/dapangzi88/article/details/54866422
Raft 的目標(biāo)是將日志完整地復(fù)制到集群內(nèi)的所有服務(wù)器犯戏,這些復(fù)制的日志會(huì)被狀態(tài)機(jī)所使用送火。假設(shè)我們希望程序或應(yīng)用能可靠地執(zhí)行,能夠?qū)崿F(xiàn)的一種方式是保證集群中所有服務(wù)器內(nèi)的狀態(tài)機(jī)都能按照相同的方式執(zhí)行命令先匪,這就是狀態(tài)機(jī)復(fù)制同步的目的种吸,這里的狀態(tài)機(jī)通常指的是一個(gè)輸入輸出程序或應(yīng)用。日志可以保證狀態(tài)機(jī)執(zhí)行相同的命令呀非。下面介紹它的運(yùn)作機(jī)制坚俗。
如果系統(tǒng)的客戶端將要執(zhí)行的命令傳遞給集群中的一臺(tái)服務(wù)器,假設(shè)命令是 X 岸裙,那么它會(huì)被該臺(tái)服務(wù)器記錄猖败,然后命令會(huì)被發(fā)送到其他服務(wù)器,并被其他服務(wù)器上的日志所記錄降允。一旦命令被安全的復(fù)制到日志中辙浑,那么它們就能被發(fā)送到狀態(tài)機(jī)供執(zhí)行。當(dāng)其中的一臺(tái)狀態(tài)機(jī)完成了命令的執(zhí)行拟糕,結(jié)果會(huì)被返回給客戶端【胩撸可以注意到只要各個(gè)服務(wù)器上的日志是相同的送滞,各個(gè)服務(wù)器上的狀態(tài)機(jī)就能以相同的順序執(zhí)行相同的命令,這樣它們執(zhí)行的結(jié)果也都是一樣的辱挥。所以共識(shí)性模塊的任務(wù)就是管理這些日志犁嗅,并保證它們正確的在集群內(nèi)復(fù)制并且決定何時(shí)將命令傳送給狀態(tài)機(jī)才是安全的。
普通操作比較簡(jiǎn)單晤碘,客戶端將命令發(fā)送給領(lǐng)導(dǎo)者褂微,領(lǐng)導(dǎo)者首先將命令寫(xiě)入它自己的日志中功蜓,然后向所有其他的跟隨者發(fā)送 AppendEntries 的遠(yuǎn)程調(diào)用。通常這些調(diào)用的消息會(huì)被同時(shí)發(fā)送所有服務(wù)器宠蚂,以并行的方式執(zhí)行式撼,并等待這些消息的響應(yīng)。一旦領(lǐng)導(dǎo)者收到足夠多的響應(yīng)求厕,可以它認(rèn)為該條命令已經(jīng)在多數(shù)服務(wù)器上處于已提交狀態(tài)時(shí)著隆,那么該條命令就可以被執(zhí)行。領(lǐng)導(dǎo)者這時(shí)會(huì)將命令發(fā)送給狀態(tài)機(jī)呀癣,當(dāng)執(zhí)行結(jié)束后美浦,它會(huì)將結(jié)果返回給客戶端。不僅如此项栏,一旦服務(wù)器知道某個(gè)記錄已經(jīng)處于提交狀態(tài)浦辨,它就會(huì)通過(guò)后續(xù)的 AppendEntries 遠(yuǎn)程調(diào)用告知其他的服務(wù)器。所以最終沼沈,每個(gè)跟隨者都會(huì)知道該記錄已提交流酬,并且將該命令發(fā)送至自己本地的狀態(tài)機(jī)執(zhí)行。如果跟隨者崩潰了或處于慢響應(yīng)狀態(tài)庆冕,領(lǐng)導(dǎo)者會(huì)反復(fù)重試這個(gè)調(diào)用康吵,直到跟隨者恢復(fù)后,領(lǐng)導(dǎo)者就能重試成功访递。但是領(lǐng)導(dǎo)者并不需要等待每個(gè)跟隨者的響應(yīng)晦嵌,它只需要等到足夠數(shù)量的響應(yīng),保證記錄已被大多數(shù)服務(wù)器存儲(chǔ)即可拷姿。所以這樣就能在一般情況下獲得很好的性能提升惭载。也就是說(shuō),在通常情況下响巢,只需要獲得大多數(shù)最快的服務(wù)器的應(yīng)答描滔,領(lǐng)導(dǎo)者就可以立即執(zhí)行命令,并將結(jié)果返回至客戶端踪古。例如含长,如果某個(gè)服務(wù)器很慢,這并不能影響客戶端獲得響應(yīng)的速度伏穆,因?yàn)轭I(lǐng)導(dǎo)者并不需要一直等待該臺(tái)服務(wù)器拘泞。
領(lǐng)導(dǎo)選舉時(shí)leader crash時(shí)?
參考:https://www.cnblogs.com/mindwind/p/5231986.html
Raft 要求 RPC 請(qǐng)求實(shí)現(xiàn)冪等性枕扫,也就是要實(shí)現(xiàn)內(nèi)部去重機(jī)制陪腌。