分布式系統(tǒng)基礎(chǔ)-State Machine

在研究Raft算法的時候般婆,看到其是使用狀態(tài)機實現(xiàn)的到腥,于是找了一篇論文,了解了一下狀態(tài)機.

論文原文為Implementing Fault-Tolerant Services Using the State Machine Approach:A Tutorial.這篇文章是作者在讀了論文之后的一些心得蔚袍,一些體會.所以不會跟論文中那樣詳細(xì)乡范,來證明一些公式.當(dāng)然配名,作者的水平有限,理解的跟作者的意思還是有一些差距的晋辆,所以渠脉,希望讀者還是要讀原文,防止作者誤人子弟.

狀態(tài)機

顧名思義瓶佳,狀態(tài)機就是關(guān)于狀態(tài)的一種機器芋膘,其由狀態(tài)變量以及狀態(tài)命令組成,狀態(tài)命令用于改變狀態(tài)機的狀態(tài).狀態(tài)機的三個組件為:

  • client. client向狀態(tài)機發(fā)送一個請求霸饲,要求狀態(tài)機執(zhí)行一條狀態(tài)命令
  • 狀態(tài)機.狀態(tài)機負(fù)責(zé)執(zhí)行狀態(tài)命令为朋,維護(hù)狀態(tài)信息
  • output. output負(fù)責(zé)狀態(tài)機處理結(jié)果的輸出

狀態(tài)機從宏觀上就包含這三個組件,但是我們在提到狀態(tài)機時贴彼,往往指的只是其中負(fù)責(zé)執(zhí)行狀態(tài)命令潜腻,維護(hù)狀態(tài)信息的狀態(tài)機.相當(dāng)于一臺計算機的操作系統(tǒng).

狀態(tài)機在執(zhí)行client發(fā)送來的請求時埃儿,有這樣的原則:

  • 同一個client發(fā)送來的請求器仗,需要按序執(zhí)行
  • 有因果關(guān)系的請求,需要按序執(zhí)行

如果你讀過我前一篇關(guān)于Lamport Clock的文章童番,你會發(fā)現(xiàn)精钮,這不就是要求做到局部有序性嘛.跟Lamport Clock中的局部有序性的定義一樣一樣的.

如果狀態(tài)機的初始狀態(tài)相同,執(zhí)行相同的狀態(tài)命令序列剃斧,結(jié)束狀態(tài)應(yīng)該也相同.也就是說轨香,狀態(tài)機的輸出,應(yīng)該只跟執(zhí)行的狀態(tài)命令序列有關(guān)幼东,跟操作系統(tǒng)臂容,時間等沒有關(guān)系.

下面是一個狀態(tài)機的例子.client輪詢傳感器的值,發(fā)送給狀態(tài)機根蟹,狀態(tài)機進(jìn)行處理脓杉,并發(fā)送給actuator:

monitor:
    process
        do true -> val := sensor;
            <pc.adjust, val>;
            delay D
        od
    end monitor
pc: state_machine
    var q:real;
    
    adjust:
        command(sensor_val:real)
        q := F(q, sensor_val);
        send q to actuator
        end adjust
    end pc

如果我們把讀取傳感器的值并發(fā)送給狀態(tài)機的這個操作,放在狀態(tài)機內(nèi)部简逮,也就是pc內(nèi)部中球散,那么這就不是一個狀態(tài)機了.因為這樣就沒有client了.

分布式系統(tǒng)中的兩種錯誤

  • 拜占庭式錯誤.拜占庭式錯誤指的是,狀態(tài)機可能發(fā)生任何錯誤散庶,比如蕉堰,客戶端發(fā)送給狀態(tài)機的請求由于網(wǎng)絡(luò)延時而無序到達(dá),又比如悲龟,客戶端發(fā)送給狀態(tài)機的請求被修改.本來是要修改狀態(tài)機中變量a的值為1屋讶,結(jié)果被篡改為修改變量a的值為2.
  • Fail-stop Failures. 這種錯誤指的是,當(dāng)發(fā)生了錯誤時须教,組件會處于失敗狀態(tài)皿渗,別的組件可以檢測到其發(fā)生了錯誤.這種錯誤并不會有請求被篡改的這種問題.

我們后面的討論也是建立在這兩種錯誤的基礎(chǔ)上的.

容錯性狀態(tài)機

如果我們要讓狀態(tài)機的可容錯率為t,那么我們應(yīng)該有多少個狀態(tài)機呢?

先看最簡單的情況,即我們假設(shè)只會發(fā)生Fail-stop Failures這個錯誤.那么很簡單羹奉,我們需要有t+1個狀態(tài)機.這樣秒旋,即使t個狀態(tài)機發(fā)生了錯誤,我們還是會通過剩下的那一個正確的狀態(tài)機獲取正確的結(jié)果.

再看另一種情況诀拭,就是我們假設(shè)會發(fā)生拜占庭式錯誤.我們在獲取狀態(tài)機的值的時候迁筛,是需要聚合全部狀態(tài)機的對應(yīng)的值的.比如說,要獲取狀態(tài)機中變量a的值耕挨,我們需要獲取全部狀態(tài)機中變量a的值细卧,然后進(jìn)行合并,假設(shè)有5臺狀態(tài)機筒占,三臺的值為1,兩臺的值為2,那么我們會認(rèn)為1為正確的值.也就是說贪庙,我們總共需要2t+1臺狀態(tài)機.+1是因為我們認(rèn)為占多數(shù)的值為正確的值.

要實現(xiàn)容錯性狀態(tài)機,我們需要保證以下條件:
Replica Coordination: 全部的狀態(tài)機都收到并且處理相同的請求序列

我們可以進(jìn)一步將其拆分成下面兩條:

  • Agreement. 每一臺正常運行的狀態(tài)機翰苫,都會收到每一個請求止邮,不會出現(xiàn)丟失請求的情況
  • Order. 每一臺正常運行的狀態(tài)機,都按相同的相對順序來處理它收到的請求.

注意在Order這一條中奏窑,我們說的是按相同的相對順序导披,我們在對狀態(tài)機的介紹中,也提到了埃唯,狀態(tài)機要求的是局部有序性.這就導(dǎo)致可能會從兩個client撩匕, client1 和 client2中,收到兩個并發(fā)的請求墨叛,有相同的時間戳止毕,假設(shè)為5.Order要求所有的狀態(tài)機,都按照相同的順序來處理這兩條并發(fā)的請求.可以都是先處理client1,然后再處理client2漠趁,也可以都是先處理client2扁凛,然后再處理client1,這是沒有關(guān)系的,因為它們是并發(fā)的請求.只要保證按照相同的順序來處理就好了.

在有些情況下棚潦,我們可以弱化這兩個要求.

比如令漂,如果我們假設(shè)只會發(fā)生Fail-Stop Failure,并且只會收到讀請求,那么Agreement可以被弱化成只要一臺正常運行的狀態(tài)機收到這個讀請求就好啦.很容易理解.

再比如丸边,假設(shè)請求的順序可以是互換的叠必,那么Order就沒有必要滿足.那什么是可以互換的請求呢?如果狀態(tài)機先執(zhí)行請求1再執(zhí)行請求2,和先執(zhí)行請求2,再執(zhí)行請求1,最后得到的狀態(tài)都是一致的妹窖,那么我們就稱這兩個請求是可互換的

比如纬朝,我們處理一個投票請求.假設(shè)每個客戶端最多可以投一次票,并且只有當(dāng)一個候選者獲得大多數(shù)選票時骄呼,才選擇它.那么我們很容易就能知道請求的順序是可以互換的.比如共苛,假設(shè)總共有10個客戶端進(jìn)行投票判没,候選者A和候選者B此時分別得到了4票.由上面的假設(shè),我們很容易地知道隅茎,只有其中一個候選者得到了6票時澄峰,我們才會選擇它.現(xiàn)在還剩下兩票,可能的情況為:都投A,都投B,投A一票投B一票.我們很容易地就能得知辟犀,此時跟選票的順序并沒有什么關(guān)系.此時Order不滿足就沒有關(guān)系.

但是俏竞,我們稍微改變一下假設(shè)的前提條件,那么結(jié)果就是天壤之別了.假設(shè)每個客戶端還是最多可以投一次票堂竟,但是當(dāng)一個候選者不必獲得大多數(shù)選票時魂毁,我們就可以選他.一種情況就是只要一個候選者獲取到一半選票時,我們就可以選它.那么在上面的那個例子中出嘹,我們很容易的就可以得知席楚,結(jié)果是跟順序有關(guān)的.也就是說,選票的順序不是可互換的

我們再假設(shè)候選者還是必須獲得大多數(shù)選票時税稼,我們才可以選他.但是客戶端可以提出不只一個選票.那么在上面的例子中烦秩,假設(shè)到最后的兩個客戶端,我們假設(shè)為客戶端1和客戶端2娶聘,客戶端1提出兩個選票闻镶,其均為投候選者A甚脉,客戶端2也提出兩個選票丸升,其均為投B.很明顯也是不符合可互換性的.

滿足Agreement

我們可以通過引入一個新的組件,稱為transmitter牺氨,它負(fù)責(zé)向其他的組件發(fā)送一個值狡耻,只要滿足以下條件,那么就能滿足Aggrement:

  • 全部的正常運行的processors同意同一個值
  • 如果transmitter正常運行猴凹,那么其他的正常運行的processors均使用它的值作為它們同意的那個值

這種協(xié)議已經(jīng)引起了學(xué)術(shù)界的關(guān)注.目前也已經(jīng)有相應(yīng)的協(xié)議產(chǎn)生了.

我們可以將client作為transmitter,也可以單獨設(shè)置這樣一個組件.但是如果單獨設(shè)置這樣一個組件的話夷狰,我們需要確保請求在發(fā)送到trasmitter的過程中,丟失或者被篡改.我們可以通過讓client也接收transmitter發(fā)送的請求郊霎,來避免這種情況.

滿足Order和Stability

論文原文中沼头,并沒有給出Stability的定義,但是通過下文的一些信息书劝,我認(rèn)為Stability的定義為:如果一個請求是stable的进倍,那么它就會執(zhí)行,否則它不會被執(zhí)行.

那么如何實現(xiàn)Order呢购对?論文中提出了三種方式猾昆,一種是Logical Clock,一種是Synchronized Real-Time Clocks,最后一種是Replica-Generated Identifiers.但是由于最后一種我讀了好幾遍也沒有理解其思想骡苞,想不明白如何實現(xiàn)垂蜗,所以這里我并不會介紹.感興趣的讀者請自行查看原論文.

另外楷扬,對于Logical ClockSynchronized Real-Time Clocks,它們的介紹贴见,這里也不再介紹了.如果有不懂得朋友烘苹,請自行Google,或者查看我的關(guān)于Lamport Logical Clocks的文章片部,其中就包含了這兩種方式.

Logical Clocks

Logical Clocks的實現(xiàn)方式螟加,能夠容錯Fail-stop failure.它的實現(xiàn)方式為,每個客戶端都隔一段時間就給狀態(tài)機發(fā)送一個請求吞琐,可以發(fā)送空請求.那么這個請求有什么作用呢捆探?狀態(tài)機會取出這個請求的時間戳,然后跟本地等待隊列中的請求的時間戳做比較站粟,然后將那些有比全部客戶端發(fā)送的請求的最小的時間戳都小的時間戳的請求黍图,變?yōu)?strong>stable狀態(tài),即讓它們可以被狀態(tài)機讀取執(zhí)行了.

比如說奴烙,狀態(tài)機A的本地等待隊列中助被,有兩個請求,一個時間戳是1,一個時間戳是2.有三個客戶端給狀態(tài)機A發(fā)送了三個請求切诀,它們的時間戳分別是2,3,4.那么狀態(tài)機A的本地等待隊列中揩环,時間戳為1的那個請求,會被轉(zhuǎn)換為stable狀態(tài)幅虑,而時間戳為2的那個請求丰滑,則不會被轉(zhuǎn)換為stable狀態(tài).需要繼續(xù)等待.

關(guān)于其為何能夠容錯Fail-stop failure的證明,請各位朋友自行讀原論文了解.

Synchronized Real-Time Clocks

Synchronized Real-Time Clocks能夠容錯Byzantine Failures.它的實現(xiàn)方式為:

  • 在狀態(tài)機中倒庵,只有一個請求的時間戳比狀態(tài)機的時間戳-最大請求傳輸時間要小時褒墨,才會被轉(zhuǎn)換為stable狀態(tài).
  • 如果在狀態(tài)機中,它收到了一個請求A.并且它還從其他的全部client收到了請求.如果每一個client發(fā)送的請求中擎宝,都有一個時間戳比請求A的時間戳大的請求郁妈,那么請求A就會被轉(zhuǎn)換為stable狀態(tài).

關(guān)于其證明,同樣請各位朋友自行讀原論文了解.

后記

這篇文章中绍申,由于目前有些地方理解的不透徹噩咪,故省略了原論文中的一些內(nèi)容,比如Replica-Generated Identifiers, Tolerating faulty output devices, Tolerating fault clients, configuration, repair errors等.所以极阅,想深入了解其原理的朋友胃碾,務(wù)必讀原論文.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市涂屁,隨后出現(xiàn)的幾起案子书在,更是在濱河造成了極大的恐慌,老刑警劉巖拆又,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件儒旬,死亡現(xiàn)場離奇詭異栏账,居然都是意外死亡,警方通過查閱死者的電腦和手機栈源,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門挡爵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人甚垦,你說我怎么就攤上這事茶鹃。” “怎么了艰亮?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵闭翩,是天一觀的道長。 經(jīng)常有香客問我迄埃,道長疗韵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任侄非,我火速辦了婚禮蕉汪,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘逞怨。我一直安慰自己者疤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布叠赦。 她就那樣靜靜地躺著驹马,像睡著了一般。 火紅的嫁衣襯著肌膚如雪眯搭。 梳的紋絲不亂的頭發(fā)上窥翩,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天,我揣著相機與錄音鳞仙,去河邊找鬼。 笑死笔时,一個胖子當(dāng)著我的面吹牛棍好,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播允耿,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼借笙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了较锡?” 一聲冷哼從身側(cè)響起业稼,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚂蕴,沒想到半個月后低散,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體俯邓,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年熔号,在試婚紗的時候發(fā)現(xiàn)自己被綠了稽鞭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡引镊,死狀恐怖朦蕴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弟头,我是刑警寧澤吩抓,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站赴恨,受9級特大地震影響琴拧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嘱支,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一蚓胸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧除师,春花似錦沛膳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至倚舀,卻和暖如春叹哭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背痕貌。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工风罩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舵稠。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓超升,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哺徊。 傳聞我的和親對象是個殘疾皇子室琢,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)落追,斷路器盈滴,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 可進(jìn)入我的博客查看原文。 Raft 算法是可以用來替代 Paxos 算法的分布式一致性算法轿钠,而且 raft 算法比...
    Jeffbond閱讀 13,294評論 4 91
  • 實時消息協(xié)議---流的分塊 版權(quán)聲明: 版權(quán)(c)2009 Adobe系統(tǒng)有限公司巢钓。全權(quán)所有病苗。 摘要: 本備忘錄描...
    一個人zy閱讀 1,885評論 0 9
  • 開放源代碼已經(jīng)成為一些大型網(wǎng)站的基本原則。而在這些網(wǎng)站成長的過程中竿报,一些優(yōu)秀的實踐經(jīng)驗和規(guī)則也出現(xiàn)在他們的結(jié)構(gòu)中铅乡。...
    零一間閱讀 1,007評論 0 4
  • 一不小心 我被命運之神 踢進(jìn)了萬丈深淵 我本能的掙扎著 痛苦的嚎叫著 并不是有意打擾您 您完全可以視而不見 充...
    呆萌的老張看世界687閱讀 761評論 6 13