1.0 分布式事務概述 2018-02-05 02:05:26 32,685 16
1、事務簡介
事務(Transaction)是訪問并可能更新資料庫中各種資料項的一個程式執行單元(unit),在關系資料庫中,一個事務由一組SQL陳述句組成,事務應該具有4個屬性:原子性、一致性、隔離性、持久性,這四個屬性通常稱為ACID特性,
原子性(atomicity):個事務是一個不可分割的作業單位,事務中包括的諸操作要么都做,要么都不做,
一致性(consistency):事務必須是使資料庫從一個一致性狀態變到另一個一致性狀態,事務的中間狀態不能被觀察到的,
隔離性(isolation):一個事務的執行不能被其他事務干擾,即一個事務內部的操作及使用的資料對并發的其他事務是隔離的,并發執行的各個事務之間不能互相干擾,隔離性又分為四個級別:讀未提交(read uncommitted)、讀已提交(read committed,解決臟讀)、可重復讀(repeatable read,解決虛讀)、串行化(serializable,解決幻讀),
持久性(durability):持久性也稱永久性(permanence),指一個事務一旦提交,它對資料庫中資料的改變就應該是永久性的,接下來的其他操作或故障不應該對其有任何影響,
任何事務機制在實作時,都應該考慮事務的ACID特性,包括:本地事務、分布式事務,及時不能都很好的滿足,也要考慮支持到什么程度,
2 本地事務
大多數場景下,我們的應用都只需要操作單一的資料庫,這種情況下的事務稱之為本地事務(Local Transaction),本地事務的ACID特性是資料庫直接提供支持,本地事務應用架構如下所示:

在JDBC編程中,我們通過java.sql.Connection物件來開啟、關倍訓者提交事務,代碼如下所示:
Connection conn = ... //獲取資料庫連接
conn.setAutoCommit(false); //開啟事務
try{
//...執行增刪改查sql
conn.commit(); //提交事務
}catch (Exception e) {
conn.rollback();//事務回滾
}finally{
conn.close();//關閉鏈接
}
此外,很多java應用都整合了spring,并使用其宣告式事務管理功能來完成事務功能,一般使用的步驟如下:
1、配置事務管理器,spring提供了一個PlatformTransactionManager介面,其有2個重要的實作類:
DataSourceTransactionManager:用于支持本地事務,事實上,其內部也是通過操作java.sql.Connection來開啟、提交和回滾事務,
JtaTransactionManager:用于支持分布式事務,其實作了JTA規范,使用XA協議進行兩階段提交,需要注意的是,這只是一個代理,我們需要為其提供一個JTA provider,一般是Java EE容器提供的事務協調器(Java EE server's transaction coordinator),也可以不依賴容器,配置一個本地的JTA provider,
2、 在需要開啟的事務的bean的方法上添加@Transitional注解
可以看到,spring除了支持本地事務,也支持分布式事務,下面我們先對分布式事務的典型應用場景進行介紹,
3 分布式事務典型場景
當下互聯網發展如火如荼,絕大部分公司都進行了資料庫拆分和服務化(SOA),在這種情況下,完成某一個業務功能可能需要橫跨多個服務,操作多個資料庫,這就涉及到到了分布式事務,用需要操作的資源位于多個資源服務器上,而應用需要保證對于多個資源服務器的資料的操作,要么全部成功,要么全部失敗,本質上來說,分布式事務就是為了保證不同資源服務器的資料一致性,
典型的分布式事務場景:
1、跨庫事務
跨庫事務指的是,一個應用某個功能需要操作多個庫,不同的庫中存盤不同的業務資料,筆者見過一個相對比較復雜的業務,一個業務中同時操作了9個庫,下圖演示了一個服務同時操作2個庫的情況:

2、分庫分表
通常一個庫資料量比較大或者預期未來的資料量比較大,都會進行水平拆分,也就是分庫分表,如下圖,將資料庫B拆分成了2個庫:

對于分庫分表的情況,一般開發人員都會使用一些資料庫中間件來降低sql操作的復雜性,如,對于sql:insert into user(id,name) values (1,"tianshouzhi"),(2,"wangxiaoxiao"),這條sql是操作單庫的語法,單庫情況下,可以保證事務的一致性,
但是由于現在進行了分庫分表,開發人員希望將1號記錄插入分庫1,2號記錄插入分庫2,所以資料庫中間件要將其改寫為2條sql,分別插入兩個不同的分庫,此時要保證兩個庫要不都成功,要不都失敗,因此基本上所有的資料庫中間件都面臨著分布式事務的問題,
3、服務化(SOA)
微服務架構是目前一個比較一個比較火的概念,例如上面筆者提到的一個案例,某個應用同時操作了9個庫,這樣的應用業務邏輯必然非常復雜,對于開發人員是極大的挑戰,應該拆分成不同的獨立服務,以簡化業務邏輯,拆分后,獨立服務之間通過RPC框架來進行遠程呼叫,實作彼此的通信,下圖演示了一個3個服務之間彼此呼叫的架構:

Service A完成某個功能需要直接操作資料庫,同時需要呼叫Service B和Service C,而Service B又同時操作了2個資料庫,Service C也操作了一個庫,需要保證這些跨服務的對多個資料庫的操作要不都成功,要不都失敗,實際上這可能是最典型的分布式事務場景,
小結:上述討論的分布式事務場景中,無一例外的都直接或者間接的操作了多個資料庫,如何保證事務的ACID特性,對于分布式事務實作方案而言,是非常大的挑戰,同時,分布式事務實作方案還必須要考慮性能的問題,如果為了嚴格保證ACID特性,導致性能嚴重下降,那么對于一些要求快速回應的業務,是無法接受的,
4 X/Open DTP模型與XA規范
X/Open,即現在的open group,是一個獨立的組織,主要負責制定各種行業技術標準,官網地址:http://www.opengroup.org/,X/Open組織主要由各大知名公司或者廠商進行支持,這些組織不光遵循X/Open組織定義的行業技術標準,也參與到標準的制定,下圖展示了open group目前主要成員(官網截圖):

可以看到,中國人的驕傲,華為,赫然在列!!!此處應該有掌聲,
就分布式事務處理(Distributed Transaction Processing,簡稱DTP)而言,X/Open主要提供了以下參考檔案:
DTP 參考模型: <
DTP XA規范: << Distributed Transaction Processing: The XA Specification>>
4.1 DTP模型
1、模型元素
在<
應用程式(Application Program ,簡稱AP):用于定義事務邊界(即定義事務的開始和結束),并且在事務邊界內對資源進行操作,
資源管理器(Resource Manager,簡稱RM):如資料庫、檔案系統等,并提供訪問資源的方式,
事務管理器(Transaction Manager ,簡稱TM):負責分配事務唯一標識,監控事務的執行進度,并負責事務的提交、回滾等,
通信資源管理器(Communication Resource Manager,簡稱CRM):控制一個TM域(TM domain)內或者跨TM域的分布式應用之間的通信,
通信協議(Communication Protocol,簡稱CP):提供CRM提供的分布式應用節點之間的底層通信服務,
其中由于通信資源管理器(Communication Resource Manager)和通信協議(Communication Protocol)是一對好基友,從Communication Protocol的簡稱CP上就可以看出來,兩個元素的關系不一般,因此有的文章在介紹DTP模型元素時,只提到了通信資源管理器....
2、模型實體(Instance of the Model)
一個DTP模型實體,至少有3個組成部分:AP、RMs、TM,如下所示:

這張圖類似于我們之前提到的跨庫事務的概念,即單個應用需要操作多個庫,在這里就是一個AP需要操作多個RM上的資源,AP通過TM來宣告一個全域事務,然后操作不同的RM上的資源,最后通知TM來提交或者回滾全域事務,
特別的,如果分布式事務需要跨多個應用,類似于我們前面的提到的分布式事務場景中的服務化,那么每個模型實體中,還需要額外的加入一個通信資源管理器CRM,
下圖中演示了2個模型實體,如何通過CRM來進行通信:

CRM作為多個模型實體之間通信的橋梁,主要作用如下:
基本的通信能力:從這個角度,可以將CRM類比為RPC框架,模型實體之間通過RPC呼叫實作彼此的通信,這一點體現在AP、CRM之間的連線,
事務傳播能力:與傳統RPC框架不同的是,CRM底層采用OSI TP(Open Systems Interconnection — Distributed Transaction Processing)通信服務,因此CRM具備事務傳播能力,這一點體現TM、CRM之間的連線,
2、事務管理器作用域 (TM domain)
一個TM domain中由一個或者多個模型實體組成,這些模型實體使用的都是同一個TM,但是操作的RMs各不相同,由TM來統一協調這些模型實體共同參與形成的全域事務(global transaction),
下圖展示了一個由四個模型實體組成的TM Domain,這四個模型實體使用的都是同一個事務管理器TM1,

TM domain只是列出了最終參與到一個全域事務中,有哪些模型實體,并不關心這些模型實體之間的關系,這就好比,有一個班級,我們只是想知道這個班級中每位同學的名字,但是并不是關心誰是班長、誰是學習委員等,
不過顯然的,當一個TM domain中存在多個模型實體時,模型實體彼此之間存在一定的層級呼叫關系,這就是全域事務的樹形結構,
3 全域事務樹形結構(Global Transaction Tree Structure)
當一個TM domain中,存在多個模型實體時,會形成一種樹形條用關系,如下圖所示:

其中:
發起分布式事務的模型實體稱之為root節點,或者稱之為事務的發起者,其他的模型實體可以統稱為事務的參與者,事務發起者負責開啟整個全域事務,事務參與者各自負責執行自己的事務分支,
而從模型實體之間的相互呼叫關系來說,呼叫方稱之為上游節點(Superior Node),被呼叫方稱之為下游節點(Subordinate Node),
小結:通過對DTP模型的介紹,我們可以看出來,之前提到的分布式事務的幾種典型場景實際上在DTP模型中都包含了,甚至比我們考慮的還復雜,DTP模型從最早提出到現在已經有接近30年,到如今依然適用,不得不佩服模型的設計者是很有遠見的,
4.2 XA規范
在DTP本地模型實體中,由AP、RMs和TM組成,不需要其他元素,AP、RM和TM之間,彼此都需要進行互動,如下圖所示:

這張圖中(1)表示AP-RM的互動介面,(2)表示AP-TM的互動介面,(3)表示RM-TM的互動介面,關于這張圖,XA規范有以下描述:
The subject of this X/Open specification is interface (3) in the diagram above, the XA interface by which TMs and RMs interact.
For more details on this model and diagram, including detailed definitions of each component, see the referenced DTP guide.
也就是說XA規范的最主要的作用是,就是定義了RM-TM的互動介面,下圖更加清晰了演示了XA規范在DTP模型中發揮作用的位置,從下圖中可以看出來,XA僅僅出現在RM和TM的連線上,

XA規范除了定義的RM-TM互動的介面(XA Interface)之外,還對兩階段提交協議進行了優化, 一些讀者可能會誤認為兩階段提交協議是在XA規范中提出來的,事實上: 兩階段協議(two-phase commit)是在OSI TP標準中提出的;在DTP參考模型(<<Distributed Transaction Processing: Reference Model>>)中,指定了全域事務的提交要使用two-phase commit協議;而XA規范(<< Distributed Transaction Processing: The XA Specification>>)只是定義了兩階段提交協議中需要使用到的介面,也就是上述提到的RM-TM互動的介面,因為兩階段提交程序中的參與方,只有TM和RMs,參見<<Distributed Transaction Processing: Reference Model>> 第3版 2.1節,原文如下:
Commitment Protocol
A commitment protocol is the synchronisation that occurs at transaction completion. The X/Open DTP Model follows the two-phase commit with presumed rollback1 protocol defined in the referenced OSI TP standards. A description of the basic protocol is given in Section 3.4.3 on page 13. In certain cases, a global transaction may be completed heuristically. Heuristic transaction completion is described in Section 3.4.5 on page 14.
4.2.1 XA Interface
XA規范中定義的RM 和 TM互動的介面如下圖所示:

關于這些介面的詳細解釋,可以直接參考XA規范,后面在講解到mysql對XA事務的支持時,我們也會使用到部分命令,
4.2.2 兩階段提交協議(2PC)
兩階段提交協議(Two Phase Commit)不是在XA規范中提出,但是XA規范對其進行了優化,因此統一放到這里進行講解,而從字面意思來理解,Two Phase Commit,就是將提交(commit)程序劃分為2個階段(Phase):

In Phase 1, the TM asks all RMs to prepare to commit (or prepare) transaction branches. This asks whether the RM can guarantee its ability to commit the transaction branch. An RM may have to query other entities internal to that RM.
If an RM can commit its work, it records stably the information it needs to do so, then replies affirmatively. A negative reply reports failure for any reason. After making a negative reply and rolling back its work, the RM can discard any knowledge it has of the transaction branch.
In Phase 2, the TM issues all RMs an actual request to commit or roll back the transaction branch, as the case may be. (Before issuing requests to commit, the TM stably records the fact that it decided to commit, as well as a list of all involved RMs.) All RMs commit or roll back changes to shared resources and then return status to the TM. The TM can then discard its knowledge of the global transaction.
階段1:
TM通知各個RM準備提交它們的事務分支,如果RM判斷自己進行的作業可以被提交,那就就對作業內容進行持久化,再給TM肯定答復;要是發生了其他情況,那給TM的都是否定答復,在發送了否定答復并回滾了已經的作業后,RM就可以丟棄這個事務分支資訊,
以mysql資料庫為例,在第一階段,事務管理器向所有涉及到的資料庫服務器發出prepare"準備提交"請求,資料庫收到請求后執行資料修改和日志記錄等處理,處理完成后只是把事務的狀態改成"可以提交",然后把結果回傳給事務管理器,
階段2
TM根據階段1各個RM prepare的結果,決定是提交還是回滾事務,如果所有的RM都prepare成功,那么TM通知所有的RM進行提交;如果有RM prepare失敗的話,則TM通知所有RM回滾自己的事務分支,
以mysql資料庫為例,如果第一階段中所有資料庫都prepare成功,那么事務管理器向資料庫服務器發出"確認提交"請求,資料庫服務器把事務的"可以提交"狀態改為"提交完成"狀態,然后回傳應答,如果在第一階段內有任何一個資料庫的操作發生了錯誤,或者事務管理器收不到某個資料庫的回應,則認為事務失敗,回撤所有資料庫的事務,資料庫服務器收不到第二階段的確認提交請求,也會把"可以提交"的事務回撤,
XA規范對兩階段提交協議有2點優化:
Protocol Optimisations
? Read-only
An RM can respond to the TM’s prepare request by asserting that the RM was not asked to update shared resources in this transaction branch. This response concludes the RM’s involvement in the transaction; the Phase 2 dialogue between the TM and this RM does not occur. The TM need not stably record, in its list of participating RMs, an RM that asserts a read-only role in the global transaction.
However, if the RM returns the read-only optimisation before all work on the global transaction is prepared, global serialisability1 cannot be guaranteed. This is because the RM may release transaction context, such as read locks, before all application activity for that global transaction is finished.
-
One-phase Commit
A TM can use one-phase commit if it knows that there is only one RM anywhere in the DTP system that is making changes to shared resources. In this optimisation, the TM makes its Phase 2 commit request without having made a Phase 1 prepare request. Since the RM decides the outcome of the transaction branch and forgets about the transaction branch before returning to the TM, there is no need for the TM to record stably these global transactions and, in some failure cases, the TM may not know the outcome.
只讀斷言
在Phase 1中,RM可以斷言“我這邊不涉及資料增刪改”來答復TM的prepare請求,從而讓這個RM脫離當前的全域事務,從而免去了Phase 2,
這種優化發生在其他RM都完成prepare之前的話,使用了只讀斷言的RM早于AP其他動作(比如說這個RM回傳那些只讀資料給AP)前,就釋放了相關資料的背景關系(比如讀鎖之類的),這時候其他全域事務或者本地事務就有機會去改變這些資料,結果就是無法保障整個系統的可序列化特性——通俗點說那就會有臟讀的風險,
一階段提交
如果需要增刪改的資料都在同一個RM上,TM可以使用一階段提交——跳過兩階段提交中的Phase 1,直接執行Phase 2,
這種優化的本質是跳過Phase 1,RM自行決定了事務分支的結果,并且在答復TM前就清除掉事務分支資訊,對于這種優化的情況,TM實際上也沒有必要去可靠的記錄全域事務的資訊,在一些例外的場景下,此時TM可能不知道事務分支的執行結果,
4.2.3 兩階段提交協議(2PC)存在的問題
二階段提交看起來確實能夠提供原子性的操作,但是不幸的是,二階段提交還是有幾個缺點的:
1、同步阻塞問題,兩階段提交方案下全域事務的ACID特性,是依賴于RM的,例如mysql5.7官方檔案關于對XA分布式事務的支持有以下介紹:
https://dev.mysql.com/doc/refman/5.7/en/xa.html
A global transaction involves several actions that are transactional in themselves, but that all must either complete successfully as a group, or all be rolled back as a group. In essence, this extends ACID properties “up a level” so that multiple ACID transactions can be executed in concert as components of a global operation that also has ACID properties. (As with nondistributed transactions, SERIALIZABLE may be preferred if your applications are sensitive to read phenomena. REPEATABLE READ may not be sufficient for distributed transactions.)
大致含義是說,一個全域事務內部包含了多個獨立的事務分支,這一組事務分支要不都成功,要不都失敗,各個事務分支的ACID特性共同構成了全域事務的ACID特性,也就是將單個事務分支的支持的ACID特性提升一個層次(up a level)到分布式事務的范疇,
括號中的內容的意思是: 即使在非分布事務中(即本地事務),如果對操作讀很敏感,我們也需要將事務隔離級別設定為SERIALIZABLE,而對于分布式事務來說,更是如此,可重復讀隔離級別不足以保證分布式事務一致性,
也就是說,如果我們使用mysql來支持XA分布式事務的話,那么最好將事務隔離級別設定為SERIALIZABLE, 地球人都知道,SERIALIZABLE(串行化)是四個事務隔離級別中最高的一個級別,也是執行效率最低的一個級別,
2、單點故障,由于協調者的重要性,一旦協調者TM發生故障,參與者RM會一直阻塞下去,尤其在第二階段,協調者發生故障,那么所有的參與者還都處于鎖定事務資源的狀態中,而無法繼續完成事務操作,(如果是協調者掛掉,可以重新選舉一個協調者,但是無法解決因為協調者宕機導致的參與者處于阻塞狀態的問題)
3、資料不一致,在二階段提交的階段二中,當協調者向參與者發送commit請求之后,發生了區域網路例外或者在發送commit請求程序中協調者發生了故障,這回導致只有一部分參與者接受到了commit請求,而在這部分參與者接到commit請求之后就會執行commit操作,但是其他部分未接到commit請求的機器則無法執行事務提交,于是整個分布式系統便出現了資料不一致性的現象,
由于二階段提交存在著諸如同步阻塞、單點問題等缺陷,所以,研究者們在二階段提交的基礎上做了改進,提出了三階段提交,
5 三階段提交協議(Three-phase commit)
三階段提交(3PC),是二階段提交(2PC)的改進版本,參考維基百科:https://en.wikipedia.org/wiki/Three-phase_commit_protocol
與兩階段提交不同的是,三階段提交有兩個改動點,
1、引入超時機制,同時在協調者和參與者中都引入超時機制,
2、在第一階段和第二階段中插入一個準備階段,保證了在最后提交階段之前各參與節點的狀態是一致的,也就是說,除了引入超時機制之外,3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段,

CanCommit階段
3PC的CanCommit階段其實和2PC的準備階段很像,協調者向參與者發送commit請求,參與者如果可以提交就回傳Yes回應,否則回傳No回應,
1.事務詢問 協調者向參與者發送CanCommit請求,詢問是否可以執行事務提交操作,然后開始等待參與者的回應,
2.回應反饋 參與者接到CanCommit請求之后,正常情況下,如果其自身認為可以順利執行事務,則回傳Yes回應,并進入預備狀態,否則反饋No
PreCommit階段
協調者根據參與者的反應情況來決定是否可以記性事務的PreCommit操作,根據回應情況,有以下兩種可能,
假如協調者從所有的參與者獲得的反饋都是Yes回應,那么就會執行事務的預執行,
1.發送預提交請求 協調者向參與者發送PreCommit請求,并進入Prepared階段,
2.事務預提交 參與者接收到PreCommit請求后,會執行事務操作,并將undo和redo資訊記錄到事務日志中,
3.回應反饋 如果參與者成功的執行了事務操作,則回傳ACK回應,同時開始等待最終指令,
假如有任何一個參與者向協調者發送了No回應,或者等待超時之后,協調者都沒有接到參與者的回應,那么就執行事務的中斷,
1.發送中斷請求 協調者向所有參與者發送abort請求,
2.中斷事務 參與者收到來自協調者的abort請求之后(或超時之后,仍未收到協調者的請求),執行事務的中斷,
doCommit階段
該階段進行真正的事務提交,也可以分為以下兩種情況,
Case 1:執行提交
1.發送提交請求 協調接收到參與者發送的ACK回應,那么他將從預提交狀態進入到提交狀態,并向所有參與者發送doCommit請求,
2.事務提交 參與者接收到doCommit請求之后,執行正式的事務提交,并在完成事務提交之后釋放所有事務資源,
3.回應反饋 事務提交完之后,向協調者發送Ack回應,
4.完成事務 協調者接收到所有參與者的ack回應之后,完成事務,
Case 2:中斷事務 協調者沒有接收到參與者發送的ACK回應(可能是接受者發送的不是ACK回應,也可能回應超時),那么就會執行中斷事務,
1.發送中斷請求 協調者向所有參與者發送abort請求
2.事務回滾 參與者接收到abort請求之后,利用其在階段二記錄的undo資訊來執行事務的回滾操作,并在完成回滾之后釋放所有的事務資源,
3.反饋結果 參與者完成事務回滾之后,向協調者發送ACK訊息
4.中斷事務 協調者接收到參與者反饋的ACK訊息之后,執行事務的中斷,
在doCommit階段,如果參與者無法及時接收到來自協調者的doCommit或者rebort請求時,會在等待超時之后,會繼續進行事務的提交,(其實這個應該是基于概率來決定的,當進入第三階段時,說明參與者在第二階段已經收到了PreCommit請求,那么協調者產生PreCommit請求的前提條件是他在第二階段開始之前,收到所有參與者的CanCommit回應都是Yes,(一旦參與者收到了PreCommit,意味他知道大家其實都同意修改了)所以,一句話概括就是,當進入第三階段時,由于網路超時等原因,雖然參與者沒有收到commit或者abort回應,但是他有理由相信:成功提交的幾率很大, )
小結:2PC與3PC的區別
相對于2PC,3PC主要解決的單點故障問題,并減少阻塞,因為一旦參與者無法及時收到來自協調者的資訊之后,他會默認執行commit,而不會一直持有事務資源并處于阻塞狀態,但是這種機制也會導致資料一致性問題,因為,由于網路原因,協調者發送的abort回應沒有及時被參與者接收到,那么參與者在等待超時之后執行了commit操作,這樣就和其他接到abort命令并執行回滾的參與者之間存在資料不一致的情況,
了解了2PC和3PC之后,我們可以發現,無論是二階段提交還是三階段提交都無法徹底解決分布式的一致性問題,Google Chubby的作者Mike Burrows說過, there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即世上只有一種一致性演算法,那就是Paxos,所有其他一致性演算法都是Paxos演算法的不完整版,后面的文章會介紹這個公認為難于理解但是行之有效的Paxos演算法,
6 BASE理論與柔性事務
6.1 經典的分布式系統理論-CAP
2000年7月,加州大學伯克利分校的Eric Brewer教授在ACM PODC會議上提出CAP猜想,Brewer認為在設計一個大規模的分布式系統時會遇到三個特性:一致性(consistency)、可用性(Availability)、磁區容錯(partition-tolerance),而一個分布式系統最多只能滿足其中的2項,2年后,麻省理工學院的Seth Gilbert和Nancy Lynch從理論上證明了CAP,之后,CAP理論正式成為分布式計算領域的公認定理,

-
一致性
一致性指“all nodes see the same data at the same time”,即更新操作成功并回傳客戶端完成后,所有節點在同一時間的資料完全一致,不能存在中間狀態,例如對于電商系統用戶下單操作,庫存減少、用戶資金賬戶扣減、積分增加等操作必須在用戶下單操作完成后必須是一致的,不能出現類似于庫存已經減少,而用戶資金賬戶尚未扣減,積分也未增加的情況,如果出現了這種情況,那么就認為是不一致的,
關于一致性,如果的確能像上面描述的那樣時刻保證客戶端看到的資料都是一致的,那么稱之為強一致性,如果允許存在中間狀態,只要求經過一段時間后,資料最終是一致的,則稱之為最終一致性,此外,如果允許存在部分資料不一致,那么就稱之為弱一致性,
-
可用性
可用性是指系統提供的服務必須一直處于可用的狀態,對于用戶的每一個操作請求總是能夠在有限的時間內回傳結果,“有限的時間內”是指,對于用戶的一個操作請求,系統必須能夠在指定的時間內回傳對應的處理結果,如果超過了這個時間范圍,那么系統就被認為是不可用的,試想,如果一個下單操作,為了保證分布式事務的一致性,需要10分鐘才能處理完,那么用戶顯然是無法忍受的,“回傳結果”是可用性的另一個非常重要的指標,它要求系統在完成對用戶請求的處理后,回傳一個正常的回應結果,不論這個結果是成功還是失敗,
-
磁區容錯性
分布式系統在遇到任何網路磁區故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務,除非是整個網路環境都發生了故障,
小結: 既然一個分布式系統無法同時滿足一致性、可用性、磁區容錯性三個特點,我們就需要拋棄一個,需要明確的一點是,對于一個分布式系統而言,磁區容錯性是一個最基本的要求,因為既然是一個分布式系統,那么分布式系統中的組件必然需要被部署到不同的節點,否則也就無所謂分布式系統了,而對于分布式系統而言,網路問題又是一個必定會出現的例外情況,因此磁區容錯性也就成為了一個分布式系統必然需要面對和解決的問題,因此系統架構師往往需要把精力花在如何根據業務特點在C(一致性)和A(可用性)之間尋求平衡,而前面我們提到的X/Open XA 兩階段提交協議的分布式事務方案,強調的就是一致性;由于可用性較低,實際應用的并不多,而基于BASE理論的柔性事務,強調的是可用性,目前大行其道,大部分互聯網公司采可能會優先采用這種方案,
6.2 BASE理論
eBay的架構師Dan Pritchett源于對大規模分布式系統的實踐總結,在ACM上發表文章提出BASE理論,文章鏈接:https://queue.acm.org/detail.cfm?id=1394128
BASE理論是對CAP理論的延伸,核心思想是即使無法做到強一致性(Strong Consistency,CAP的一致性就是強一致性),但應用可以采用適合的方式達到最終一致性(Eventual Consitency),
BASE是Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性)三個短語的縮寫,
1. 基本可用(Basically Available)
指分布式系統在出現不可預知故障的時候,允許損失部分可用性,
2. 軟狀態( Soft State)
指允許系統中的資料存在中間狀態,并認為該中間狀態的存在不會影響系統的整體可用性,
3. 最終一致( Eventual Consistency)
強調的是所有的資料更新操作,在經過一段時間的同步之后,最終都能夠達到一個一致的狀態,因此,最終一致性的本質是需要系統保證最終資料能夠達到一致,而不需要實時保證系統資料的強一致性,
BASE理論面向的是大型高可用可擴展的分布式系統,和傳統的事物ACID特性是相反的,它完全不同于ACID的強一致性模型,而是通過犧牲強一致性來獲得可用性,并允許資料在一段時間內是不一致的,但最終達到一致狀態,但同時,在實際的分布式場景中,不同業務單元和組件對資料一致性的要求是不同的,因此在具體的分布式系統架構設計程序中,ACID特性和BASE理論往往又會結合在一起,
6.3 典型的柔性事務方案
最大努力通知(非可靠訊息、定期校對)
可靠訊息最終一致性(異步確保型)
TCC(兩階段型、補償型)
來源:http://www.tianshouzhi.com/api/tutorials/distributed_transaction
歡迎關注公眾號 【碼農開花】一起學習成長
我會一直分享Java干貨,也會分享免費的學習資料課程和面試寶典
回復:【計算機】【設計模式】【面試】有驚喜哦
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/242220.html
標籤:其他
