讓咱們用最經典的 Use Case:「A賬號向B賬號匯錢」來講明一下,熟悉RDBMS事務的都知道從賬號A到賬號B須要6個操做:node
爲了數據的一致性,這6件事,要麼都成功作完,要麼都不成功,並且這個操做的過程當中,對A、B賬號的其它訪問必需鎖死,所謂鎖死就是要排除其它的讀寫操做,否則會有髒數據的問題,這就是事務。mysql
若是A賬號和B賬號的數據不在同一臺服務器上怎麼辦?咱們須要一個跨機器的事務處理。也就是說,若是A的扣錢成功了,但B的加錢不成功,咱們還要把A的操做給回滾回去。這在跨機器的狀況下,就變得比較複雜了。算法
若是不考慮性能的話,保證事務並不困難,系統慢一點就好了;除了考慮性能外,咱們還要考慮可用性,也就是說,一臺機器沒了,數據不丟失,服務可由別的機器繼續提供。 因而,咱們須要重點考慮下面的這麼幾個狀況:sql
要解決數據不丟,只能經過數據冗餘的方法,就算是數據分區,每一個區也須要進行數據冗餘處理。這就是數據副本:當出現某個節點的數據丟失時能夠從副本讀到,數據副本是分佈式系統解決數據丟失異常的惟一手段。因此在數據冗餘狀況下考慮數據的一致性和性能的問題:數據庫
1)要想讓數據有高可用性,就得寫多份數據。服務器
2)寫多份的問題會致使數據一致性的問題。網絡
3)數據一致性的問題又會引起性能問題併發
這就是軟件開發,按下了葫蘆起了瓢。異步
數據一致性能夠簡單分爲三類:分佈式
在分佈式系統中,每一個節點雖然能夠知曉本身的操做時成功或者失敗,卻沒法知道其餘節點的操做的成功或失敗。當一個事務跨越多個節點時,引入一個做爲協調者(coordinator)的組件來統一掌控全部節點(稱做參與者)的操做結果,並最終指示這些節點是否要把操做結果進行真正的提交(好比將更新後的數據寫入磁盤等等)。
兩階段提交(two phase commit, 2PC)的算法以下:
第一階段(vote):
第二階段(commit):
2PC實現了強一致性,其最大缺點就是它經過阻塞完成,會極大影響性能;另外一個問題則在timeout上:
3PC是把二段提交的第一個段break成了兩段:詢問,而後再鎖資源。最後真正提交。其核心理念是:在詢問的時候並不鎖定資源,除非全部人都贊成了,纔開始鎖資源。
理論上來講,若是第一階段全部的結點返回成功,那麼有理由相信成功提交的機率很大。這樣一來,能夠下降參與者Cohorts的狀態未知的機率。也就是說,一旦參與者收到了PreCommit,意味他知道你們其實都贊成修改了。這一點很重要。下面咱們來看一下3PC的狀態遷移圖:(注意圖中的虛線,那些F,T是Failuer或Timeout,其中的:狀態含義是 q – Query,a – Abort,w – Wait,p – PreCommit,c – Commit)
從上圖的狀態變化圖咱們能夠從虛線(那些F,T是Failuer或Timeout)看到——若是結點處在P狀態(PreCommit)的時候發生了F/T的問題,三段提交比兩段提交的好處是,三段提交能夠繼續直接把狀態變成C狀態(Commit),而兩段提交則不知所措。
Paxos是一種民主選舉的算法,目的是讓整個集羣對某個值的變動達成一致,大多數節點的決定會成個整個集羣的決定。任何一個點均可以提出要修改某個數據的提案,是否經過這個提案取決於這個集羣中是否有超過半數的結點贊成(須要集羣中的節點是單數)。
這個算法有兩個階段(假設這個有三個結點:A,B,C):
第一階段:Prepare階段
A把申請修改的請求Prepare Request發給全部的結點A,B,C。注意,Paxos算法會有一個Sequence Number(提案號,這個數不斷遞增,並且是惟一的,也就是說A和B不可能有相同的提案號),這個提案號會和修改請求一同發出,任何結點在「Prepare階段」時都會拒絕其值小於當前提案號的請求。因此,結點A在向全部結點申請修改請求的時候,須要帶一個提案號,越新的提案,這個提案號就越是是最大的。
若是接收結點收到的提案號n大於其它結點發過來的提案號,這個結點會迴應Yes(本結點上最新的被批准提案號),並保證不接收其它<n的提案。這樣一來,結點上在Prepare階段里老是會對最新的提案作承諾。
優化:在上述 prepare 過程當中,若是任何一個結點發現存在一個更高編號的提案,則須要通知 提案人,提醒其中斷此次提案。
第二階段:Accept階段
若是提案者A收到了超過半數的結點返回的Yes,而後他就會向全部的結點發布Accept Request(一樣,須要帶上提案號n),若是沒有超過半數的話,那就返回失敗。
當結點們收到了Accept Request後,若是對於接收的結點來講,n是最大的了,那麼,它就會修改這個值,若是發現本身有一個更大的提案號,那麼,結點就會拒絕修改。
咱們能夠看以,這彷佛就是一個「兩段提交」的優化。其實,2PC/3PC都是分佈式一致性算法的殘次版本,Google Chubby的做者Mike Burrows說過這個世界上只有一種一致性算法,那就是Paxos,其它的算法都是殘次品。
CAP理論爲:一個分佈式系統最多隻能同時知足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。
對於多數大型互聯網應用的場景,主機衆多、部署分散,並且如今的集羣規模愈來愈大,因此節點故障、網絡故障是常態,並且要保證服務可用性達到N個9,即保證P和A,捨棄C(退而求其次保證最終一致性)。雖然某些地方會影響客戶體驗,但沒達到形成用戶流程的嚴重程度。
但對於銀行等金融機構,C必須保證。網絡發生故障寧肯中止服務,這是保證CA,捨棄P。
數據庫事務(Transaction)是指做爲單個邏輯工做單元執行的一系列操做,要麼徹底地執行,要麼徹底地不執行。
一方面,當多個應用程序併發訪問數據庫時,事務能夠在應用程序間提供一個隔離方法,防止互相干擾。另外一方面,事務爲數據庫操做序列提供了一個從失敗恢復正常的方法。
事物有下面4個特性:
實際工做中事務幾乎都是併發的,徹底作到互相之間不干擾會嚴重犧牲性能,爲了平衡隔離型和性能,SQL92規範定義了四個事務隔離級別:
事務隔離級別越高,越能保證數據的一致性,但對併發性能影響越大,一致性和高性能必須有所取捨或折中。
通常狀況下,多數應用程序能夠選擇將數據庫的隔離級別設置爲讀已提交,這樣能夠避免髒讀,也能夠獲得不錯的併發性能。儘管這個隔離級別會致使不可重複度、幻讀,但這種個別場合應用程序能夠經過主動加鎖進行併發控制。
BASE理論是對CAP理論的延伸,核心思想是即便沒法作到強一致性(Strong Consistency,CAP的一致性就是強一致性),但應用能夠採用適合的方式達到最終一致性(Eventual Consitency)。
BASE支持的是大型分佈式系統,提出經過犧牲強一致性得到高可用性。