您好,登錄后才能下訂單哦!
本篇內容主要講解“分布式數據庫對2PC的優化方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“分布式數據庫對2PC的優化方法是什么”吧!
兩階段提交(2PC)
兩階段提交協議主要有2種,一種是應用層的TCC,比如阿里巴巴的seata就實現了TCC模式,這種模式的特點是每個服務都需要提供try/confirm/cancel這3個實現,這3個實現需要在業務代碼中實現,對業務侵入高。
今天我分享的是面向資源的2PC協議,最早由Jim Gray提出,整個事務分為2個階段,prepare階段和commit階段,這2個階段由協調節點和DB資源管理器協作完成。
這里我們還是以經典的電商系統為例,整個系統分為訂單、賬戶和庫存3個服務,我們收到客戶的購買請求后,協調節點需要協調訂單服務生成訂單,賬戶服務扣減商品款,庫存服務扣減商品庫存,假如這3個服務的數據庫在不同切片上,這個協調過程具體如下:
1.prepare階段
協調節點向所有服務發送prepare請求,每個服務收到prepare請求后會嘗試執行本地事務,但不會真正提交本地事務。這個嘗試執行的過程會檢查到是否具備執行事務的條件,比如資源是否被鎖定等,當所有服務都嘗試執行成功后會給協調節點返回一個yes,如下圖:
2.commit/rollback階段
如果prepare階段所有服務有返回了yes,那么協調節點就會通知各個服務執行commit操作,這時各個服務就會真正的提交本地事務。如下圖:
如果prepare階段有服務返回了no,協調節點就需要通知所有服務進行本地事務回滾。
2PC存在問題
上面我們簡單地分析了2PC協議的執行過程,那么2PC有什么問題呢?
1.性能問題
本地事務在prepare階段鎖定資源,比如賬戶服務要扣減xiaoming這個賬戶的金額100元,那必須把xiaoming這個賬戶先鎖定。這樣如果有其他事務也要修改xiaoming這個賬戶,就必須等待前面的事務完成。這樣就造成了延遲和性能下降。
2.協調節點單點故障
協調節點是單節點的,如果發生故障,整個事務會一直阻塞。比如第一個階段prepare成功了,但是第二個階段協調節點發出commit指令之前宕機了,所有服務的數據資源處于鎖定狀態,后面的事務只能等待。
3.數據不一致
如果第一階段prepare成功了,但是第二階段commit的時候,如果協調節點通知庫存服務失敗了,這樣就相當于生成了訂單,扣減了賬戶,但是沒有扣減庫存。這導致了數據的不一致。
Percolator模型
主流的NewSQL數據庫,比如TiDB,是用Percolator模型來解決的。如下官網鏈接:
https://pingcap.com/blog-cn/percolator-and-txn/
Percolator模型來自于Google論文:
《Large-scale Incremental Processing Using Distributed Transactions and Notifications》
原文可以看下面連接,網上也有好多翻譯版的:
https://www.cs.princeton.edu/courses/archive/fall10/cos597B/papers/percolator-osdi10.pdf
Percolator的前提是本地事務的數據庫支持多版本并發控制協議,也就是mvcc。現在主流數據庫比如mysql、oracle都是支持的。
a)初始階段
還是看上面我們提到的經典電商案例,初始階段,我們假設訂單數量是0,賬戶服務是1000,庫存服務是100,客戶下了1個訂單后,訂單服務增加1個訂單,賬戶服務扣除金額100,庫存服務扣除商品數量1。各個切片的初始數據如下表:
":"前面的是時間戳或者數據版本,后面是數據值。這3張表中,第一條記錄不保存真正的數據,而是保存了指向真正數據的指針,比如訂單表中,6這個版本的數據指向了5個版本的數據,訂單數量是0。
b)prepare階段
在prepare階段,協調節點向每個服務發送了prepare命令,這3張表分別進入了prepare階段。在prepare階段,Percolator定義了主鎖的概念,每個分布式事務只能有一個服務獲得主鎖,比如本案例的訂單服務,其他服務的鎖指向這個主鎖的指針,如下表:
prepare階段,每個服務會寫日志,并且根據時間戳記錄事務的私有版本,這樣其他事務就不能操作這三條數據了。
c)commit階段
在commit階段,協調節點只需要跟訂單服務通信,因為訂單服務擁有primary lock,也就是說協調節點只跟擁有primary lock的切片通信。這時數據如下表:
這時我們注意到除了order服務的鎖沒有了,而且增加了版本8指向版本7,說明訂單服務已經沒有私有版本了,但是賬戶服務和庫存服務的私有版本還在。Percolator的獨特之處就是在這里,它會啟動異步線程來更新賬戶服務和庫存服務。最終數據如下表:
因為協調節點只需要跟獲取primary lock的切片進行通信,要么成功要么失敗這樣就避免了commit時節點不能全部成功導致的數據不一致問題。
而prepare階段記錄了日志,如果某個切片commit失敗,可以根據日志進行再次commit,這樣就保證了數據最終一致。
如果協調節點宕機了,異步線程可以做資源的釋放工作,避免了因單點故障通信失敗造成的資源不能釋放。
這里我們要注意2點:
primary lock的選擇是隨機的,比如本例中并不一定會選擇訂單服務
協調節點發送commit后訂單服務先提交成功,這時如果其他事務要讀取賬戶服務和庫存服務的2條數據,雖然2條數據上面還有lock,但是查找primary@order.bal發現已提交,所以是可以讀取的。
總結
2PC協議有3個問題,性能問題、單點故障和數據不一致。
Percolator模型簡化了協調節點和切片的通信流程,讓協調節點只跟其中一個primary切片通信,一方面,減少了通信開銷,另一方面,避免了因為單點故障,commit階段部分節點通信失敗導致的數據不一致問題。
Percolator在prepare階段記錄了日志,這樣即使協調節點故障了,恢復后也可以根據日志來做事務恢復。
Percolator使用異步線程來做資源的釋放工作,這樣即使協調節點故障了,也不用擔心資源得不到釋放。
知名的NewSQL數據庫TiDB就是參照Percolator模型來對2PC協議進行優化的。
但是我們要知道,2PC的性能問題還是存在的,好在主流的分布式數據庫都做了優化,性能損耗只會越來越小。
到此,相信大家對“分布式數據庫對2PC的優化方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。