微服務(wù)分布式一致性模式

微服務(wù)拆分后遇到的一個麻煩是分布后的一致性問題恶复。單體架構(gòu)的業(yè)務(wù)處理和數(shù)據(jù)都在一個進程里面,一致性保障很成熟畏鼓,開發(fā)人員基本上不用關(guān)心邮破。當把業(yè)務(wù)系統(tǒng)拆分到不同進程時诈豌,就遇到了技術(shù)性一致性問題。這帶來了糾結(jié)抒和,我們希望有一顆銀彈矫渔,一把解決問題。但由于分布式一致性在(CAP)理論上沒有完美的解決方案摧莽,我們所能選擇的方案是在特定業(yè)務(wù)場景下的選擇庙洼。

我們這里討論的分布是指業(yè)務(wù)邏輯上做了拆分導致的分布,而不是數(shù)據(jù)量特別大導致的分布镊辕。

如果業(yè)務(wù)上不拆分油够,數(shù)據(jù)量特別大需要做分布,可以選擇支持大數(shù)據(jù)的分布式數(shù)據(jù)庫征懈∈В可以選擇Cassandra, MongoDB等NoSQL,或者TiDB這類支持SQL的分布式方案卖哎。

如果業(yè)務(wù)上進行了拆分鬼悠,不論選什么數(shù)據(jù)庫都不能解決分布式一致性問題虏束。把數(shù)據(jù)庫或者分布式數(shù)據(jù)庫看成是一個系統(tǒng),能處理一個外部請求在數(shù)據(jù)庫內(nèi)部的分布式問題厦章,但不能處理多個外部請求的一致性問題。

分布式強一致的數(shù)據(jù)庫不能解決業(yè)務(wù)邏輯拆分帶來的分布式一致性問題照藻,我們還得繼續(xù)糾結(jié)如何解決業(yè)務(wù)分布式一致性的問題袜啃。

首先我把微服務(wù)分布式一致性問題分為數(shù)據(jù)共享一致性和業(yè)務(wù)交易一致性問題。

數(shù)據(jù)共享一致性

在單體架構(gòu)的時候用同一個數(shù)據(jù)庫幸缕,不存在數(shù)據(jù)共享問題群发。微服務(wù)強調(diào)要獨立數(shù)據(jù)庫,引起數(shù)據(jù)如何共享的問題发乔。

數(shù)據(jù)共享分為拉和推兩種模式熟妓,拉指消費者去供應商那邊拉數(shù)據(jù),推指供應商主動把數(shù)據(jù)推到消費者面前栏尚。

拉-視圖共享

對于一般的企業(yè)信息系統(tǒng)起愈,數(shù)據(jù)量不大,并發(fā)需求也不大译仗,我建議所有的微服務(wù)用同一個數(shù)據(jù)庫實例抬虽,但是拆分在不同的Schema。這樣的好處是在業(yè)務(wù)邏輯上數(shù)據(jù)庫是獨立的纵菌,也可以獨立演進阐污。然后數(shù)據(jù)庫又可以集中管理。 這個方案對于大型遺留系統(tǒng)拆分尤其適用咱圆,因為原本就是在一個庫里面笛辟,為了業(yè)務(wù)更好的獨立演進進行數(shù)據(jù)庫Schema拆分,又能延續(xù)原有的數(shù)據(jù)庫實例管理技術(shù)序苏。由于不同的微服務(wù)實際運行在同一個數(shù)據(jù)庫實例上手幢,可以簡單的建視圖進行數(shù)據(jù)共享。 需要注意的是杠览,不要拉整個表出去弯菊,根據(jù)需要選擇幾個字段。這種模式技術(shù)上簡單踱阿,壞處有兩個:一是由于視圖同步的數(shù)據(jù)是實時的管钳,應用可能基于實時同步數(shù)據(jù)的假設(shè)進行設(shè)計,會導致以后做分布式擴展的時候特別困難软舌;二是視圖很容易暴露出表結(jié)構(gòu)才漆,這需要特別加強對視圖的設(shè)計和結(jié)構(gòu)管理给梅,讓暴露出去的視圖不要直接綁定在現(xiàn)有的表結(jié)構(gòu)上褥影。視圖所需的字段是外部需要,而不是表上面有什么礼预。這樣視圖就是接口,只不過是強耦合在特定的數(shù)據(jù)庫實例上鸳玩。

拉-API獲取

微服務(wù)最推薦的方式是服務(wù)方提供數(shù)據(jù)API阅虫,消費者需要的時候去拉取。好處是消費者和供應方技術(shù)上完全解耦不跟,壞處是提高了開發(fā)成本颓帝。如果消費者使用API方式獲取所需數(shù)據(jù),建議使用異步Stream方式進行編程窝革。 如果一次業(yè)務(wù)請求需要拉取多個數(shù)據(jù)源购城,不建議用同步的方式調(diào)用,因為會延長處理時間虐译。建議使用reactiveX模式進行異步拉取和組裝 瘪板。

推-事件消息

發(fā)生事件時發(fā)送消息是DDD CQRS模式,既解決了消費者要擁有數(shù)據(jù)用的爽快的問題(根據(jù)需要建立本地數(shù)據(jù)結(jié)構(gòu)漆诽、獲取性能和方式), 也解決了數(shù)據(jù)庫技術(shù)異構(gòu)的問題侮攀。帶來的問題是需要一個消息平臺,并且消費者或者供應方都要耦合在一個消息平臺技術(shù)上拴泌。對于大型遺留系統(tǒng)改造不是很友好魏身,一方面遺留系統(tǒng)的消息平臺往往不符合高并發(fā)大數(shù)據(jù)量的性能要求,另一方面對于新的微服務(wù)也不想依賴老的消息平臺蚪腐,而想要用Kafka這樣的互聯(lián)網(wǎng)高并發(fā)輕量的消息平臺箭昵。

數(shù)據(jù)共享一致性選擇總結(jié):

對于遺留系統(tǒng)改造和數(shù)據(jù)量不大(日交易量不超過百萬)的應用,建議使用不同微服務(wù)創(chuàng)建不同Schema回季,但用同一個數(shù)據(jù)庫實例家制,然后通過視圖的方式進行數(shù)據(jù)共享。

如果有些業(yè)務(wù)數(shù)據(jù)量非常大又需要共享泡一,使用API共享颤殴,利用異步Stream編程進行數(shù)據(jù)共享。

如果微服務(wù)平臺技術(shù)設(shè)施成熟鼻忠,可以使用推送事件消息模式涵但, 即解決共享數(shù)據(jù)消費便利性問題,又解決數(shù)據(jù)結(jié)構(gòu)解耦帖蔓,并且使用輕量消息平臺(Kafka)只是有輕度的技術(shù)耦合矮瘟。

業(yè)務(wù)交易分布式一致性

業(yè)務(wù)交易分布式一致性指一次請求,但分布在不同的微服務(wù)系統(tǒng)處理塑娇,引發(fā)一致性協(xié)調(diào)的問題澈侠。

交易分布式一致性分為補償模式,二次提交模式和Saga模式埋酬。

補償模式

補償模式主要是通過重試達到最后的成功哨啃,僅適用于交易請求在業(yè)務(wù)上必須沒有失敗的場景烧栋。

補償模式用的最普遍的是消息投遞,假設(shè)給A發(fā)消息拳球,如果沒有收到A確認消息已收到审姓,就繼續(xù)發(fā)送,直到A確認收到消息為止祝峻。

有很多業(yè)務(wù)可以變成必須成功的交易邑跪。比如下訂單付款,如果先確認訂單再去扣款呼猪,就有可能因為賬戶沒錢扣款不成功,導致業(yè)務(wù)上的失敗砸琅。如果業(yè)務(wù)改成先扣款再去確認訂單宋距,那可以認為訂單必須要確認成功。通過業(yè)務(wù)順序的調(diào)整來實現(xiàn)一個交易必須成功的情境症脂。在技術(shù)實現(xiàn)上比較簡單谚赎,利用一個任務(wù)隊列跟蹤任務(wù)的完成狀態(tài),來決定重試诱篷。補償模式對API的要求是必須要冪等壶唤,因為有可能任務(wù)已經(jīng)成功了,但消費者不知道棕所,再次發(fā)出任務(wù)請求闸盔。

二次提交模式

由于補償模式需要對業(yè)務(wù)進行調(diào)整,適用范圍也比較小琳省,我們還是希望有個通用的分布式一致性方案迎吵。

最有名的應該是二次提交模式,更具體點是TCC(Try,Confirm,Cancel)针贬。先發(fā)起try請求讓業(yè)務(wù)任務(wù)參與方做好處理準備击费,等所有的參與方都做好準備后,再發(fā)出confirm進行確認桦他。因為所有的業(yè)務(wù)參與方都事前做好了準備蔫巩,在confirm階段可以確保一次性成功。如果有某個參與方失敗快压,則發(fā)cancel進行回滾圆仔。這種模式和數(shù)據(jù)的事務(wù)管理基本一樣,像Java的JTA實現(xiàn)Automikos就是從支持數(shù)據(jù)庫事務(wù)嗓节,也支持REST API荧缘。二次提交雖然能解決事務(wù)一致性問題,但成本比較高拦宣。一個業(yè)務(wù)處理必須要拆分為準備和確認執(zhí)行兩個階段截粗,對業(yè)務(wù)設(shè)計要求和開發(fā)成本都比較高信姓。

Sagas模式

Sagas模式的確保一致性程度和實現(xiàn)成本在補償模式和二次提交模式之間,既簡單又能廣泛支持分布式事務(wù)場景绸罗。二次提交模式基于悲觀鎖意推,所以先要求任務(wù)參與方都做好準備,然后再做執(zhí)行珊蟀。Saga和補償模式是基于樂觀鎖菊值,先讓任務(wù)參與方執(zhí)行,如果執(zhí)行沒響應則要求再次執(zhí)行育灸。Saga給參與方發(fā)出任務(wù)后會記錄一個event(Saga的中文翻譯可以是事跡)腻窒,所有event都會持久化。如果某個參與方執(zhí)行失敗磅崭,再發(fā)出cancel請求要求所有參與方回退儿子。因為大部分交易請求是成功,這種基于樂觀鎖的協(xié)調(diào)機制能達成一致性目的砸喻,并降低了開發(fā)成本柔逼,業(yè)務(wù)設(shè)計上也比較容易理解。目前支持Saga的Java框架有華為開源的servicecomb saga割岛,京東已經(jīng)有些線上系統(tǒng)用了愉适。還有做CQRS的框架axoniq也實現(xiàn)了saga。

參考文獻

Saga論文

ServiceComb數(shù)據(jù)一致性解決方案Saga演進介紹

Saga模式

文/ThoughtWorks 吳雪峰

更多精彩洞見癣漆,請關(guān)注微信公眾號:ThoughtWorks商業(yè)洞見

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末维咸,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子惠爽,更是在濱河造成了極大的恐慌腰湾,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疆股,死亡現(xiàn)場離奇詭異费坊,居然都是意外死亡,警方通過查閱死者的電腦和手機旬痹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門附井,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人两残,你說我怎么就攤上這事永毅。” “怎么了人弓?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵沼死,是天一觀的道長。 經(jīng)常有香客問我崔赌,道長意蛀,這世上最難降的妖魔是什么耸别? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮县钥,結(jié)果婚禮上秀姐,老公的妹妹穿的比我還像新娘。我一直安慰自己若贮,他們只是感情好省有,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谴麦,像睡著了一般蠢沿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匾效,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天搏予,我揣著相機與錄音,去河邊找鬼弧轧。 笑死,一個胖子當著我的面吹牛碗殷,可吹牛的內(nèi)容都是我干的精绎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼锌妻,長吁一口氣:“原來是場噩夢啊……” “哼代乃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仿粹,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤搁吓,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后吭历,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堕仔,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年晌区,在試婚紗的時候發(fā)現(xiàn)自己被綠了摩骨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡朗若,死狀恐怖恼五,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哭懈,我是刑警寧澤灾馒,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站遣总,受9級特大地震影響睬罗,放射性物質(zhì)發(fā)生泄漏轨功。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一傅物、第九天 我趴在偏房一處隱蔽的房頂上張望夯辖。 院中可真熱鬧,春花似錦董饰、人聲如沸蒿褂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽啄栓。三九已至,卻和暖如春也祠,著一層夾襖步出監(jiān)牢的瞬間昙楚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工诈嘿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堪旧,地道東北人。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓奖亚,卻偏偏與公主長得像淳梦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子昔字,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

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