事務(wù)的具體定義
事務(wù)(Transaction)是訪問并可能更新數(shù)據(jù)庫中各種數(shù)據(jù)項的一個程序執(zhí)行單元(unit)。在關(guān)系數(shù)據(jù)庫中,一個事務(wù)由一組SQL語句組成。事務(wù)應(yīng)該具有4個屬性:原子性、一致性、隔離性、持久性。這四個屬性通常稱為ACID特性。
事務(wù)提供一種機制將一個活動涉及的所有操作納入到一個不可分割的執(zhí)行單元,組成事務(wù)的所有操作只有在所有操作均能正常執(zhí)行的情況下方能提交,只要其中任一操作執(zhí)行失敗,都將導(dǎo)致整個事務(wù)的回滾。
簡單地說,事務(wù)提供一種“要么什么都不做,要么做全套(All or Nothing)”機制。
數(shù)據(jù)庫本地事務(wù)
在計算機系統(tǒng)中,更多的是通過關(guān)系型數(shù)據(jù)庫來控制事務(wù),這是利用數(shù)據(jù)庫本身的事務(wù)特性來實現(xiàn)的,因此叫數(shù)據(jù)庫事務(wù),由于應(yīng)用主要靠關(guān)系數(shù)據(jù)庫來控制事務(wù),而數(shù)據(jù)庫通常和應(yīng)用在同一個服務(wù)器,所以基于關(guān)系型數(shù)據(jù)庫的事務(wù)又被稱為本地事務(wù)。
回顧一下數(shù)據(jù)庫事務(wù)的四大特性 ACID:
說到數(shù)據(jù)庫事務(wù)就不得不說,數(shù)據(jù)庫事務(wù)中的四大特性 ACID:
A:原子性(Atomicity):一個事務(wù)(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結(jié)束在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。
- 在 MySQL 中,原子性通過回滾日志(Undo Log)來實現(xiàn)。當(dāng)事務(wù)執(zhí)行時,MySQL 將所有操作的結(jié)果記錄到回滾日志中,如果事務(wù)執(zhí)行失敗,MySQL 將通過回滾日志將所有操作回滾到執(zhí)行前的狀態(tài)。
C:一致性(Consistency):事務(wù)的一致性指的是在一個事務(wù)執(zhí)行之前和執(zhí)行之后數(shù)據(jù)庫都必須處于一致性狀態(tài)。
- 如果事務(wù)成功地完成,那么系統(tǒng)中所有變化將正確地應(yīng)用,系統(tǒng)處于有效狀態(tài)。
- 如果在事務(wù)中出現(xiàn)錯誤,那么系統(tǒng)中的所有變化將自動地回滾,系統(tǒng)返回到原始狀態(tài)。
- 在 MySQL 中,一致性通過使用鎖來實現(xiàn)。當(dāng)事務(wù)執(zhí)行時,MySQL 會對需要修改的數(shù)據(jù)行加鎖,以防止其他事務(wù)對數(shù)據(jù)的修改導(dǎo)致不一致。
I:隔離性(Isolation):指的是在并發(fā)環(huán)境中,當(dāng)不同的事務(wù)同時操縱相同的數(shù)據(jù)時,每個事務(wù)都有各自的完整數(shù)據(jù)空間。
由并發(fā)事務(wù)所做的修改必須與任何其他并發(fā)事務(wù)所做的修改隔離。事務(wù)查看數(shù)據(jù)更新時,數(shù)據(jù)所處的狀態(tài)要么是另一事務(wù)修改它之前的狀態(tài),要么是另一事務(wù)修改它之后的狀態(tài),事務(wù)不會查看到中間狀態(tài)的數(shù)據(jù)。
- 在 MySQL 中,隔離性通過使用鎖和 MVCC(多版本并發(fā)控制)來實現(xiàn)。MVCC 是指對于每個修改操作,MySQL 會保存一份舊的數(shù)據(jù)版本,并通過版本號來控制事務(wù)的隔離級別。
D:持久性(Durability):指的是只要事務(wù)成功結(jié)束,它對數(shù)據(jù)庫所做的更新就必須永久保存下來。即使發(fā)生系統(tǒng)崩潰,重新啟動數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)庫還能恢復(fù)到事務(wù)成功結(jié)束時的狀態(tài)。
- 在 MySQL 中,持久性通過使用重做日志(Redo Log)來實現(xiàn)。當(dāng)事務(wù)提交時,MySQL 將事務(wù)的修改操作記錄到重做日志中,以確保數(shù)據(jù)的持久性。
分布式事務(wù)
隨著互聯(lián)網(wǎng)的快速發(fā)展,軟件系統(tǒng)由原來的單體應(yīng)用轉(zhuǎn)變?yōu)榉植际綉?yīng)用,隨著應(yīng)用服務(wù)化,出現(xiàn)各個微服務(wù),以及這些服務(wù)對應(yīng)的庫表,多個庫表之間的數(shù)據(jù)操作可能需要保證原子性。
下圖描述了單體應(yīng)用向微服務(wù)的演變:
分布式系統(tǒng)會把一個應(yīng)用系統(tǒng)拆分為可獨立部署的多個服務(wù),因此需要服務(wù)與服務(wù)之間遠(yuǎn)程協(xié)作才能完成事務(wù)操作,這種分布式系統(tǒng)環(huán)境下由不同的服務(wù)之間通過網(wǎng)絡(luò)遠(yuǎn)程協(xié)作完成事務(wù)稱之為分布式事務(wù),例如用戶注冊送積分事務(wù)、創(chuàng)建訂單減庫存事務(wù),銀行轉(zhuǎn)賬事務(wù)等都是分布式事務(wù)。
分布式事務(wù)基礎(chǔ)理論
CAP定理
CAP定理,又被叫作布魯爾定理。對于設(shè)計分布式系統(tǒng)來說(不僅僅是分布式事務(wù))的架構(gòu)師來說,CAP就是你的入門理論。
CAP理論告訴我們,一個分布式系統(tǒng)不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)和分區(qū)容錯性(P:Partion tolerance)這三個基本需求,最多只能同時滿足其中的兩項。
C - Consistency(一致性):
在分布式環(huán)境下,一致性是指數(shù)據(jù)在多個副本之間是否能夠保持一致的特性。對某個指定的客戶端來說,讀操作能返回最新的寫操作。對于數(shù)據(jù)分布在不同節(jié)點上的數(shù)據(jù)上來說,如果在某個節(jié)點更新了數(shù)據(jù),那么在其他節(jié)點如果都能讀取到這個最新的數(shù)據(jù),那么就稱為強一致,如果有某個節(jié)點沒有讀取到,那就是分布式不一致。
如何實現(xiàn)一致性?
- 1、寫入主數(shù)據(jù)庫后要將數(shù)據(jù)同步到從數(shù)據(jù)庫。
- 2、寫入主數(shù)據(jù)庫后,在向從數(shù)據(jù)庫同步期間要將從數(shù)據(jù)庫鎖定,待同步完成后再釋放鎖,以免在新數(shù)據(jù)寫入成功后,向從數(shù)據(jù)庫查詢到舊的數(shù)據(jù)。
分布式系統(tǒng)一致性的特點:
- 1、由于存在數(shù)據(jù)同步的過程,寫操作的響應(yīng)會有一定的延遲。
- 2、為了保證數(shù)據(jù)一致性會對資源暫時鎖定,待數(shù)據(jù)同步完成釋放鎖定資源。
- 3、如果請求數(shù)據(jù)同步失敗的結(jié)點則會返回錯誤信息,一定不會返回舊數(shù)據(jù)。
A - Availability(可用性):
可用性是指系統(tǒng)提供的服務(wù)必須一直處于可用的狀態(tài),對于用戶的每一個操作請求總是能夠在有限的時間內(nèi)返回正確結(jié)果。非故障的節(jié)點在合理的時間內(nèi)返回合理的響應(yīng)(不是錯誤和超時的響應(yīng))。可用性的兩個關(guān)鍵一個是合理的時間,一個是合理的響應(yīng)。合理的時間指的是請求不能無限被阻塞,應(yīng)該在合理的時間給出返回。合理的響應(yīng)指的是系統(tǒng)應(yīng)該明確返回結(jié)果并且結(jié)果是正確的,這里的正確指的是比如應(yīng)該返回50,而不是返回40。
如何實現(xiàn)可用性?
- 1、寫入主數(shù)據(jù)庫后要將數(shù)據(jù)同步到從數(shù)據(jù)庫。
- 2、由于要保證從數(shù)據(jù)庫的可用性,不可將從數(shù)據(jù)庫中的資源進(jìn)行鎖定。
- 3、即使數(shù)據(jù)還沒有同步過來,從數(shù)據(jù)庫也要返回要查詢的數(shù)據(jù),哪怕是舊數(shù)據(jù),如果連舊數(shù)據(jù)也沒有則可以按照約定返回一個默認(rèn)信息,但不能返回錯誤或響應(yīng)超時。
分布式系統(tǒng)可用性的特點:
- 1、 所有請求都有響應(yīng),且不會出現(xiàn)響應(yīng)超時或響應(yīng)錯誤。
P - Partition tolerance(分區(qū)容錯性):
分布式系統(tǒng)在遇到任何網(wǎng)絡(luò)分區(qū)故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務(wù),除非是整個網(wǎng)絡(luò)環(huán)境都發(fā)生了故障。打個比方,這里個集群有多臺機器,有臺機器網(wǎng)絡(luò)出現(xiàn)了問題,但是這個集群仍然可以正常工作。
網(wǎng)絡(luò)分區(qū)是指在分布式系統(tǒng)中,不同的節(jié)點分布在不同的子網(wǎng)絡(luò)(機房或異地網(wǎng)絡(luò)等)中,由于一些特殊的原因?qū)е逻@些子網(wǎng)絡(luò)之間出現(xiàn)網(wǎng)絡(luò)不連通的狀況,但各個子網(wǎng)絡(luò)的內(nèi)部網(wǎng)絡(luò)是正常的,從而導(dǎo)致整個系統(tǒng)的網(wǎng)絡(luò)環(huán)境被切分成了若干孤立的區(qū)域。需要注意的是,組成一個分布式系統(tǒng)的每個節(jié)點的加入與退出都可以看作是一個特殊的網(wǎng)絡(luò)分區(qū)。
如何實現(xiàn)分區(qū)容錯性?
- 1、盡量使用異步取代同步操作,例如使用異步方式將數(shù)據(jù)從主數(shù)據(jù)庫同步到從數(shù)據(jù),這樣結(jié)點之間能有效的實現(xiàn)松耦合。
- 2、添加從數(shù)據(jù)庫結(jié)點,其中一個從結(jié)點掛掉其它從結(jié)點提供服務(wù)。
分布式分區(qū)容錯性的特點:
1、分區(qū)容錯性分是布式系統(tǒng)具備的基本能力。
CAP組合方式
熟悉CAP的人都知道,三者不能共有。在所有分布式事務(wù)場景中不會同時具備CAP三個特性,因為在具備了P的前提下C和A是不能共存的。
在分布式系統(tǒng)中,網(wǎng)絡(luò)無法100%可靠,分區(qū)其實是一個必然現(xiàn)象,如果我們選擇了CA而放棄了P,那么當(dāng)發(fā)生分區(qū)現(xiàn)象時,為了保證一致性,這個時候必須拒絕請求,但是A又不允許,所以分布式系統(tǒng)理論上不可能選擇CA架構(gòu),只能選擇CP或者AP架構(gòu)。
順便一提,CAP理論中是忽略網(wǎng)絡(luò)延遲,也就是當(dāng)事務(wù)提交時,從節(jié)點A復(fù)制到節(jié)點B,但是在現(xiàn)實中這個是明顯不可能的,所以總會有一定的時間是不一致。同時CAP中選擇兩個,比如你選擇了CP,并不是叫你放棄A。因為P出現(xiàn)的概率實在是太小了,大部分的時間你仍然需要保證CA。就算分區(qū)出現(xiàn)了你也要為后來的A做準(zhǔn)備,比如通過一些日志的手段,是其他機器回復(fù)至可用。
CAP有哪些組合方式呢?
所以在生產(chǎn)中對分布式事務(wù)處理時要根據(jù)需求來確定滿足CAP的哪兩個方面。
1)AP:
放棄一致性(這里說的一致性是強一致性),追求分區(qū)容錯性和可用性。這是很多分布式系統(tǒng)設(shè)計時的選擇。
通常實現(xiàn)AP都會保證最終一致性,后面講的BASE理論就是根據(jù)AP來擴展的,一些業(yè)務(wù)場景 比如:訂單退款,今日退款成功,明日賬戶到賬,只要用戶可以接受在一定時間內(nèi)到賬即可。
2)CP:
放棄可用性,追求一致性和分區(qū)容錯性,我們的zookeeper其實就是追求的強一致,又比如跨行轉(zhuǎn)賬,一次轉(zhuǎn)賬請求要等待雙方銀行系統(tǒng)都完成整個事務(wù)才算完成。
3)CA:
放棄分區(qū)容忍性,即不進(jìn)行分區(qū),不考慮由于網(wǎng)絡(luò)不通或結(jié)點掛掉的問題,則可以實現(xiàn)一致性和可用性。那么系統(tǒng)將不是一個標(biāo)準(zhǔn)的分布式系統(tǒng),我們最常用的關(guān)系型數(shù)據(jù)就滿足了CA。
階段總結(jié)
- CAP是一個已經(jīng)被證實的理論,一個分布式系統(tǒng)最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partition tolerance)這三項中的兩項。
- 它可以作為我們進(jìn)行架構(gòu)設(shè)計、技術(shù)選型的考量標(biāo)準(zhǔn)。對于多數(shù)大型互聯(lián)網(wǎng)應(yīng)用的場景,結(jié)點眾多、部署分散,而且現(xiàn)在的集群規(guī)模越來越大,所以節(jié)點故障、網(wǎng)絡(luò)故障是常態(tài),而且要保證服務(wù)可用性達(dá)到N個9(99.99..%),并要達(dá)到良好的響應(yīng)性能來提高用戶體驗,因此一般都會做出如下選擇:保證P和A,舍棄C強一致,保證最終一致性。
BASE理論
1、理解強一致性和最終一致性
CAP理論告訴我們一個分布式系統(tǒng)最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partition tolerance)這三項中的兩項,其中AP在實際應(yīng)用中較多,AP即舍棄一致性,保證可用性和分區(qū)容忍性,但是在實際生產(chǎn)中很多場景都要實現(xiàn)一致性,比如主數(shù)據(jù)庫向從數(shù)據(jù)庫同步數(shù)據(jù),即使不要一致性,但是最終也要將數(shù)據(jù)同步成功來保證數(shù)據(jù)一致,這種一致性和CAP中的一致性不同,CAP中的一致性要求在任何時間查詢每個結(jié)點數(shù)據(jù)都必須一致,它強調(diào)的是強一致性,但是最終一致性是允許可以在一段時間內(nèi)每個結(jié)點的數(shù)據(jù)不一致,但是經(jīng)過一段時間每個結(jié)點的數(shù)據(jù)必須一致,它強調(diào)的是最終數(shù)據(jù)的一致性。
BASE是Basically Available(基本可用)、Soft state(軟狀態(tài))和Eventually consistent (最終一致性)三個短語的縮寫。BASE理論是對CAP中AP的一個擴展,通過犧牲強一致性來獲得可用性,當(dāng)出現(xiàn)故障允許部分不可用但要保證核心功能可用,允許數(shù)據(jù)在一段時間內(nèi)是不一致的,但最終達(dá)到一致狀態(tài)。滿足BASE理論的事務(wù),我們稱之為“柔性事務(wù)”。
BASE理論指的是:
Basically Available(基本可用):允許響應(yīng)時間拉長,允許功能上的損失,允許降級頁面(系統(tǒng)繁忙,稍后重試等),即分布式系統(tǒng)在出現(xiàn)故障時,允許損失部分可用功能,保證核心功能可用。如,電商網(wǎng)站交易付款出現(xiàn)問題了,商品依然可以正常瀏覽。
Soft state(軟狀態(tài)):是指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認(rèn)為該中間狀態(tài)的存在不會影響系統(tǒng)的整體可用性。如訂單的"支付中"、“數(shù)據(jù)同步中”等狀態(tài),待數(shù)據(jù)最終一致后狀態(tài)改為“成功”狀態(tài)。
Eventually consistent(最終一致性):本質(zhì)就是需要保證最終數(shù)據(jù)能夠達(dá)到一致性,而不需要實時保證系統(tǒng)數(shù)據(jù)的強一致性。如訂單的"支付中"狀態(tài),最終會變?yōu)椤爸Ц冻晒Α被蛘?支付失敗",使訂單狀態(tài)與實際交易結(jié)果達(dá)成一致,但需要一定時間的延遲、等待。
分布式事務(wù)解決方案
以理論為基礎(chǔ),針對不同的分布式場景業(yè)界常見的解決方案有2PC、TCC、可靠消息最終一致性、最大努力通知這幾種。
兩階段提交:分布式事務(wù)兩階段提交——XA方案 Seata方案
TCC方案:分布式事務(wù)TCC方案——Hmily方案
可靠消息最終一致性:分布式事務(wù)解決方案——可靠消息最終一致性
最大努力通知:分布式事務(wù)解決方案——最大努力通知
分布式事務(wù)對比分析:
2階段提交(2PC):
最大的詬病是一個阻塞協(xié)議。RM在執(zhí)行分支事務(wù)后需要等待TM的決定,此時服務(wù)會阻塞并鎖定資源。由于其阻塞機制和最差時間復(fù)雜度高, 因此,這種設(shè)計不能適應(yīng)隨著事務(wù)涉及的服務(wù)數(shù)量增加而擴展的需要,很難用于并發(fā)較高以及子事務(wù)生命周期較長 (long-running transactions) 的分布式服務(wù)中。
TCC方案:
如果拿TCC事務(wù)的處理流程與2PC兩階段提交做比較,2PC通常都是在跨庫的DB層面,而TCC則在應(yīng)用層面的處理,需要通過業(yè)務(wù)邏輯來實現(xiàn)。這種分布式事務(wù)的實現(xiàn)方式的優(yōu)勢在于,可以讓應(yīng)用自己定義數(shù)據(jù)操作的粒度,使得降低鎖沖突、提高吞吐量成為可能。而不足之處則在于對應(yīng)用的侵入性非常強,業(yè)務(wù)邏輯的每個分支都需要實現(xiàn)try、confirm、cancel三個操作。此外,其實現(xiàn)難度也比較大,需要按照網(wǎng)絡(luò)狀態(tài)、系統(tǒng)故障等不同的失敗原因?qū)崿F(xiàn)不同的回滾策略。典型的使用場景:滿,登錄送優(yōu)惠券等。
可靠消息最終一致性
可靠消息最終一致性事務(wù)適合執(zhí)行周期長且實時性要求不高的場景。引入消息機制后,同步的事務(wù)操作變?yōu)榛谙?zhí)行的異步操作,避免了分布式事務(wù)中的同步阻塞操作的影響,并實現(xiàn)了兩個服務(wù)的解耦。典型的使用場景:注冊送積分,登錄送優(yōu)惠券等。
最大努力通知
最大努力通知是分布式事務(wù)中要求最低的一種,適用于一些最終一致性時間敏感度低的業(yè)務(wù);允許發(fā)起通知方處理業(yè)務(wù)失敗,在接收通知方收到通知后積極進(jìn)行失敗處理,無論發(fā)起通知方如何處理結(jié)果都會不影響到接收通知方的后續(xù)處理;發(fā)起通知方需提供查詢執(zhí)行情況接口,用于接收通知方校對結(jié)果。典型的使用場景:銀行通知、支付結(jié)果通知等。
2PC | TCC | 可靠消息 | 最大努力通知 | |
---|---|---|---|---|
一致性 | 強一致 | 最終一致 | 最終一致 | 最終一致 |
吞吐量 | 低 | 中 | 高 | 高 |
實現(xiàn)復(fù)雜度 | 易 | 難 | 中 | 易 |
總結(jié):
在條件允許的情況下,我們盡可能選擇本地事務(wù)單數(shù)據(jù)源,因為它減少了網(wǎng)絡(luò)交互帶來的性能損耗,且避免了數(shù)據(jù)弱一致性帶來的種種問題。若某系統(tǒng)頻繁且不合理的使用分布式事務(wù),應(yīng)首先從整體設(shè)計角度觀察服務(wù)的拆分是否合理,是否高內(nèi)聚低耦合?是否粒度太小?分布式事務(wù)一直是業(yè)界難題,因為網(wǎng)絡(luò)的不確定性,而且我們習(xí)慣于拿
分布式事務(wù)與單機事務(wù)ACID做對比。
無論是數(shù)據(jù)庫層的XA、還是應(yīng)用層TCC、可靠消息、最大努力通知等方案,都沒有完美解決分布式事務(wù)問題,它們不過是各自在性能、一致性、可用性等方面做取舍,尋求某些場景偏好下的權(quán)衡。