分布式系統(tǒng)—最后一致性

(此文來自樂字節(jié))

這篇文章我們聊分布式相關(guān)的內(nèi)容徽级。

提到分布式系統(tǒng)气破,就一定繞不開“一致性”,這次我們說說:最終一致性餐抢。

最終一致性是現(xiàn)在大部分高可用的分布式系統(tǒng)的核心思路现使。

估計有人對最終一致性不太熟低匙,先來個簡單介紹:

最終一致性指的是系統(tǒng)中的所有分散在不同節(jié)點的數(shù)據(jù),經(jīng)過一定時間后碳锈,最終能夠達(dá)到符合業(yè)務(wù)定義的一致的狀態(tài)顽冶。

劃重點:

是數(shù)據(jù)一致性,不是事務(wù)一致性(ACID 是事務(wù)一致性)售碳;

存在條件:多個節(jié)點/系統(tǒng)强重;

不一致可能是暫時的,最終要一致(鬼知道“最終”是多久)

好贸人,正文開始间景。

莫看江面平如鏡,要看水底萬丈深

最終一致性艺智,一言以蔽之倘要,過程松,結(jié)果緊十拣。不管中間過程如何封拧,結(jié)果必須符合業(yè)務(wù)需求,滿足數(shù)據(jù)一致性的要求父晶。

雖然哮缺,在實現(xiàn)中,有各種花樣百出的方案甲喝,但是本質(zhì)的思想都是一樣的尝苇。我們現(xiàn)在就來忽略那些亂花迷眼的過程,仔細(xì)探討下最終一致性的本質(zhì)埠胖。

何事居窮道不窮糠溜,亂時還與凈時同

在我剛到樂字節(jié)不久的時候,能力有限直撤,菜鳥一個非竿,只能做一些小的功能模塊。我印象最深的就是訂單模塊谋竖。

用戶下單红柱,訂單模塊收到下單請求后,執(zhí)行對應(yīng)的訂單業(yè)務(wù)邏輯蓖乘。最終锤悄,會把訂單插入到訂單表,并返回下單結(jié)果給用戶嘉抒。用戶結(jié)算后零聚,訂單模塊就會去根據(jù)支付情況去更新訂單狀態(tài)。

就這點事兒,對我這個技術(shù)渣渣來說隶症,開始也著實費了一番手腳政模,不過最終也成了熟手,維護(hù)起這個模塊來也駕輕就熟了蚂会。

這種簡單的小日子過了一陣子后淋样,新任務(wù)來了!

產(chǎn)品經(jīng)理告訴我颂龙,數(shù)據(jù)審計部門想要我維護(hù)的這個訂單模塊在訂單完成后习蓬,能及時分發(fā)一份訂單數(shù)據(jù)給他們纽什。他們提供了一個接口措嵌,讓我直接傳數(shù)據(jù)給他們。

兩個問題出現(xiàn)了:

問題 1:用戶等待時間變長

最簡單的實現(xiàn)就是我更新完訂單數(shù)據(jù)后芦缰,再順序去調(diào)用數(shù)據(jù)審計部門給的接口企巢,把訂單數(shù)據(jù)傳過去。

但是让蕾,從用戶結(jié)算成功到更新訂單狀態(tài)這一系列的流程是同步的浪规,假設(shè)這一系列流程所花費的時間是 n 毫秒。這就意味著探孝,用戶需要等待至少 n 毫秒笋婿。

如果再加上傳給數(shù)據(jù)審計部門的操作時間,假設(shè)為 m 毫秒顿颅,則整個用戶就需要等待就 n+m 毫秒缸濒。

整個功能用戶等待時間成本上升,體驗下降粱腻。如下圖:

問題 2:部分成功庇配,部分失敗

引入新的接口后,某些時候調(diào)用這個接口可能會失敗绍些,比如網(wǎng)絡(luò)問題啊捞慌,驗證問題啊,接口服務(wù)失敗啊柬批,很多原因啸澡。那么問題來了,新接口失敗的時候怎么處理氮帐?

如果訂單更新成功嗅虏,傳給數(shù)據(jù)審計部門的時候失敗了,這種情況會讓訂單模塊的后續(xù)處理變得很尷尬揪漩。

首先你不可能返回給客戶端說你這次結(jié)算失敗了旋恼,請求就沒失敗,你憑什么說人家失敗了?

其次冰更,你又不能說這次業(yè)務(wù)上就是成功的产徊,因為數(shù)據(jù)審計其實還挺重要的,它是業(yè)務(wù)邏輯的重要組成部分蜀细。

真是進(jìn)退兩難舟铜。

我們以前談到過 CAP,知道如果犧牲一定的一致性就可以保證分區(qū)容錯性和可用性奠衔。

而最終一致性則是不能保證同時讓所有的數(shù)據(jù)當(dāng)時都符合業(yè)務(wù)需求谆刨,但是我們能保證任何時候服務(wù)在內(nèi)部出現(xiàn)問題的時候都是可對外服務(wù)的。

四哥我平時喜歡玩游戲归斤,那我們就用一個淘寶買 Switch 的例子痊夭,來解釋最終一致性:

如果你想在淘寶同時買一個 Switch 的數(shù)字版游戲和一臺 Switch,那么你付完錢后脏里,你就可以立刻得到數(shù)字版的游戲她我,但是,對于那臺購買的 Switch迫横,你就要等幾天番舆,等到快遞投遞到家才可以拿到。

來梳理下這個例子的細(xì)節(jié):

首先淘寶上肯定得有個對顧客售賣 Switch 和數(shù)字游戲的商家去接受我們下的訂單矾踱,并給你一個單號恨狈。

你得到了一個數(shù)字版游戲,但是沒拿到 Switch呛讲。

你不知道這個商家背后 Switch 是怎么給你準(zhǔn)備的禾怠,是不是中間他沒貨了還得跑別的商家串貨,又或者沒貨等了兩天才發(fā)給你(延遲發(fā)貨可以給出別的理由圣蝎,不再贅述)刃宵。這些不重要,重要的是你明確對方接單了他就要完成這筆單子徘公。

你下單成功之后牲证,你就有了保障,你最終會拿到你的 Switch关面,只是你可能不太肯定什么時候收到坦袍。

過了幾天,你終于收到貨了等太,恩捂齐,恭喜你成功入坑 Switch。

上面的例子就是我們說的最終一致性缩抡。但是奠宜,這里有個非常非常重要的東西還沒有凸顯出來,即到底是什么樣的原因在驅(qū)使我們使用最終一致性?

答案就是數(shù)據(jù)的分發(fā)压真。

紙上得來終覺淺娩嚼,絕知此事要躬行

為什么我們會出現(xiàn)需要最終一致性的情況呢?

因為我們需要把數(shù)據(jù)分發(fā)到不同的地方上去滴肿,而由于分發(fā)數(shù)據(jù)到不同的地方岳悟,就會導(dǎo)致,可能中間分發(fā)過程中出現(xiàn)分發(fā)成功或者失敗的不一致情況泼差,就需要最終一致性這種思路來處理這些情況贵少。

恩,分發(fā)數(shù)據(jù)……OK堆缘,你想到了吧滔灶?

沒錯,通過 MQ 分發(fā)消息就可以處理分發(fā)數(shù)據(jù)的情況套啤,而這正是最終一致性最常用的實現(xiàn)手段宽气。

我們把要分發(fā)的數(shù)據(jù)打包成消息,再發(fā)送給 MQ 中間件潜沦。中間件會廣播這些數(shù)據(jù)給所有想要收到這些消息的服務(wù)。這些收到消息的服務(wù)就根據(jù)自己的業(yè)務(wù)情況對數(shù)據(jù)進(jìn)行獨立的處理绪氛。 回到我們訂單模塊的那個例子唆鸡,我們可以采用兩種方式使用最終一致性。

先插入數(shù)據(jù)庫枣察,后發(fā)消息給數(shù)據(jù)審計

這個方式争占,訂單模塊先更新訂單狀態(tài)。然后序目,把訂單數(shù)據(jù)打包成消息發(fā)送到 MQ 中臂痕,訂單模塊的任務(wù)就結(jié)束了。剩下的任務(wù)就是由數(shù)據(jù)審計部門根據(jù)自己的業(yè)務(wù)猿涨,從 MQ 中獲取消息后進(jìn)行對應(yīng)的處理握童。

這個方法里,我們既保證數(shù)據(jù)庫更新成功也保證數(shù)據(jù)被發(fā)送到了 MQ 中叛赚。最終澡绩,當(dāng)數(shù)據(jù)審計部門收到消息并根據(jù)消息內(nèi)容做完對應(yīng)的處理后,則整體數(shù)據(jù)達(dá)到最終一致的狀態(tài)俺附。

只插入到 MQ 中

這個方式肥卡,訂單模塊直接收到請求后,將數(shù)據(jù)打包成消息放入到 MQ 中事镣。

然后步鉴,再由訂單模塊自己和數(shù)據(jù)審計部門的服務(wù)分別從 MQ 中拿到對應(yīng)的消息,再各自根據(jù)自己的業(yè)務(wù)邏輯該更新數(shù)據(jù)庫的更新數(shù)據(jù)庫,該走自己的審計的走自己的審計氛琢,最終達(dá)到一致的狀態(tài)只嚣。

小荷才露尖尖角,早有蜻蜓立上頭

在以上的例子中,我們描述了最終一致性的核心思路艺沼,不保證數(shù)據(jù)狀態(tài)能實時滿足業(yè)務(wù)要求册舞,但是就像我們在線購物一樣,我們能保證在間隔了一段時間窗口后肯定能滿足業(yè)務(wù)需求障般。

然而调鲸,雖然說起來簡單,但是世間上的事情又哪里那么容易呢挽荡?根據(jù)業(yè)務(wù)的不同藐石,最終一致性分化出了多種實現(xiàn)思路。比如:

重試 + 逆向模式

在我們做支付時定拟,需要記賬于微,當(dāng)記賬不成功時,我們可能希望能盡可能的重試青自。當(dāng)重試達(dá)到某種限制后株依,甚至我們還要通知上游系統(tǒng)去提供一個重試和取消接口,讓下游能通知上游重發(fā)消息延窜,或者先暫時取消操作恋腕。

補(bǔ)救任務(wù)模式

在我們做支付記賬失敗了,我們又嘗試了重試 + 逆向模式取消了操作逆瑞,那么此時就可以創(chuàng)建一個補(bǔ)救任務(wù)荠藤,等到后期可以保證記賬成功的時候去執(zhí)行這個任務(wù)。

異步消息模式

在我們做轉(zhuǎn)賬的時候获高,我們肯定是要保證 A 轉(zhuǎn)出后 B 轉(zhuǎn)入這種業(yè)務(wù)是強(qiáng)一致性的哈肖。然而,可能此時又需要跨服務(wù)念秧。同時淤井,我們還想盡量保證性能。

那么出爹,這個時候我們就可以先把本地對數(shù)據(jù)庫的寫操作和要跨服務(wù)的消息做成事務(wù)庄吼,然后,后期再根據(jù)消息被處理的狀態(tài)做整體事務(wù)的提交和回滾严就。

可以看到总寻,最終一致性的實現(xiàn)方式是多種多樣的,但是梢为,它始終逃不過一個核心渐行,通過消息隊列分發(fā)數(shù)據(jù)轰坊。在明白了這個根本原則后,以后我們理解各種各樣的分布式事務(wù)祟印,分布式共識等就會容易許多了肴沫。

PS:自學(xué)視頻阿里P8強(qiáng)烈推薦的8個Java項目實戰(zhàn)大合集B站:BV1J64y1R7UN

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蕴忆,隨后出現(xiàn)的幾起案子颤芬,更是在濱河造成了極大的恐慌,老刑警劉巖套鹅,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件站蝠,死亡現(xiàn)場離奇詭異,居然都是意外死亡卓鹿,警方通過查閱死者的電腦和手機(jī)菱魔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吟孙,“玉大人澜倦,你說我怎么就攤上這事〗芗耍” “怎么了藻治?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長稚失。 經(jīng)常有香客問我栋艳,道長,這世上最難降的妖魔是什么句各? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮晴叨,結(jié)果婚禮上凿宾,老公的妹妹穿的比我還像新娘。我一直安慰自己兼蕊,他們只是感情好初厚,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著孙技,像睡著了一般产禾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上牵啦,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天亚情,我揣著相機(jī)與錄音,去河邊找鬼哈雏。 笑死楞件,一個胖子當(dāng)著我的面吹牛衫生,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播土浸,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼罪针,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了黄伊?” 一聲冷哼從身側(cè)響起泪酱,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎还最,沒想到半個月后墓阀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡憋活,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年岂津,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悦即。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡吮成,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出辜梳,到底是詐尸還是另有隱情粱甫,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布作瞄,位于F島的核電站茶宵,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宗挥。R本人自食惡果不足惜乌庶,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望契耿。 院中可真熱鬧瞒大,春花似錦、人聲如沸搪桂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽踢械。三九已至酗电,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間内列,已是汗流浹背撵术。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留德绿,地道東北人荷荤。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓退渗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蕴纳。 傳聞我的和親對象是個殘疾皇子会油,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

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