Zookeeper概念學習系列之分佈式事務

 

 

    很少說,直接上乾貨!html

 

  初學者來講,確定會有這麼一個疑問。爲何會在zookeeper裏牽扯到分佈式事務?數據庫

 

 

 

zookeeper究竟是什麼?安全

  zookeeper其實是yahoo開發的,用於分佈式中一致性處理的框架。最初其做爲研發hadoop時的副產品。因爲分佈式系統中一致性處理較爲困難,其餘的分佈式系統沒有必要 費勁重複造輪子,故隨後的分佈式系統中大量應用了zookeeper,以致於zookeeper成爲了各類分佈式系統的基礎組件,其地位之重要,可想而知。著名的hadoop,kafka,dubbo 都是基於zookeeper而構建。
  要想理解zookeeper究竟是作啥的,那首先得理解清楚,什麼是一致性。
  所謂的一致性,實際上就是圍繞着「看見」來的。誰能看見?可否看見?何時看見?舉個例子:淘寶後臺賣家,在後臺上架一件大促的商品,經過服務器A提交到主數據庫,假設剛提交後立馬就有用戶去經過應用服務器B去從數據庫查詢該商品,就會出現一個現象,賣家已經更新成功了,然而買家卻看不到;而通過一段時間後,主數據庫的數據同步到了從數據庫,買家就能查到了。
  假設賣家更新成功以後買家立馬就能看到賣家的更新,則稱爲強一致性
  若是賣家更新成功後買家不能看到賣家更新的內容,則稱爲弱一致性
  而賣家更新成功後,買家通過一段時間最終能看到賣家的更新,則稱爲最終一致性服務器

 

 

  更詳細,見網絡

Zookeeper概念學習系列之zookeeper是什麼?

 

 

 

 

 

 

 

 

分佈式事務框架

  咱們首先考慮一致性的特殊狀況,即分佈式事務的狀況。分佈式事務對於一致性的要求是強一致性,所以對於咱們後續討論有必定的借鑑意義。分佈式

  這裏咱們用到一個經典的例子:bob給smith轉帳,強一致性的要求必定是須要對外來講bob減錢的同時smith加錢oop

  由於假設賣家更新成功以後買家立馬就能看到賣家的更新,則稱爲強一致性;post

 

 

  單機環境下是這樣的:性能

  簡單講就是有關bob的減錢和smith的加錢都轉同一個庫來作,能夠採用數據庫的事務特性輕鬆支持。保證bob給smith轉帳的安全性。

 

 

 

  而分佈式環境就變這樣了:

  假設應用服務器是A,bob端的數據庫是B,smith端的數據是C,那麼A作成一個轉帳,須要B事務成功提交,而且C事務成功提交。然而由於網絡的影響,可能出現兩種狀況:

  1. 若是bob扣款成功,而網絡通知smith失敗了,則會出現bob的錢減了,smith的錢沒加
  2. 若是bob扣款不成功,而smith加錢成功了,則會出現smith錢增長了,可是bob的錢也沒減小

 

 

 

 

 

 

 

2PC

  這種不一致的問題困擾着你們。任意一邊出錯想要回滾另外一邊都不是簡單的數據庫回滾的事情( 由於此時已經成功提交),而是須要作業務的逆向操做,而不一樣業務的逆操做都不一樣,致使複雜性增長。考慮數據庫事務的執行其實是先將執行操做寫入binlog,等到最後經過一個commit指令將binlog的內容一次更新到表中,或者寫到一半經過一個rollback指令將binlog中的內容回滾。因而乎,能夠想到使用2個階段來執行這個過程,第一階段,寫入binlog;第二階段執行commit或者rollback。這就是著名的兩階段提交協議(2PC)。若是仔細考慮,會發現兩階段協議並無解決問題,只不過下降了出錯的機率而已,由於第二階段一樣存在上面的兩種狀況。注意最終狀態是多臺機器的狀態&&的 結果。如下是兩階段協議的時序圖:

 1. 考慮prepare階段的響應(由於請求階段和執行階段均可以在最後響應中體現出來),對於分佈式環境中,任意時刻考慮3種狀態:成功、失敗、超時。
    a.成功。沒必要處理,執行後續行爲commit。
    b.失敗。這是執行階段出錯,執行後續行爲rollback。
    c.超時。這多是執行階段太慢,也多是網絡階段太慢或丟包,可是保守處理,超時能夠當作出錯。
  能夠看出,prepare階段的問題可以徹底避免。
2. 考慮commit階段,一樣考慮成功失敗超時3種狀態。
    a. 成功。整個事務成功執行
    b. 失敗。提交出錯,假設此時前面的B已經提交成功了,則一樣面臨須要回滾B卻沒法回滾的問題,由於B已經提交成功了。
    c. 超時。同上。
  還有一種例外狀況,即prepare階段完成後A掛了,則B,C即進入不知所措的狀態。
  能夠看出,在2PC中事務沒法作到像單機同樣安全,只不過下降了出問題的機率。

 

 

 

 

 

3PC

  針對如何解決2PC中的例外狀況,出現了3階段提交協議。3階段的主要改進是把2階段的prepare再分爲canCommit和preCommit兩個階段。

 

1. 考慮cancommit階段的響應。
  a.成功。沒必要處理,執行後續行爲precommit。
  b.失敗。說明沒法執行,無須後續提交或回滾行爲。
  c.超時。保守處理,超時能夠當作失敗。
2. 考慮precommit階段的響應。
  a.成功。沒必要處理,執行後續行爲docommit。
  b.失敗。執行階段出錯,執行後續行爲rollback。
c.超時。執行階段太慢,也多是網絡階段太慢或丟包,可是保守處理,超時能夠當作出錯。
  3. 考慮cancommit階段的響應。
  a.成功。整個事務成功執行。
  b.失敗。提交出錯,假設此時前面的B已經提交成功了,則一樣面臨沒法回滾的問題。
  c.超時。保守處理,超時能夠當作失敗。
  例外狀況,即自cancommit返回成功後的任意階段A掛掉了,那麼BC一樣可以知道這個事務正在發生(由於cancommit已經提交了足夠信息讓BC知曉此事),因而BC能夠在無A的狀況下繼續執行後續的階段(好比BC投票啓動新的A',並提供A'足夠信息)。因而3PC正好解決了2PC的例外狀況。
可是3PC仍然存在相似2PC的問題,即最後階段失敗或超時一樣有可能出現數據不一致的問題。因此3PC仍然只是下降了發生機率,並無真正解決問題。

 

 

 

 

 

 

XTS

  工業界的對分佈式事務的應用是如何呢?能夠參考某寶的知名分佈式框架XTS。

  XTS本質上是2PC(實際上若是引入3PC會多2n次網絡交互,在量大時反而更加不安全)。XTS引入協調者A的server部分,其實是一個大集羣,以配置的方式接入各類須要分佈式事務的業務,集羣由專門的團隊維護,保證其可用性和性能;而協調者A的client部分則經過發起方調用,prepare階段時,先經過client將本次事務信息發送到server,落庫,而後即時推送prepare請求到B和C,當收到B,C的響應時把他們狀態入庫,若是正常,則作commit提交;不然會用定時任務去推送未完成的狀態直到完成。上文提到的prepare以後協調者A掛了這種狀況,在server集羣的保證下,幾乎不多會發生。而上文提到的全部超時的狀況,均可以經過定時任務推送拿到一個肯定的狀態而不是盲目的選擇回滾或者提交。另外因爲B和C都是集羣,不多會發生屢次請求過去無響應的狀況。直到最後一種狀況就是commit時B成功了C失敗了,或者反過來B失敗C成功,這種狀況成爲懸掛事務,最終等待人工來解決,聽說天天都有幾筆到幾十筆。

  無疑XTS做爲2PC在工業界的應用,是至關了不得的設計,經過各類方式規避了各類可能的不一致性,在性能,效率等方面作到了平衡。

 

  分佈式開放消息系統(RocketMQ)的原理與實踐 http://www.jianshu.com/p/453c6e7ff81c

相關文章
相關標籤/搜索