分布式鎖,分布式事務以及解決方案了解一下

2021-08-21 13:40:53 字數 1803 閱讀 7034

一、分布式鎖

場景1:常規的我們多執行緒訪問同一**塊的時候,為了保證同一時間只能 由乙個執行緒訪問,保證資料安全一致性,通常我們使用synchronized關鍵字來對方法加鎖,以達到保證資料安全性。

場景2:現在越來越多的專案,為了追求效能與高併發,採用了soa架構,微服務架構,於是就會出現多個模組單獨的服務。這個時候呢就會有乙個問題,如何保證多個節點的現場同步執行呢? 這種情況呢,就會用到了分布式鎖。

1、資料庫解決方案思路:

a.資料庫建一張表,字段方法名並且作為唯一性,當乙個方法執行時插入,則相當於獲得鎖,其他執行緒將無法訪問,方法執行完則釋放鎖。

但是上面這種存在問題:

1、資料庫單點,出現故障則將導致系統不可用。

2、沒有失效時間,一旦操作方法異常,導致一直沒有解鎖,也將導致其他不可用用。

b.使用select * from user u where username = '' for update 來對記錄加上排他鎖。操作完成後使用commit命令釋放鎖。

2、基於快取實現:通常有memcached、redis實現等,以下以redis實現分布式鎖為例

思路:主要用到的redis函式是setnx(),這個應該是實現分布式鎖最主要的函式。首先是將某一任務標識名(這裡用lock:order作為標識名的例子)作為鍵存到redis裡,並為其設個過期時間,如果是還有lock:order請求過來,先是通過setnx()看看是否能將lock:order插入到redis裡,可以的話就返回true,不可以就返回false

具體實現參照:

3.zookeeper分布式鎖

大致思路:每個客戶端對某個方法加鎖時,在zookeeper上的與該方法對應的指定節點的目錄下,生成乙個唯一的瞬時有序節點。 判斷是否獲取鎖的方式很簡單,只需要判斷有序節點中序號最小的乙個。 當釋放鎖的時候,只需將這個瞬時節點刪除即可。同時,其可以避免服務宕機導致的鎖無法釋放,而產生的死鎖問題。

zk中建立和刪除節點只能通過leader伺服器來執行,然後將資料同不到所有的follower機器上,所以效能上不如基於快取實現。

二、分布式事務:

舉個栗子吧:比如從支付寶轉100元到餘額寶,我們又兩個方法1、支付寶減掉100,2、餘額寶加上100。傳統的在乙個模組,乙個服務,或者乙個方法裡面,我們就很好解決了,只需要註解乙個事務就行了,是吧。

@transactional(rollbackfor=exception.class)這樣我們就可以保證兩個方法資料的一致性了。

但是顯然,現在我們的專案中,為了滿足效能要求,不可能還這樣傳統單機實現。我們做成了兩個服務,在兩個不同的模組 1、支付寶,2、餘額寶 這樣就存在了我們提到的問題,分布式事務,這個時候如何解決呢?

通常來說呢 實現方式有如下幾種:

1、兩階段提交協議(two-phase commit,2pc):架構圖如下

簡單來說,協調器先給a/b各發一條,準備的命令,等到都返回準備好了的命令的時候,在發起事務提交。這樣來保證事務一致性,但是存在很多問題,就是通訊上中斷的情況,會導致事務一致無法提交,而可能使系統崩潰。這就可以使用第二種方案。

2、tcc補償性,分為三個階段trying-confirming-canceling(使用訊息佇列實現,比如mq)

分布式事務解決方案

一 結合mq訊息中介軟體實現的可靠訊息最終一致性 二 tcc補償性事務解決 三 最大努力通知型方案 第一種方案 可靠訊息最終一致性,需要業務系統結合mq訊息中介軟體實現,在實現過程中需要保證訊息的成功傳送及成功消費。即需要通過業務系統控制mq的訊息狀態 第二種方案 tcc補償性,分為三個階段tryi...

分布式事務解決方案

當資料庫單錶一年產生的資料超過1000w,那麼就要考慮分庫分表,具體分庫分表的原理在此不做解釋,以後有空詳細說,簡單的說就是原來的乙個資料庫變成了多個資料庫。這時候,如果乙個操作既訪問01庫,又訪問02庫,而且要保證資料的一致性,那麼就要用到分布式事務。所謂的soa化,就是業務的服務化。比如原來單機...

分布式事務解決方案

由於資料量的巨大,大部分web應用都需要部署很多個資料庫例項。這樣,有些使用者操作就可能需要去修改多個資料庫例項中的資料。傳統的解決方法是使用分布式事務保證資料的全域性一致性,經典的方法是使用兩階段提交協議。長期以來,分布式事務提供的優雅的全域性acid保證麻醉了應用開發者的心靈,很多人都不敢越雷池...