深入理解分布式鎖:從原理到實踐

1. 為何要使用分布式鎖

在分布式系統(tǒng)中,多個服務(wù)實例可能同時訪問共享資源,傳統(tǒng)的本地鎖失效。分布式鎖應(yīng)運而生,解決以下關(guān)鍵問題:

  • 并發(fā)資源訪問控制
  • 防止數(shù)據(jù)不一致
  • 避免重復(fù)操作
  • 保證業(yè)務(wù)原子性

典型場景:

  • 訂單生成
  • 庫存扣減
  • 秒殺系統(tǒng)
  • 分布式任務(wù)調(diào)度

2. 分布式鎖的幾種實現(xiàn)方式

2.1 數(shù)據(jù)庫實現(xiàn)

-- 悲觀鎖
SELECT * FROM table WHERE id = ? FOR UPDATE

優(yōu)點:簡單直接
缺點:性能低,數(shù)據(jù)庫壓力大

2.2 ZooKeeper實現(xiàn)

// 創(chuàng)建臨時順序節(jié)點
create -e -s /lock path

優(yōu)點:可靠性高
缺點:依賴ZooKeeper集群

2.3 Redis實現(xiàn)

--加鎖
SET key value NX PX 30000

優(yōu)點:性能高
缺點:需要自己實現(xiàn)續(xù)期機制

3. 為什么總選擇Redis?

  • 性能優(yōu)勢
  • 內(nèi)存操作,毫秒級響應(yīng)
  • 原子操作命令
  • 支持集群和高可用
  • 實現(xiàn)簡單

4. Redisson的優(yōu)越性

既然是redis,那么開箱即用,便是大家所需,redission應(yīng)運而生

  • 功能全面
  • 自動續(xù)期
  • 可重入鎖
  • 公平鎖
    代碼示例
RLock lock = redissonClient.getLock("myLock");
lock.lock();
try {
    // 業(yè)務(wù)邏輯
} finally {
    lock.unlock();
}

5. Redisson看門狗失效及解決

redission雖然有看門狗續(xù)命機制,但也不能做到萬無一失

5.1 失效場景

  • 有垃圾收集器( GC ),有時運行期間會暫停所有正在運行的線程。這些GC暫停甚至有時會持續(xù)數(shù)分鐘 !即使像HotSpot JVM CMS所謂的“并發(fā)”垃圾收集器也不能完全與應(yīng)用代碼并行運行,需要時時地停止活動的線程。通過改變分配模式或調(diào)整GC某些參數(shù)可 減少暫停,但是我們還是要防范最差情況以提供可靠的保證。

  • 當(dāng)操作系統(tǒng)執(zhí)行線程上下文切換時,或者虛擬機管理程序切換到 個虛機時
    正在運行的線程可能會在代碼的任意位置被暫停。在虛擬機環(huán)境中,這種被其
    虛擬機中斷的 PU時間稱為竊取時間 。如果機器負載很高( 等待運行的錢程很
    長),被暫停的線程可能需要 段時間之后才能再次運行。

  • 如果操作系統(tǒng)配置了基于磁盤的內(nèi)存交換分區(qū),內(nèi)存訪問可能觸發(fā)缺頁中斷,進
    而需要從磁盤中加載內(nèi)存頁。 I/O 進行時(通常比較慢)線程為暫停。如果內(nèi)存
    使用壓力很大,還可能迫使更多的頁面換出到磁盤 極端的情況下,操作系統(tǒng)可
    會花費大量時間在頁面換入換出上,而實際工作完成很少(所謂的顛簸’)。為
    了避免 問題,通常在服務(wù)器上禁用分頁,寧愿殺死一些進程來釋放內(nèi) 而不
    是反復(fù)抖動。
    總之,當(dāng)節(jié)點1拿到鎖在執(zhí)行時,如果看門狗未來的及續(xù)命,被暫停了,而redis鎖過期了,節(jié)點2就有可能拿到鎖,然后節(jié)點1復(fù)活繼續(xù)執(zhí)行,就會造成并發(fā)問題

5.2解決方案

5.2.1 顯式設(shè)置超時

// 增加鎖的超時時間
RLock lock = redissonClient.getLock("your_lock");
lock.lock(60, TimeUnit.SECONDS);  // 顯式設(shè)置較長超時

5.2.2 業(yè)務(wù)冪等設(shè)計

  • 唯一請求ID
  • 狀態(tài)機
  • 補償機制

5.2.3 JVM參數(shù)調(diào)優(yōu)

調(diào)整JVM GC策略
優(yōu)化Full GC頻率和時間
使用G1或ZGC替代
增加鎖的容錯機制

# 調(diào)整內(nèi)存大小
-Xms4g -Xmx4g  # 初始和最大堆內(nèi)存一致
-XX:MaxMetaspaceSize=256m  # 限制元空間大小

# 垃圾回收器選擇
-XX:+UseG1GC  # 推薦G1收集器
-XX:MaxGCPauseMillis=200  # 控制最大GC停頓時間

# 減少Full GC頻率
-XX:+DisableExplicitGC  # 禁止顯式調(diào)用System.gc()

結(jié)語
分布式鎖是分布式系統(tǒng)中的利器,選擇合適的方案和框架至關(guān)重要。Redisson提供了強大且易用的分布式鎖解決方案,但仍需謹慎設(shè)計和使用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容