日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

理性撕逼!分布式事務(wù):不過是在一致性、吞吐量和復(fù)雜度之間,做一個選擇

 openlabzeng 2016-10-07
針對微服務(wù)下的交易業(yè)務(wù)如何保障數(shù)據(jù)一致性,本文盡量做到理論結(jié)合實踐,將我們在實際產(chǎn)品中用到的分布式事務(wù)實現(xiàn)機(jī)制,和大家扒一扒,希望能幫到各位。

前言

這是一個開撕的話題,我經(jīng)歷過太多的關(guān)于分布式事務(wù)的需求:“有沒有簡單的方案,像使用數(shù)據(jù)庫事務(wù)那樣,解決分布式數(shù)據(jù)一致性的問題”。特別是微服務(wù)架構(gòu)流行的今天,一次交易需要跨越多個“服務(wù)”、多個數(shù)據(jù)庫來實現(xiàn),傳統(tǒng)的技術(shù)手段,已經(jīng)無法應(yīng)對和滿足微服務(wù)情況下這些復(fù)雜的場景了。

談到分布式事務(wù),必須先把CAP拿出來說說事……,當(dāng)然還有BASE……

從架構(gòu)的角度來看,業(yè)務(wù)拆分(數(shù)據(jù)分區(qū))、數(shù)據(jù)一致性、性能(可用性)永遠(yuǎn)是個平衡的藝術(shù):

  • 在微服務(wù)架構(gòu)下,為了獲得更高的性能與靈活性,將業(yè)務(wù)應(yīng)用拆分為多個,交易跨多個微服務(wù)編排,數(shù)據(jù)一致性的問題產(chǎn)生;

  • 為了解決數(shù)據(jù)一致性問題,需要采用不同的事務(wù)機(jī)制來保障,這又會產(chǎn)生性能(可用性)問題;

在計算機(jī)世界里,為了解決一件事情,另外的問題就會接踵而至,從另一個層面印證了IT架構(gòu)永遠(yuǎn)是一種平衡的藝術(shù)。

“BASE”其核心思想是根據(jù)業(yè)務(wù)特點,采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性(Eventual consistency);在互聯(lián)網(wǎng)領(lǐng)域,通常需要犧牲強(qiáng)一致性來換取系統(tǒng)的高可用性,只需要保證數(shù)據(jù)的“最終一致”,只是這個最終時間需要在用戶可以接受的范圍內(nèi);但在金融相關(guān)的交易領(lǐng)域,仍然需要采用強(qiáng)一致性的方式來保障交易的準(zhǔn)確性與可靠性。

接下來為大家介紹業(yè)界常見的事務(wù)處理模式,包括兩階段提交、三階段提交、Sagas長事務(wù)、補償模式、可靠事件模式(本地事件表、外部事件表)、可靠事件模式(非事務(wù)消息、事務(wù)消息)、TCC等。不同的事務(wù)模型支持不同的數(shù)據(jù)一致性。如果讀者對這幾種分布式事務(wù)比較熟悉,可以直接參考下圖并結(jié)合自身業(yè)務(wù)需求選擇合適的事務(wù)模型。

兩階段提交、三階段提交

這種分布式事務(wù)解決方案目前在各種技術(shù)平臺上已經(jīng)比較成熟:JavaEE架構(gòu)下面的JTA事務(wù)(各應(yīng)用服務(wù)器均提供了實現(xiàn),Tomcat除外)。

但目前兩階段提交、三階段提交存在如下的局限性,并不適合在微服務(wù)架構(gòu)體系下使用:

  • 所有的操作必須是事務(wù)性資源(比如數(shù)據(jù)庫、消息隊列、EJB組件等),存在使用局限性(微服務(wù)架構(gòu)下多數(shù)使用HTTP協(xié)議),比較適合傳統(tǒng)的單體應(yīng)用;

  • 由于是強(qiáng)一致性,資源需要在事務(wù)內(nèi)部等待,性能影響較大,吞吐率不高,不適合高并發(fā)與高性能的業(yè)務(wù)場景;

Sagas長事務(wù)

在Sagas事務(wù)模型中,一個長事務(wù)是由一個預(yù)先定義好執(zhí)行順序的子事務(wù)集合和他們對應(yīng)的補償子事務(wù)集合組成的。典型的一個完整的交易由T1、T2、……、Tn等多個業(yè)務(wù)活動組成,每個業(yè)務(wù)活動可以是本地操作、或者是遠(yuǎn)程操作,所有的業(yè)務(wù)活動在Sagas事務(wù)下要么全部成功,要么全部回滾,不存在中間狀態(tài)。

Sagas事務(wù)模型的實現(xiàn)機(jī)制:

  • 每個業(yè)務(wù)活動都是一個原子操作;

  • 每個業(yè)務(wù)活動均提供正反操作;

  • 任何一個業(yè)務(wù)活動發(fā)生錯誤,按照執(zhí)行的反順序,實時執(zhí)行反操作,進(jìn)行事務(wù)回滾;

  • 回滾失敗情況下,需要記錄待沖正事務(wù)日志,通過重試策略進(jìn)行重試;

  • 沖正重試依然失敗的場景,提供定時沖正服務(wù)器,對回滾失敗的業(yè)務(wù)進(jìn)行定時沖正;

  • 定時沖正依然失敗的業(yè)務(wù),等待人工干預(yù);

Sagas長事務(wù)模型支持對數(shù)據(jù)一致性要求比較高的場景比較適用,由于采用了補償?shù)臋C(jī)制,每個原子操作都是先執(zhí)行任務(wù),避免了長時間的資源鎖定,能做到實時釋放資源,性能相對有保障。

Sagas長事務(wù)方式如果由業(yè)務(wù)去實現(xiàn),復(fù)雜度與難度并存。在我們實際使用過程中,開發(fā)了一套支持Sagas事務(wù)模型的框架來支撐業(yè)務(wù)快速交付。

開發(fā)人員:業(yè)務(wù)只需要進(jìn)行交易編排,每個原子操作提供正反交易;

配置人員:可以針對異常類型設(shè)定事務(wù)回滾策略(哪些異常納入事務(wù)管理、哪些異常不納入事務(wù)管理);每個原子操作的流水是否持久化(為了不同性能可以支持緩存、DB、以及擴(kuò)展其它持久化方式);以及沖正選項配置(重試次數(shù)、超時時間、是否實時沖正、定時沖正等);

Sagas事務(wù)框架:提供事務(wù)保障機(jī)制,負(fù)責(zé)原子操作的流水落地,原子操作的執(zhí)行順序,提供實時沖正、定時沖正、事務(wù)攔截器等基礎(chǔ)能力;

Sagas框架的核心是IBusinessActivity、IAtomicAction。IBusinessActivity完成原子活動的enlist()、delist()、prepare()、commit()、rollback()等操作;IAtomicAction主要完成對狀態(tài)上下文、正反操作執(zhí)行。

限于文章篇幅,本文不對具體實現(xiàn)做詳述;后面找時間可以詳細(xì)介紹基于Sagas長事務(wù)模型具體的實現(xiàn)框架。Sagas長事務(wù)需要交易提供反操作,支持事務(wù)的強(qiáng)一致性,由于沒有在整個事務(wù)周期內(nèi)鎖定資源,對性能影響較小,適合對數(shù)據(jù)要求比較高的場景中使用。

補償模式

Sagas長事務(wù)模型本質(zhì)上是補償機(jī)制的復(fù)雜實現(xiàn),如果實際業(yè)務(wù)場景上不需要復(fù)雜的Sagas事務(wù)框架支撐,可以在業(yè)務(wù)中實現(xiàn)簡單的補償模式。補償過程往往也同樣需要實現(xiàn)最終一致性,需要保證取消服務(wù)至少被調(diào)用一次和取消服務(wù)必須實現(xiàn)冪等性。補償模式可以參見同事田向陽的技術(shù)文章《微服務(wù)架構(gòu)下數(shù)據(jù)一致性保證(三)》http:///3TVJaB

補償機(jī)制不推薦在復(fù)雜場景(需要多個交易的編排)下使用,優(yōu)點是非常容易提供回滾,而且依賴的服務(wù)也非常少,與Sagas長事務(wù)比較來看,使用起來更簡便;缺點是會造成代碼量龐大,耦合性高,對應(yīng)無法提供反操作的交易不適合。

可靠事件模式(本地事件表、外地事件表)

可靠事件模式屬于事件驅(qū)動架構(gòu),當(dāng)某件重要事情發(fā)生時,例如更新一個業(yè)務(wù)實體,微服務(wù)會向消息代理發(fā)布一個事件。消息代理會向訂閱事件的微服務(wù)推送事件,當(dāng)訂閱這些事件的微服務(wù)接收此事件時,就可以完成自己的業(yè)務(wù),也可能會引發(fā)更多的事件發(fā)布。

可靠事件模式在于保證可靠事件投遞和避免重復(fù)消費,靠事件投遞定義為: 

  • 每個服務(wù)原子性的業(yè)務(wù)操作和發(fā)布事件;

  • 消息代理確保事件傳遞至少一次;避免重復(fù)消費要求服務(wù)實現(xiàn)冪等性。 

基于事件模式,需要重點考慮的是事件的可靠到達(dá),在我們產(chǎn)品實際支持過程中,通常有本地事件表、外部事件表兩種模式:

1、本地事件表方法將事件和業(yè)務(wù)數(shù)據(jù)保存在同一個數(shù)據(jù)庫中,使用一個額外的“事件恢復(fù)”服務(wù)來恢復(fù)事件,由本地事務(wù)保證更新業(yè)務(wù)和發(fā)布事件的原子性??紤]到事件恢復(fù)可能會有一定的延時,服務(wù)在完成本地事務(wù)后可立即向消息代理發(fā)布一個事件。

  1. 微服務(wù)在同一個本地事務(wù)中記錄業(yè)務(wù)數(shù)據(jù)和事件;

  2. 微服務(wù)實時發(fā)布一個事件立即通知關(guān)聯(lián)的業(yè)務(wù)服務(wù),如果事件發(fā)布成功立即刪除記錄的事件;

  3. 事件恢復(fù)服務(wù)定時從事件表中恢復(fù)未發(fā)布成功的事件,重新發(fā)布,重新發(fā)布成功才刪除記錄的事件;

其中第2條的操作主要是為了增加發(fā)布事件的實時性,由第三條保證事件一定被發(fā)布。本地事件表方式業(yè)務(wù)系統(tǒng)和事件系統(tǒng)耦合比較緊密,額外的事件數(shù)據(jù)庫操作也會給數(shù)據(jù)庫帶來額外的壓力,可能成為瓶頸。

2、外部事件表方法將事件持久化到外部的事件系統(tǒng),事件系統(tǒng)需提供實時事件服務(wù)以接受微服務(wù)發(fā)布事件,同時事件系統(tǒng)還需要提供事件恢復(fù)服務(wù)來確認(rèn)和恢復(fù)事件。

  1. 業(yè)務(wù)服務(wù)在事務(wù)提交前,通過實時事件服務(wù)向事件系統(tǒng)請求發(fā)送事件,事件系統(tǒng)只記錄事件并不真正發(fā)送;

  2. 業(yè)務(wù)服務(wù)在提交后,通過實時事件服務(wù)向事件系統(tǒng)確認(rèn)發(fā)送,事件得到確認(rèn)后,事件系統(tǒng)才真正發(fā)布事件到消息代理;

  3. 業(yè)務(wù)服務(wù)在業(yè)務(wù)回滾時,通過實時事件向事件系統(tǒng)取消事件;

  4. 如果業(yè)務(wù)服務(wù)在發(fā)送確認(rèn)或取消之前停止服務(wù)了怎么辦呢?事件系統(tǒng)的事件恢復(fù)服務(wù)會定期找到未確認(rèn)發(fā)送的事件向業(yè)務(wù)服務(wù)查詢狀態(tài),根據(jù)業(yè)務(wù)服務(wù)返回的狀態(tài)決定事件是要發(fā)布還是取消;

該方式將業(yè)務(wù)系統(tǒng)和事件系統(tǒng)獨立解耦,都可以獨立伸縮。但是這種方式需要一次額外的發(fā)送操作,并且需要發(fā)布者提供額外的查詢接口。

基于可靠事件的事務(wù)保障模式可以有很多的變種實現(xiàn),比如對消息可靠性不高的話,可以將本地表的方式換做緩存方式。為了提高消息投遞的效率,可以將多次消息合并為投遞模式。為了提供強(qiáng)一致性的事務(wù)保障,甚至可以將本地消息表持久化(保障發(fā)方法消息可靠落地)+遠(yuǎn)程消息表持久化(保障接收方消息可靠落地)結(jié)合的模式。

在我們的流程產(chǎn)品中針對業(yè)務(wù)和流程的分布式事務(wù)解決方案就采用了多次消息合并投遞+本地緩存+遠(yuǎn)程消息表持久化的模式,接下來為大家介紹具體的使用方式。

使用場景

在實際業(yè)務(wù)項目中通常采用業(yè)務(wù)與流程分布式部署的模式,業(yè)務(wù)系統(tǒng)通過遠(yuǎn)程接口訪問流程引擎,業(yè)務(wù)數(shù)據(jù)同流程數(shù)據(jù)存放到各自的數(shù)據(jù)庫中。

在這種場景中,如果業(yè)務(wù)系統(tǒng)的流程操作和業(yè)務(wù)操作交叉在一起,當(dāng)流程操作成功,而業(yè)務(wù)操作失敗時,就會造成業(yè)務(wù)回滾,而流程在引擎端已經(jīng)創(chuàng)建,導(dǎo)致業(yè)務(wù)系統(tǒng)和流程引擎狀態(tài)不一致。

在業(yè)務(wù)應(yīng)用中對一個事務(wù)中的流程操作采用本地緩存+批量投遞+遠(yuǎn)程落地的模式(如果需要在客戶端確保消息可靠性,可以將本地緩存換成本地表的方式);在流程引擎端在消息投遞來之后,做了消息表落地的工作,保障可靠執(zhí)行。在我們流程產(chǎn)品中流程引擎對外提供的客戶端提供了統(tǒng)一的分布式事務(wù)API,和使用傳統(tǒng)本地事務(wù)一樣進(jìn)行操作,保證了透明性,簡化開發(fā)人員的復(fù)雜度。分布式事務(wù)API支持兩種協(xié)議模式:

  1. HTTP + 二進(jìn)制序列化的模式

  2. WebService模式

后續(xù)我們會增加Restful風(fēng)格的接口。

可靠事件模式在互聯(lián)網(wǎng)公司中有著較大規(guī)模的應(yīng)用,該方式適合的業(yè)務(wù)場景非常廣泛,而且能夠做到數(shù)據(jù)的最終一致性,缺點是該模式實現(xiàn)難度較大,依賴數(shù)據(jù)庫實現(xiàn)可靠性,在高并發(fā)場景下可能存在性能瓶頸,需要在公司層面搭建一套標(biāo)準(zhǔn)的可靠事件框架來支撐。

可靠事件模式(非事務(wù)消息、事務(wù)消息)

可靠事件模式的事件通知可以采用消息的模式來實現(xiàn),其實現(xiàn)原理和本地事件表、外部事件表一致,本文就不在詳述。目前常用的消息框架ActiveMQ、RabbitMQ、Kafka、RocketMQ可以用來作為消息投遞的渠道。注意:Kafka通常不適合,因為Kafka的設(shè)計存在丟消息的場景。

目前市面上支持事務(wù)的消息產(chǎn)品比較少,RocketMQ雖然實現(xiàn)了可靠的事務(wù)模式,但并沒有開源出來、沒有開源出來、沒有開源出來,順便說一下國內(nèi)的開源有太多需要改進(jìn)的空間(關(guān)鍵點不開源,開源后沒有持續(xù)的投入)。

TCC模式

一個完整的TCC業(yè)務(wù)由一個主業(yè)務(wù)服務(wù)和若干個從業(yè)務(wù)服務(wù)組成,主業(yè)務(wù)服務(wù)發(fā)起并完成整個業(yè)務(wù)活動,TCC模式要求從服務(wù)提供三個接口:Try、Confirm、Cancel。

  1. Try:完成所有業(yè)務(wù)檢查

    預(yù)留必須業(yè)務(wù)資源

  2. Confirm:真正執(zhí)行業(yè)務(wù)

    不作任何業(yè)務(wù)檢查;只使用Try階段預(yù)留的業(yè)務(wù)資源;Confirm操作滿足冪等性;

  3. Cancel: 

    釋放Try階段預(yù)留的業(yè)務(wù)資源;Cancel操作滿足冪等性;

整個TCC業(yè)務(wù)分成兩個階段完成:

第一階段:主業(yè)務(wù)服務(wù)分別調(diào)用所有從業(yè)務(wù)的try操作,并在活動管理器中登記所有從業(yè)務(wù)服務(wù)。當(dāng)所有從業(yè)務(wù)服務(wù)的try操作都調(diào)用成功或者某個從業(yè)務(wù)服務(wù)的try操作失敗,進(jìn)入第二階段。

第二階段:活動管理器根據(jù)第一階段的執(zhí)行結(jié)果來執(zhí)行confirm或cancel操作。如果第一階段所有try操作都成功,則活動管理器調(diào)用所有從業(yè)務(wù)活動的confirm操作。否則調(diào)用所有從業(yè)務(wù)服務(wù)的cancel操作。

TCC模式的詳細(xì)描述可以參見同事田向陽的技術(shù)文章《微服務(wù)架構(gòu)下數(shù)據(jù)一致性保證(三)》http:///3TVJaB。

需要注意的是第二階段confirm或cancel操作本身也是滿足最終一致性的過程,在調(diào)用confirm或cancel的時候也可能因為某種原因(比如網(wǎng)絡(luò))導(dǎo)致調(diào)用失敗,所以需要活動管理支持重試的能力,同時這也就要求confirm和cancel操作具有冪等性。

總結(jié)

六種分布式事務(wù)的實現(xiàn)模式從數(shù)據(jù)一致性、事務(wù)級別、吞吐量、實現(xiàn)的復(fù)雜度各有優(yōu)劣,下圖為大家提供選擇依據(jù)。

站在架構(gòu)設(shè)計的角度,針對數(shù)據(jù)一致性需要把業(yè)務(wù)因素考慮進(jìn)來,這有利于團(tuán)隊在技術(shù)上作出更合理的選擇。根據(jù)具體業(yè)務(wù)場景,評估出業(yè)務(wù)對事務(wù)的優(yōu)先級,更有利于作出架構(gòu)上的取舍。我們經(jīng)常接觸的證券、金融、支付等行業(yè),對數(shù)據(jù)一致性要求極高,需要嚴(yán)格的實時保證要求;但對于基于社交類的應(yīng)用場景,可以采用局部實時一致,最終全局一致的能力。因此大家在實踐過程中,一定要把技術(shù)與業(yè)務(wù)結(jié)合,選擇適合自身業(yè)務(wù)的技術(shù)方案。

延展閱讀(點擊標(biāo)題):


喜歡我們的會點贊,愛我們的會分享!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多