閱讀635 返回首頁    go 阿裏雲 go 技術社區[雲棲]


分布式事務雲市場分析

背景

全局事務服務GTS上個月開始在阿裏雲上公測,之前我們也發表了一篇「破解世界性技術難題!GTS讓分布式事務簡單高效」的文章,引起了業界廣泛關注,接受了大量的谘詢,故希望通過本文讓大家對GTS有更深入的理解。

GTS在目前在阿裏內外部已經有較大規模的應用,有100多個用戶,其中專有雲大用戶就有10多個,預計今年將有更大規模的市場需求爆發。

用戶訴求是什麼

分布式事務解決的用戶最本質訴求是什麼?數據一致

大中企業有一個共同的訴求是數據一致,幾乎覆蓋到各個行業。

比如說零售行業,庫存與出貨的數據需要保持一致,出貨量與庫存數據不匹配,顯而易見會出問題,拿到訂單卻沒貨了,或者有貨卻下不了訂單。

比如說金融行業,轉賬數據搞錯了,A扣款了,B沒加上,馬上該用戶投訴了;A沒扣款,B卻加上了,產生資損;又比如從總賬戶中買了基金、股票後餘額不對了,等等,都會導致嚴重問題。

比如說車票購票網,用戶退票了,但是他買的那個座位狀態還是“已售賣”,造成損失;用戶購買了,卻已經沒座了,更是大問題。

數據一致對各個行業都很重要,但為什麼以前不覺著是個普遍需求?

以前多數企業的數據規模、業務複雜度相對較小,很多操作可以單機完成,數據庫本地事務可以搞定,所以數據一致問題不那麼明顯。

隨著互聯網技術快速發展,數據規模增大,分布式係統越來越普及,采用分布式數據庫或者跨多個數據庫的應用在中大規模企業普遍存在,服務化也是廣泛應用,由於網絡的不可靠和機器不可靠,數據不一致問題很容易出現。

數據一致性問題的現有解決方案

數據一致性問題是必須解決的,在很多大企業多年前就已經成為突出問題,他們是怎麼解決的?有這麼幾個典型方案:

• a)XA事務方案
• b)柔性事務
• c)基於消息的最終一致
• d)業務補償與人工訂正

方案a,XA協議由Tuxedo首先提出的,並交給X/Open組織,作為資源管理器(數據庫)與事務管理器的接口標準。Oracle、Informix、DB2和Sybase等各大數據庫廠家都提供對XA的支持。XA協議采用兩階段提交方式來管理分布式事務。最主要缺點是性能差,容易成為業務發展瓶頸,所以國內很少用戶采用。優點是滿足事務ACID,有幾個很成熟的產品,比較穩定,典型的是Oracle Tuxedo 和 IBM CICS。但是前景不看好,這麼多年缺乏重要技術突破,性能上不去,怎麼擁抱互聯網。

方案b,柔性事務(遵循BASE理論)是指相對於ACID剛性事務而言的,常見的是TCC型事務(Try/Confirm/Cancel)。最主要缺點是業務侵入性太強,需要大量開發工作進行業務改造,給業務升級、運維都帶來困難。優點是業務開發人員可以靈活控製事務邏輯,達到很好性能。在螞蟻金服有廣泛使用。以我的理解,這適合特定領域,很難作為通用方案對外大麵積鋪開。

方案c,常用辦法是通過本地消息表完成,也有一些通過事務消息。主要缺點同樣是業務侵入強,需要大量額外開發工作,給業務升級、運維都帶來困難。還有一個問題是使用場景受限,有些最終一致無法滿足的情況,需要人工幹預。優點是擴展性好,可以滿足日益擴大的業務,相對b來說開發沒那麼複雜。這是比較主流的方案,在阿裏廣泛使用。

方案d,多熟中小企業靠業務補償與人工訂正解決。缺點是運維、支持投入人力大,優點是簡單直接,邏輯不複雜。在業務量不大的情況下能hold住,但業務擴大了就很難應付。

這些問題很明顯,為什麼沒有產品解決?因為技術層麵很難,缺乏關鍵創新,這已經是至少10多年的世界性難題了。這種情況下,GTS橫空出世,通過一係列技術創新,希望能徹底解決這些問題。

GTS如何解決數據一致問題

從上麵分析可以看出,方案b/c/d是因為a的性能滿足不了業務需求的無奈之舉。

做出一個同樣滿足事務ACID的強一致的通用分布式事務中間件,並且性能足夠,簡單易用,才是終極方案,這就是GTS的出發點。GTS產品可以通過技術創新,解決上述方案分析中b、c和d用戶的問題,而不是尋求作為方案a用戶的替代產品。

事務比較抽象,我舉個例子類比下GTS給用戶帶來了哪些改變。

你每天上班,要經過一條10公裏的隻有兩條車道的馬路到達公司。這條路很堵,經常需要兩三個小時,上班時間沒有保證,這是方案a的問題。

選擇一條很繞,長30公裏但很少堵車的路,這是選b。上班時間有保證,但是必須早起,付出足夠的時間和汽油。

選擇一條有點繞,長20公裏的山路,路不平,隻有suv可以走,這是選c。上麵分析了c方案場景受限,對應於交通,是底盤低的小轎車沒法開,車型受限。

發揚艱苦奮鬥,走路上班,這是選d。

GTS做的是什麼?修了一條擁有4條車道的高架橋,沒有繞路,還是10公裏。不堵車,對事務來說是高性能;不繞路,對事務來說是簡單易用,對業務無侵入,不用為事務而重構;沒有車型限製,對事務來說是沒有功能限製,提供強一致事務。在沒有高架橋的時代,高架橋出現對交通來說就是一個顛覆性創新,很多以前看來無解的問題就迎刃而解了,同樣的,GTS希望通過創新改變數據一致性處理的行業現狀。

通過這個類比相信大家對GTS可以給用戶帶來的價值會有一定的了解。

GTS關鍵問題剖析

下麵我們列出幾個關鍵問題跟大家探討下。

1)GTS是強一致,還是最終一致?
2)GTS默認隔離級別是“讀未提交”,對業務影響大嗎?
3)GTS什麼場景下不能保證數據嚴格一致?

(1) 強一致,還是最終一致?

GTS是強一致,不是最終一致。一致性和隔離性對多數用戶不好區分,一致性對應事務ACID的“C”,隔離性對應的是“I”。

所謂強一致,在於用戶發起事務提交或事務回滾得到確認後,數據已經是一致的。而最終一致,用戶發起提交,得到響應說提交成功了,但是未必真的成功,隻是說過段時間它最終會數據一致。以轉賬為例,轉成功了你就一定立即可以查到是強一致,最終一致沒有這種保證。

強一致這個概念有很多爭論,不同人有不同理解,沒有權威定義。我們不搞學術化,大家理解實際業務中一致性是什麼樣子就好了。

隔離性與強一致沒有必然聯係。比如說把oracle的隔離級別設置為讀未提交,這時oracle就不強一致了?顯然還是強一致。有人提出串行化的隔離級別才是強一致,那我想問,在生產係統你會把數據庫隔離級別設置成串行化嗎?顯然絕大多數不會,這樣理解的話,大家就別搞強一致了。

(2) 隔離級別是“讀未提交”,對業務影響大嗎?

GTS支持兩種隔離級別,“讀未提交”和“讀已提交”。“讀未提交”比“讀已提交”有明顯性能優勢,而且適合絕大多數場景,所以作為我們默認隔離級別。

提起“讀未提交”,大家第一反應是有髒讀,會影響業務。真正分析下業務,會發現“讀未提交”與“讀已提交”的差別對業務有實際影響的場景很少。更多的場景是,如果你的業務邏輯在“讀未提交”下有問題,在“讀已提交”下同樣存在問題;反之,“讀已提交”下沒有問題,在“讀未提交”下也很少會存在問題。

還拿通俗易懂的轉賬為例。假定A、B、C賬戶各有10000元,賬戶信息在不同的數據庫,有兩個並發事務,事務1 A->B 1000元,事務2 A->C 2000元。轉賬的業務邏輯是,先查出賬戶餘額,再根據轉賬數目算出一個新餘額來,然後用這個新餘額去做update。

在“讀未提交”情況下,事務1在進行中,事務2讀到了A的賬戶9000元,恰巧這時事務1發生故障回滾了,兩個事務都完成後A 7000,B 10000,C 12000。數據不一致少了1000(A+B+C=29000),看來髒讀不靠譜,但是再分析下,上麵的邏輯在讀已提交下,是否也存在問題?

在“讀已提交”情況下,事務1在進行中,事務2讀到了A的賬戶10000元,兩個事務都成功完成後A 8000,B 11000,C 12000。數據不一致多出1000(A+B+C=31000),看來也不靠譜啊。

問題根源在於上麵的應用邏輯有典型的並發處理不當,修改辦法很多,比如用select … for update 查詢餘額,可以鎖定數據防止並發修改,或者是用sql中的邏輯運算代替,如 update … set value=value-2000。

我們追求極致性能,引導用戶用“讀未提交”的思路來寫分布式的業務邏輯,讓絕大多數SQL得到更好性能,個別SQL必須用“讀已提交”時才用。這比默認就用“讀已提交”更加合理。

(3) 什麼場景下不能保證數據嚴格一致?

當用戶用GTS事務操作數據,同時並發用非GTS方式(比如用oracle sqlplus)更改同一行數據,會影響到數據一致性。這種情況下,GTS校驗發現數據被修改了,會發出告警到用戶和我們團隊,用戶可以通過我們提供的工具進行訂正(通常是點點按鈕就ok了)。

問題的根本在於,GTS阻止不了別的方式寫數據。所以,我們建議用戶需要用GTS操作的數據,做到用且僅用GTS,混著搞是不安全的。我想這種限製是合理的(別的方案也有類似限製,按規則出牌),已有用戶都能接受。

在個別需要混用的特殊場景下,可以選擇GTS和非GTS有個時間差的方式。比如有個用戶是這樣的,通過GTS處理訂單,另有一個不走GTS的定時任務負責清理完成的訂單。我們建議用戶的定時任務加個where條件隻處理3分鍾前的訂單,這樣就很安全了,因為業務中設置的GTS超時時長為1分鍾,定時任務清理不會影響進行中的事務。

可以看到,很簡單的業務邏輯就可以避免這種問題,做少量改造換來大幅性能提升是值得的。

通過本文的分析,相信大家對GTS產品有了全新的理解和認識,有興趣的朋友,歡迎試用GTS:https://www.aliyun.com/aliware/txc

最後更新:2017-05-03 11:00:47

  上一篇:go JavaScript錯誤處理
  下一篇:go Java 8 開發頂級技巧