轉(zhuǎn)載本文需注明出處:微信公眾號EAWorld,違者必究。
針對分布式架構(gòu)下的數(shù)據(jù)一致性,大家也許會問這樣的問題:跨系統(tǒng)間分布式事務(wù)如何解決?系統(tǒng)內(nèi)多個服務(wù)的分布式事務(wù)如何解決?一個服務(wù)內(nèi)多個數(shù)據(jù)源/數(shù)據(jù)庫的分布式事務(wù)如何解決?……這些問題大家是很容易理解的,但是由于術(shù)語不準確,所以解釋起來會有二義性,所以先要統(tǒng)一語言或者術(shù)語,也就是統(tǒng)一概念:
域是一個虛擬的分類,幾個系統(tǒng)屬于某一個域,例如網(wǎng)上銀行和手機銀行都屬于電子渠道領(lǐng)域;
傳統(tǒng)的單體應(yīng)用,指的就是系統(tǒng),在微服務(wù)架構(gòu)下,單體應(yīng)用采用前后端分離模式,前端一般使用 Nginx,Ngnix 進程間采用主備模式,系統(tǒng)的后端可以分為多個應(yīng)用,每個應(yīng)用有一組對等的應(yīng)用進程(也稱為應(yīng)用實例)提供服務(wù),每個應(yīng)用對應(yīng)一個數(shù)據(jù)庫,實際上在分庫的情況下,有可能一個應(yīng)用對應(yīng)多個數(shù)據(jù)庫。復(fù)雜一點的是網(wǎng)關(guān),網(wǎng)關(guān)由一組對等的網(wǎng)關(guān)實例組成,如果多個系統(tǒng)共享一個網(wǎng)關(guān),網(wǎng)關(guān)和系統(tǒng)就是1對多的關(guān)系,也可以一個系統(tǒng)獨享一個網(wǎng)關(guān),就是一對一情況,下圖是一個概念的示例,使用的是系統(tǒng)獨享網(wǎng)關(guān)模式。
這里,我們看看經(jīng)常問的一些問題:跨系統(tǒng)間分布式事務(wù)、系統(tǒng)內(nèi)多個服務(wù)的分布式事務(wù)、一個服務(wù)內(nèi)多個數(shù)據(jù)源/數(shù)據(jù)庫的分布式事務(wù),這些問題完全是從技術(shù)的角度做歸納,用上述概念應(yīng)該改為:系統(tǒng)間的數(shù)據(jù)一致性、系統(tǒng)內(nèi)應(yīng)用間的數(shù)據(jù)一致性、應(yīng)用內(nèi)部對應(yīng)多數(shù)據(jù)庫的數(shù)據(jù)一致性,另外可以增加一個數(shù)據(jù)庫對應(yīng)多個應(yīng)用的數(shù)據(jù)一致性(技術(shù)上存在可能,但從上述概念上看應(yīng)該是在架構(gòu)上避免的)。
這四個情況如何處理呢?需要我們總結(jié)歸納,我在做總結(jié)歸納的時候,往往希望首先確定原則,這里的原則是從業(yè)務(wù)的角度進行分析,而不是考慮技術(shù)的可能性,因為技術(shù)的可能性無窮無盡,是一個無限組合,理論上任何情況都能發(fā)生,考慮所有情況就是胡扯了,必須根據(jù)業(yè)務(wù)的特征進行歸納。這里,我不叫分布式事務(wù)而是數(shù)據(jù)一致性就是這個道理,從業(yè)務(wù)角度目標是解決分布式情況下的數(shù)據(jù)一致性,而不是技術(shù)角度看的分布式事務(wù)。
有了這個原則,就可以分別分析這四種情況了:
1、系統(tǒng)間的數(shù)據(jù)一致性
需要服務(wù)實現(xiàn) TCC或者業(yè)務(wù)補償模式,由框架(業(yè)務(wù)協(xié)調(diào)器)自動調(diào)用,減少人工參與,或者實現(xiàn)冪等服務(wù),反復(fù)投遞。這兩種方式都沒法做到數(shù)據(jù)的 100% 一致,在失敗的時候都需要有重試的機制,例如補償失敗要重試(這就是框架的好處),多次重試還是失敗,記錄失敗歷史,業(yè)務(wù)上人工處理。不要害怕人工處理,只要減少人工處理的機會就好了,在工行時就是提出人工干預(yù)比例降低若干個百分點作為目標。
2、系統(tǒng)內(nèi)應(yīng)用間的數(shù)據(jù)一致性
這個可以使用華為 SAGA 的模式,也就是建立一個共享的事務(wù)協(xié)調(diào)器模式(雖然我對這個共享方式不喜歡,不是分布式嗎,為啥還搞出一堆集中式的東西,既然如此,為啥應(yīng)用間調(diào)用不能走網(wǎng)關(guān),要直連,說共享不好,到這里就是共享好了),好了,括號里是吐槽,簡單的方式是用共享的事務(wù)協(xié)調(diào)器模式,記錄服務(wù)調(diào)用的事件,在合適的時機調(diào)用TCC和補償服務(wù)。
3、應(yīng)用內(nèi)部對應(yīng)多數(shù)據(jù)庫的數(shù)據(jù)一致性,是個反模式,不要做通用方案
一般來說,一個應(yīng)用對應(yīng)一個數(shù)據(jù)庫,不允許一個應(yīng)用對應(yīng)多個數(shù)據(jù)庫,多個數(shù)據(jù)庫的情況應(yīng)該分成多個應(yīng)用,通過服務(wù)調(diào)用方式解決,這是一個基本原則,否則就是一個反模式設(shè)計。但是,就是有很多人較真,一定問有這個情況你怎么解決,我的回答是架構(gòu)設(shè)計解決這個問題,在技術(shù)上不支持這種方式,讓設(shè)計者必須在架構(gòu)解決,而不是利用技術(shù)手段解決不合理的架構(gòu)設(shè)計,否則后患無窮(這一點還是需要勇氣和堅持的)。空口無憑,實例為證,一般我會舉搶紅包的例子。大家知道,搶紅包的并發(fā)非常高,又有數(shù)據(jù)一致性的要求,無論哪個互聯(lián)網(wǎng)公司,都是根據(jù)紅包 ID,把數(shù)據(jù)路由到一個數(shù)據(jù)庫中,用數(shù)據(jù)庫事務(wù)保證數(shù)據(jù)一致性,在銀行互聯(lián)網(wǎng)賬務(wù)系統(tǒng)(2類 3類戶)的情況,也是把同一賬務(wù)的數(shù)據(jù)路由到不同的數(shù)據(jù)庫中(見下圖)。還會提到一種情況,在分庫分表的時候,如果恰好數(shù)據(jù)分到了不同庫中,恰好要做一個批量的調(diào)整,恰好在一個事務(wù)中,如何解決。我認為這種情況的發(fā)生,恰恰說明設(shè)計有問題,分庫的原則也是按業(yè)務(wù)拆分,不是用技術(shù)手段隨機分解,既然按業(yè)務(wù)拆分,批量處理的時候就應(yīng)該不是一個業(yè)務(wù)上的事務(wù),在技術(shù)上不提供這樣的實現(xiàn),才可以在架構(gòu)設(shè)計考慮問題。不排除在某個系統(tǒng)中可以做一些框架,解決上述問題,但是,這一定不是個通用的方案。
根據(jù)上圖,我們的概念模型是由調(diào)整的,要多一個應(yīng)用分區(qū)的情況:
4、一個數(shù)據(jù)庫對應(yīng)多個應(yīng)用的數(shù)據(jù)一致性
這種情況經(jīng)常也是一個反模式,既然是共享一個數(shù)據(jù)庫,把應(yīng)用放在一起就好了。如果真的有需要(例如一個模塊部署過于頻繁,單獨拆出來做一個應(yīng)用),那也應(yīng)該和多應(yīng)用多數(shù)據(jù)庫一樣處理。
以上,即是我分析的分布式架構(gòu)下幾種不同情況的數(shù)據(jù)一致性控制方式。
關(guān)于作者:焦烈焱,普元信息CTO,致力于技術(shù)創(chuàng)新和金融創(chuàng)新解決方案研究。專注于企業(yè)技術(shù)架構(gòu)領(lǐng)域,對分布式環(huán)境的企業(yè)計算、 企業(yè)信息架構(gòu)的規(guī)劃與實踐有著豐厚經(jīng)驗,帶領(lǐng)普元技術(shù)團隊相繼在云計算、大數(shù)據(jù)及移動開發(fā)領(lǐng)域取得多項突破,并主持中國工商銀行、中國建設(shè)銀行等多家大型企業(yè)技術(shù)平臺的規(guī)劃與研發(fā)。
關(guān)于EAWorld:微服務(wù),DevOps,數(shù)據(jù)治理,移動架構(gòu)原創(chuàng)技術(shù)分享。






