分布式鎖方案和缺陷


分布式鎖使用場景

  • 解決業務層冪等性,防止雙次點擊(譬如更新接口)
  • 解決 MQ 消費端多端接受同一消息時保證只有一端處理消息
  • 使用 schedule 執行定時任務時,多實例部署時只有一台實例執行任務

Redis

特點

  • 單線程串行處理
  • 獲取鎖性能特別好
  • setnx 不存在則設置成功否則失敗
  • 沒有心跳機制,需要設置失效時間
  • CAP 中的 AP 模型,因為用的是 gossip 協議,所以不是強一致性

多個業務獲取鎖場景

鎖失效時間設置問題

鎖定了10s后過期,但業務執行了30s(可能碰到fullgc,死循環等場景)。

主從切換問題

業務1從主獲取鎖,此時主掛機了,從晉升為主,恰好此時從未同步這個鎖的值 。

Zookeeper

特點

  • 有序節點,按排序命名節點
  • 臨時節點,客戶端斷連后自動消失
  • 事件監聽,節點下發生更新時會有事件通知
  • ZAB 協議,強一致,屬於 CP 模型
  • zk 集群變大后,性能持續下降

多個業務獲取鎖場景

客戶端掛掉或假死

客戶端斷連會把臨時節點刪除,鎖也就隨着釋放。另一個業務即可獲取鎖。
但其實客戶端沒掛,只是心跳維持間斷了。原因有好多,譬如fullgc,網絡問題(redis碰到網絡問題最多獲取鎖失敗)等。

Etcd

特點

  • 如果存在 Key 的話就不能寫入,也就意味着不能獲取到鎖,如果集群中,可以寫入 Key,就意味着獲取得到鎖。
  • Raft 保證了集群的一致性,強一致性,並且數據是可以進行持久化
  • 沒有心跳機制,需要設置失效時間

多個業務獲取鎖場景

鎖失效時間設置問題

鎖定了10s后過期,但業務執行了30s(可能碰到fullgc,死循環等場景)。

使用失效時間的鎖時間續租問題

在獲取到鎖的業務線程,可以開啟一個子線程去維護和輪訓這把鎖的有效時間,並定時的對這把鎖進行續租。
假設業務線程獲取到一把鎖,鎖的 Expire 時間為 10s,業務線程會開啟一個子線程通過輪訓的方式每 2 秒鍾去把這把鎖進行續租,每次都將鎖的 Expire 還原到 10s。

存在的問題

  • 業務死循環
  • 業務 fullgc

這些問題都會導致續租線程無法執行,從而導致鎖提前失效。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM