分布式鎖的實現

2021-09-13 14:30:18 字數 2247 閱讀 6535

分布式鎖的實現

實現分布式鎖要滿足的條件:

1.互斥性:在任意時刻,只有乙個客戶端能持有鎖;

2.死鎖:不會發生死鎖,即使乙個客戶端在持有鎖的時候崩潰而沒有自己解鎖,也能保證後面其它客戶端能重新獲取鎖;

3.容錯:只要大部分的節點能夠正常執行就能保證客戶端能加鎖和解鎖;

1.使用資料的悲觀鎖(排它鎖):

1.建立一張表用於記錄鎖操作;

2.每次操作都會加一把鎖 select * from table for update;

特點獨佔資源其他所有的執行緒都要等待,可以保證資料的一致性,如果執行緒多的情況下會效率低下;

使用場景:資料敏感度高,讀取操作頻率較低的場景

2.樂觀鎖

1.使用時間戳timestamp 每次獲取查詢到的資料和現在資料庫的時間戳是否一致

如果一直提交資料並更新時間戳

2.使用version控制

使用場景:讀取評率高修改評率較少的場景

3.基於redis的快取技術

redisservice redissrevice=redisutils.getredisservice();

string status= redissrevice.setnx("key",1);

if("1"==status){

redissrevice.expire("key",2);

//執行業務

違反了了原子性原則

set key 123561 ex 2 nx ---使用此種方式解決上面的問題

stirng status= redissrevice.set("requestid",set_if_not_exsit,set_with_expire_time,expiretime)

if("ok"==status){

//執行業務

如何大量的key過於集中失效,會出現短時間卡頓現象

解決:在key過期時間設定的時候增加隨機值,分散操作

4.基於zookeeper實現分布式鎖

基於zookeeper臨時有序節點可以實現的分布式鎖。

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

來看下zookeeper能不能解決前面提到的問題。

鎖無法釋放?使用zookeeper可以有效的解決鎖無法釋放的問題,因為在建立鎖的時候,客戶端會在zk中建立乙個臨時節點,一旦客戶端獲取到鎖之後突然掛掉(session連線斷開),那麼這個臨時節點就會自動刪除掉。其他客戶端就可以再次獲得鎖。

非阻塞鎖?使用zookeeper可以實現阻塞的鎖,客戶端可以通過在zk中建立順序節點,並且在節點上繫結***,一旦節點有變化,zookeeper會通知客戶端,客戶端可以檢查自己建立的節點是不是當前所有節點中序號最小的,如果是,那麼自己就獲取到鎖,便可以執行業務邏輯了。

不可重入?使用zookeeper也可以有效的解決不可重入的問題,客戶端在建立節點的時候,把當前客戶端的主機資訊和執行緒資訊直接寫入到節點中,下次想要獲取鎖的時候和當前最小的節點中的資料比對一下就可以了。如果和自己的資訊一樣,那麼自己直接獲取到鎖,如果不一樣就再建立乙個臨時的順序節點,參與排隊。單點問題?使用zookeeper可以有效的解決單點問題,zk是集群部署的,只要集群中有半數以上的機器存活,就可以對外提供服務。

可以直接使用zookeeper第三方庫curator客戶端,這個客戶端中封裝了乙個可重入的鎖服務。

zookeeper實現的分布式鎖其實存在乙個缺點,那就是效能上可能並沒有快取服務那麼高。

因為每次在建立鎖和釋放鎖的過程中,都要動態建立、銷毀瞬時節點來實現鎖功能。zk中建立和刪除節點只能通過leader伺服器來執行,然後將資料同不到所有的follower機器上。

使用zookeeper實現分布式鎖的優點: 有效的解決單點問題,不可重入問題,非阻塞問題以及鎖無法釋放的問題。實現起來較為簡單。

使用zookeeper實現分布式鎖的缺點 : 效能上不如使用快取實現分布式鎖。 需要對zk的原理有所了解。

三種方案的比較

從理解的難易程度角度(從低到高): 資料庫 > 快取 > zookeeper

從實現的複雜性角度(從低到高): zookeeper >= 快取 > 資料庫

從效能角度(從高到低): 快取 > zookeeper >= 資料庫

從可靠性角度(從高到低): zookeeper > 快取 > 資料庫

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

分布式鎖實現

1,資料庫實現原理 資料庫的行級x鎖。優點 不需要引入第三方應用。缺點 死鎖 對資料庫效能影響,可能較長時間占用資料庫連線資源 如果業務是分庫分表的,可能支援不了 示例 2,快取實現原理 通過setnx是否成功。當且僅當 key 不存在,將 key 的值設為 value 並返回1 若給定的 key ...

分布式鎖的實現

分布式鎖的實現方式通常有三種,第一種是基於資料庫實現分布式鎖,第二種是基於快取實現分布式鎖,第三種是基於zookeeper實現分布式鎖.第一種 基於資料庫實現分布式鎖 特點 效能較差,容易出現單點故障 鎖沒有失效時間,容易思死鎖 非阻塞式的 不可重入 第二種基於快取實現分布式鎖 鎖沒有失效時間,容易...