看了一本書《從Paxos到Zookeeper》,裏面講到二階段提交協議的缺點有4個,第一個是同步阻塞,引用書裏的話是:數據庫
二階段提交協議存在的最明顯也是最大的一個問題就是同步阻塞,這會極大地限制分佈式系統的性能。在二階段提交的執行過程當中,全部參與事務操做的邏輯都是處於阻塞狀態,也就是說,各個參與者在等待其餘參與者響應的過程當中,將沒法進行其餘任何操做。網絡
看到這段話,以爲甚是不解啊!併發
按理來講,按照數據庫事務併發執行的理論,只要事務之間沒有共同須要訪問的的數據,各個事務是能夠無序併發執行的。而對於事務之間有共同須要訪問的數據的話,按照二階段鎖(2PL)協議,也能夠以任意順序執行,只不過由於有鎖,因此其餘的事務會阻塞。聯繫一下,發現這段話少了個前提---就是訪問相同的數據(資源)。分佈式
還有就是,同步阻塞是保證數據一致性的手段之一,犧牲了併發性能,這在單個數據庫也存在這樣的問題,在一個分佈式系統裏面提出這樣一個沒法解決的問題,彷佛沒事找事的感受。性能
再看三階段。書裏介紹三階段引入了一個canCommit詢問階段和超時機制,最後說:spa
相較於二階段提交協議,三階段提交協議最大的優勢是下降了參與者的阻塞範圍,而且可以在出現單點故障後繼續達成一致性。進程
單點故障的解決就是經過超時機制完成的,我就納悶了,若是我在二階段也加上超時機制,不也能夠解決單點故障後出現的不一致性麼?難道只許三階段加超時,不許二階段加?仍是二階段加了超時就不叫二階段了麼?事務
固然了,三階段的canCommit階段仍是有點做用了,試想如下場景:資源
場景A:1個協調者,9個參與者,協調者發出canCommit消息後,最後一個參與者斷了,協調者收不到最後一個Yes響應。同步
若是是二階段,那麼協調者須要向另外8個發送Rollback,浪費了不少操做。
若是是三階段,就不會有這樣的問題。
場景B:一個協調者,9個參與者,其中的一個參與者佔用着須要訪問的資源。
若是是二階段,那麼參與者會阻塞,直到資源可用,才執行事務操做。即便加入了超時,也會跟場景A同樣,協調者須要向另外的8個發Rollback,浪費。
若是是三階段,這時協調者發送canCommit消息,以後收到其中一個No響應,協調者放棄執行事務,其餘參與者不作任何處理。
由此能夠看出,三階段多出的這個預先檢查階段好處多多。以後的兩個階段就跟二階段同樣的了。仍是會同步阻塞。
因此書裏說,
下降了參與者的阻塞範圍。
這我贊成!
但後一段又說:
三階段提交協議的缺點:三階段提交協議在去除阻塞的同時也引入了新的問題,那就是在參與者接收到preCommit消息後,若是網絡出現分區,此時協調者所在的節點和參與者沒法進行正常的網絡通訊,在這種狀況下,該參與者依然會進行事務的提交,這必然出現數據的不一致性。
剛剛纔說下降了參與者的阻塞範圍,如今又說去除了阻塞!什麼鬼啊,三階段的後兩個階段不也會佔用資源麼,其餘訪問相同資源的進程不也會阻塞麼?哪裏來的去除了阻塞啊?
還有就是,哪裏也引入的了新的問題,出現網絡分區後,二階段也會有數據不一致問題啊。
實在無語。。。就不能用詞準備一點麼