分布式鎖以及分布式鎖在專案中的使用總結

2021-09-10 09:56:28 字數 1957 閱讀 8203

第一:基於資料庫

第二:基於快取

第三:基於zookeeper

要實現分布式鎖,最簡單的方式可能就是直接建立一張鎖表,然後通過操作該表中的資料來實現了。

當我們要鎖住某個方法或資源時,我們就在該表中增加一條記錄,想要釋放鎖的時候就刪除這條記錄。

create table `methodlock` (

`id` int(11) not null auto_increment comment '主鍵',

`method_name` varchar(64) not null default '' comment '鎖定的方法名',

`desc` varchar(1024) not null default '備註資訊',

`update_time` timestamp not null default current_timestamp on update current_timestamp comment '儲存資料時間,自動生成',

primary key (`id`),

unique key `uidx_method_name` (`method_name `) using btree

) engine=innodb default charset=utf8 comment='鎖定中的方法';

當我們想要鎖住某個方法時,執行以下sql:

insert into methodlock(method_name,desc) values (『method_name』,『desc』);
方法執行完成後,釋放鎖:

delete from methodlock where method_name ='method_name'
上述方法看起來原理很簡單,但是會存在一些問題?

這把鎖沒有失效是時間,一旦解鎖失敗,就會導致鎖一直在資料庫裡邊,導致業務系統不可用。

這把鎖是非阻塞的,不管成功還是失敗都是立即返回。這把鎖是非阻塞的,不管成功還是失敗都是立即返回的。

這個鎖是非重入的。

要解決上述問題,其實也簡單,可通過下邊的操作來避免上述問題。

這把鎖沒有失效是時間?有兩個方案:

使用spring的巢狀事務來操作。使用分布式鎖的時候就起事務,業務**再起乙個事務,使用的傳播行為是required new,可以在上層事務回滾後不影響內層事務;

乙個定時任務,每隔一定時間把資料庫中的超時資料清理一遍。

非阻塞的

搞乙個while迴圈,不斷的往資料庫裡邊插入資料,直到插入成功為止或者到期為止。

這個鎖是非重入的

在資料行記錄中,記錄下執行緒的資訊,當獲取鎖的時候,先判斷執行緒是否是當前執行緒,是的話,返回成功,不是的話,返回失敗。

相對於基於資料庫實現分布式鎖的方案來說,基於快取的實現在效能上能有很大的優勢;

目前成熟的快取資料庫有很多,redis、memcached以及阿里能內中快取中介軟體tair等

實現的原理是加鎖時,利用往快取裡邊寫入一條資料,其中某乙個欄位是唯一的。

鎖釋放時手動刪除這個記錄。

這個方案也存在一些問題:

這把鎖是非重入鎖

這把鎖是非阻塞的。

非重入鎖?

和資料庫實現分布式鎖類似,其實問題還是乙個問題,解決方案也是類似的。

在儲存的資料記錄中查詢執行緒資訊,如果和當前執行緒是一致的就直接獲取鎖,不一致就獲取鎖失敗。

非阻塞的

同樣的加乙個迴圈,直到加鎖成為未知。

可以基於zk的臨時節點做分布式鎖。

大致思想就是客戶端在對某個方法加鎖時,都會在相應的方法節點下加乙個臨時有序節點,在客戶端執行完業務,會釋放鏈結,臨時節點自然刪除。判斷是否獲取鎖的邏輯是判斷當前臨時節點序號是否是做小的,如果是則獲取到了鎖。

分布式 分布式鎖

本質是利用redis的setnx 方法的特性來加鎖,setnx 即key不存在則設定key,否則直接返回false,要求在分布式系統中使用同乙個redis服務,以下提供兩種解決方案 1 直接使用redistemplate 這其實並不能完全保證高併發下的安全問題,因為可能在鎖過期之後該執行緒尚未執行完...

分布式專題 分布式鎖

在傳統的單體應用架構中,遇到併發安全性問題時我們可以通過同步鎖synchronized,同步 塊,reentrantlock等方式都可以解決,但隨著業務的發展,單體應用架構不能滿足龐大的使用者請求量,於是分布式系統應用而生,在分布式系統中,由於每個系統都執行在不同的伺服器上,有著不同的jvm,所以j...

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

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