分佈式下,我想要一致性

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每一個程序員架構夢的實現之路上,總是繞不開分佈式系統CAP這個理論的學習。如果你還沒有了解過,可以翻看之前的文章,相信我,如果你想成爲架構師,這個理論無論是在工作中還是面試中吹水,你始終都是需要的"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s/t1nbzIBL7JDLQMbKTczDjw","title":null},"content":[{"type":"text","text":"晦澀難懂的CAP"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CAP理論作爲分佈式的重要理論基礎,指出了在分佈式環境下,其實只有AP和CP兩種模型去選擇。BASE理論作爲CAP理論的一個延伸,主張犧牲一致性去換取可用性。反之,一個分佈式系統也可以去犧牲可用性去換取一致性。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"link","attrs":{"href":"#分佈式事務","title":null}},{"type":"text","text":"分佈式事務"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"說到一致性就不能不提事務,事務這個詞現在經常用於數據庫,但是有一點要注意,站在一定的角度,事務並非只適用於數據庫。如果站在數據庫角度非要下一個定義的話:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"事務(Transaction),一般是指要做的或所做的事情。在計算機術語中是指訪問並可能更新數據庫中各種數據項的一個程序執行單元(unit)。事務通常由高級數據庫操縱語言或編程語言(如SQL,C++或Java)書寫的用戶程序的執行所引起,並用形如begin transaction和end transaction語句(或函數調用)來界定。事務由事務開始(begin transaction)和事務結束(end transaction)之間執行的全體操作組成。"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了更好的認識並實現事務,抽象出了ACID理論,換句話說,如果一個系統能實現ACID特性,那麼就實現了事務特性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Atomic原子性: 一個事務的所有系列操作步驟被看成是一個動作,所有的步驟要麼全部完成要麼一個也不會完成。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Consistent一致性:事物完成時,必須所有數據保持一致狀態"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Isolated隔離性:主要用於實現併發控制, 隔離能夠確保併發執行的事務能夠順序一個接一個執行,通過隔離,一個未完成事務不會影響另外一個未完成事務。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Durable持久性:持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來即使數據庫發生故障也不應該對其有任何影響"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在單機上實現ACID並不困難,通常可以利用鎖、時間序列或者順序日誌等機制來保證。這裏多說一句,一般而言,隔離性可以利用鎖機制來實現,而原子性、一致性和持久性都可以利用日誌來實現,一致性算法Raft也是通過日誌形式來保證一致性的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是在分佈式環境下,網絡環境卻比單機要複雜的多,原因在於網絡通信的不可靠性,處於不同網絡的多個節點要想保證一致性,網絡延遲、網絡故障等因素都需要考慮。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"link","attrs":{"href":"#二階段提交協議","title":null}},{"type":"text","text":"二階段提交協議"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二階段(2PC)提交協議是根據業界首個分佈式事務標準規範X/OpenDTP提出的,顧名思義,它通過兩個階段來協商一個提交操作。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"X/OpenDTP設計了一個模型來描述分佈式事務的各個角色以及規範:"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/3c/3c820018c7211a656b577293d2f458c0.jpeg","alt":"image","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"AP:用戶程序,負責觸發分佈式事務,在這個過程中採用了特殊的事務指令(XA指令),這些指令由TM接管併發送給相關的RM去執行"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"RM:資源管理器,一般指數據庫,每個RM只執行自己相關的指令。映射到程序級別如:ODBC,"},{"type":"link","attrs":{"href":"http://ADO.Net","title":null},"content":[{"type":"text","text":"ADO.Net"}]},{"type":"text","text":",JDBC等。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"TM:事務管理器或者說是事務協調者,它負責接收AP發起的指令,調度和協調參與事務的所有RM,確保事務正常完成或者回滾。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二階段提交協議最早用來實現數據庫的分佈式事務,現在大部分數據庫的分佈式事務都採用了XA協議。在二階段提交協議中,一個事務的提交過程被分爲兩個過程:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"通知階段。在這個階段會通知所有參與事務的資源管理器(RM)進行資源的預留和其他準備工作,其中包括了持久化日誌文件和資源的鎖定。所以這個階段在整個事務過程中佔據了大部分時間,準備完成並把結果返回給事務管理器(TM)。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"提交階段。在該階段,事務管理器(TM)會根據上一步的結果來決定是提交還是回滾操作。僅當全部資源管理器(RM)都同意提交的時候,事務管理器(TM)才通知所有的資源管理器(RM)正式提交事務,否則TM將會通知所有的RM取消事務。"}]}]}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b3/b3cce4ff2c9152b41aeb9e39d4b7897a.jpeg","alt":"image","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二階段協議的精髓在於,它通過兩個階段來把不可靠事務提交失敗的機率降低到了最小,在一個真正的二階段提交事務的過程中,第一階段其實佔據了整個事務的大部分時間,而真正提交事務的第二階段幾乎是瞬間完成的,所以這正是二階段的巧妙之處。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是現實中我們很少使用二階段提交協議來保證事務性,爲什麼呢?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"在現實場景中,很少有強一致性的業務,最常用的是基於BASE理論的最終一致性"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"二階段提交協議需要鎖定資源,在性能上會有一定損失,這在高併發的場景中是不適合的。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"二階段提交協議引入了事務管理器(TM),增加了系統的複雜性,而且多數開發人員並不精通TM以及RM的技能。"}]}]}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"link","attrs":{"href":"#tcc","title":null}},{"type":"text","text":"TCC"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於二階段提交協議的一系列缺陷,TCC被引入分佈式事務。TCC是Try(預留)、Confirm(確認)、Cancel(撤銷)3個操作的簡稱,它包含了預留、確認或撤銷這2個階段。TCC針對分佈式事務大體過程是這樣的:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":null,"normalizeStart":1},"content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"預留階段:事務發起者分別向所有參與事務的業務方發起請求,要求預留業務資源,業務方並給予回覆。"}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"提交階段:事務發起者收到每個參與事務的業務方的回覆,如果都是ok,則通知每個業務方提交事務操作,如果至少有一個業務方返回結果非ok,則通知所有的業務方撤銷事務操作。"}]}]}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/c2/c26d2801b68e6980c94db1fbb84d8789.png","alt":"image","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/fd/fd77085f57990266658f0227b587d211.png","alt":"image","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"TCC本質上是補償事務,從操作上就可以看出來,每個業務方針對當前事務需要註冊三個操作:預留操作,確認操作,取消操作。這三個操作是需要參與事務的每個業務來編碼實現的。對應到編碼層面,每個業務方都需要提供三個操作的接口,爲了一致性,確認操作和取消操作必須是冪等的,因爲這兩個操作可能會系統性的重試或者人爲干預的重試。"}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"link","attrs":{"href":"#寫在最後","title":null}},{"type":"text","text":"寫在最後"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"TCC在操作上更像是一種編程模型,它主要針對業務層面,所以它在性能上要比主要針對數據庫層面的二階段提交要高很多。目前二階段提交協議主要的應用場景還是在數據庫上,所以它本質上使用的是數據庫的鎖機制,這也是在高併發的互聯網應用中很少使用二階段提交協議的重要原因之一。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"說了那麼多,在真實的業務場景中,如果能用單機數據庫的事務來代替分佈式事務,那就首選單機數據庫事務。如果業務允許放棄強一致性,那就採用最終一致性原則來保證一致性,而最終一致性最常用的解決方案是利用可靠的MQ消息,這個有時間我們詳聊。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"更多精彩文章"}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1342955119549267969&__biz=MzIwNTc3OTAxOA==#wechat_redirect","title":null},"content":[{"type":"text","text":"分佈式大併發系列"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1342959003139227648&__biz=MzIwNTc3OTAxOA==#wechat_redirect","title":null},"content":[{"type":"text","text":"架構設計系列"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1342962375443529728&__biz=MzIwNTc3OTAxOA==#wechat_redirect","title":null},"content":[{"type":"text","text":"趣學算法和數據結構系列"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&album_id=1342964237798391808&__biz=MzIwNTc3OTAxOA==#wechat_redirect","title":null},"content":[{"type":"text","text":"設計模式系列"}]}]}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f8/f8af5984765a267892bf1a1272272625.png","alt":"image","title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章