分布式鎖
分布式鎖的實現有哪些
memcached:利用 memcached 的 add 命令。此命令是原子性操作,只有在 key 不存在的情況下,才能 add 成功,也就意味著執行緒得到了鎖。
redis:和 memcached 的方式類似,利用 redis 的 setnx 命令。此命令同樣是原子性操作,只有在 key 不存在的情況下,才能 set 成功。
zookeeper:利用 zookeeper 的順序臨時節點,來實現分布式鎖和等待佇列。zookeeper 設計的初衷,就是為了實現分布式鎖服務的。
chubby:google 公司實現的粗粒度分布式鎖服務,底層利用了 paxos 一致性演算法。
通過 redis 分布式鎖的實現理解基本概念
分布式鎖實現的三個核心要素:
加鎖
最簡單的方法是使用 setnx 命令。key 是鎖的唯一標識,按業務來決定命名。比如想要給一種商品的秒殺活動加鎖,可以給 key 命名為 「lock_sale_商品id」 。而 value 設定成什麼呢?我們可以姑且設定成 1。加鎖的偽**如下:
setnx(lock_sale_商品id,1)
當乙個執行緒執行 setnx 返回 1,說明 key 原本不存在,該執行緒成功得到了鎖;當乙個執行緒執行 setnx 返回 0,說明 key 已經存在,該執行緒搶鎖失敗。
解鎖
有加鎖就得有解鎖。當得到鎖的執行緒執行完任務,需要釋放鎖,以便其他執行緒可以進入。釋放鎖的最簡單方式是執行 del 指令,偽**如下:
del(lock_sale_商品id)
釋放鎖之後,其他執行緒就可以繼續執行 setnx 命令來獲得鎖。
鎖超時
鎖超時是什麼意思呢?如果乙個得到鎖的執行緒在執行任務的過程中掛掉,來不及顯式地釋放鎖,這塊資源將會永遠被鎖住(死鎖),別的執行緒再也別想進來。所以,setnx 的 key 必須設定乙個超時時間,以保證即使沒有被顯式釋放,這把鎖也要在一定時間後自動釋放。setnx 不支援超時引數,所以需要額外的指令,偽**如下:
expire(lock_sale_商品id, 30)
綜合偽**如下:
if(setnx(lock_sale_商品id,1) == 1) finally }
存在什麼問題
以上偽**中存在三個致命問題
setnx 和 expire 的非原子性
分布式鎖 使用Redis實現分布式鎖
關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...
分布式鎖實現
1,資料庫實現原理 資料庫的行級x鎖。優點 不需要引入第三方應用。缺點 死鎖 對資料庫效能影響,可能較長時間占用資料庫連線資源 如果業務是分庫分表的,可能支援不了 示例 2,快取實現原理 通過setnx是否成功。當且僅當 key 不存在,將 key 的值設為 value 並返回1 若給定的 key ...
分布式鎖的實現
分布式鎖的實現方式通常有三種,第一種是基於資料庫實現分布式鎖,第二種是基於快取實現分布式鎖,第三種是基於zookeeper實現分布式鎖.第一種 基於資料庫實現分布式鎖 特點 效能較差,容易出現單點故障 鎖沒有失效時間,容易思死鎖 非阻塞式的 不可重入 第二種基於快取實現分布式鎖 鎖沒有失效時間,容易...