基於zookeeper
zookeepr的鎖其實和資料庫是一樣的問題。如果有臨時節點的機器沒有正確處理***邏輯。那麼,整個鎖就會被卡死。解決的辦法也和redis鎖一樣。(本質上zk的znode也是乙個key-value格式嘛)。機器會迴圈遍歷,一旦發現自己的前序臨時節點的前序臨時節點已經刪除。就在本地計時。在超時後,直接將該節點刪除。喚醒本節點。但是zookeeper作為分布式鎖的最大問題,是它僅保證最終一致性。你不能假設每台伺服器都能從zookeeper看到相同的狀態。
所以這種方案其實是不可行的。
基於redis
可以說,redis的鎖是唯一在大規模併發場景中可以使用的鎖。
資料庫和redis可以實現在不考慮超時的情況下實現嚴格的分布式鎖。因為他們本身就是單點。但是,如果考慮超時,這個問題就無解了。沒有一種考慮超時的分布式鎖能夠保證全域性唯一執行。
所以,乙個簡單的辦法是,redis作為第一層,資料庫行鎖作為第二層。為了克服資料庫行鎖沒有超時時間的問題,
spring事務提供了超時時間的配置
@transactional
(timeout=
1)
但可惜,這個超時能力是spring計時器提供的。不是資料庫本身提供的。可能會存在比如說獲取行鎖後展開大規模的gc,整個jvm被卡住。(但是資料庫session不會超時,因為為了配合資料庫連線池,一般資料庫session超時配置到很大)。讓然會造成整個系統卡住。
其實,這樣的問題出現的概率很低才對。第一層的redis鎖已經把壓力降下來了,第二層資料庫操作卻意外超時了。這簡直是不可接受的。所以,我們需要努力在**和系統配置容量上,避免上述出現的問題。這也其實是所有使用select for update的系統必須要考慮的問題。
分布式 分布式鎖
本質是利用redis的setnx 方法的特性來加鎖,setnx 即key不存在則設定key,否則直接返回false,要求在分布式系統中使用同乙個redis服務,以下提供兩種解決方案 1 直接使用redistemplate 這其實並不能完全保證高併發下的安全問題,因為可能在鎖過期之後該執行緒尚未執行完...
分布式專題 分布式鎖
在傳統的單體應用架構中,遇到併發安全性問題時我們可以通過同步鎖synchronized,同步 塊,reentrantlock等方式都可以解決,但隨著業務的發展,單體應用架構不能滿足龐大的使用者請求量,於是分布式系統應用而生,在分布式系統中,由於每個系統都執行在不同的伺服器上,有著不同的jvm,所以j...
關於分布式uuid的一點設想
1.對於不同的uuid server,給予不同的字首,那麼不同的uuid伺服器的計數互不干擾,這個依賴於運維來實現,當然,如果開發打算自己做,我覺得也沒有問題。2.對於每個uuid伺服器,啟動的時候,從當前電腦獲取出當前的時間,在這裡,可以考慮從epoch開始的秒數,然後有乙個次數計數器,從0開始計...