分布式鎖原理介紹


分布式服務中,如果各個服務節點需要競爭資源,不能像單機多線程應用一樣使用線程鎖,需要由一套分布式鎖機制保證節點對資源的訪問。通常分布式鎖以單獨的服務方式實現,目前比較常用的分布式鎖實現有三種:zookeeper實現、redis實現和memcache實現。后兩者本質上相同。

一個需要用到分布式鎖的典型場景是,分布式服務的各個節點注冊到用於服務發現的服務器,注冊后的節點需要是有序的。此時就需要有鎖來保證各個節點按先后順序注冊。

下面分別介紹三種實現方式的原理。

一、zookeeper
1、實現原理
基於zookeeper臨時順序節點實現分布式鎖,其大致思想為:
(a)每個客戶端對某個功能加鎖時,在zookeeper上的與該功能對應的指定節點的目錄下,生成一個唯一的臨時順序節點;
(b)所有臨時順序節點中序號最小的,即為當前持有鎖的節點;
(c)釋放鎖時,將自己注冊的這個臨時順序節點刪除即可。

以上實現方法,可以在客戶端監聽注冊節點目錄的變化,當發生節點刪除時通知各個客戶端檢查是否自己持有了鎖。
如果集群規模很大,這樣做可能引起羊群效應,此時可以優化為客戶端監聽注冊節點目錄下,比自己節點小的節點變化。當比自己小的節點都刪除了,那么自己就持有了鎖。
--具體看 https://blog.csdn.net/xiaoliuliu2050/article/details/51226237

2、優點
鎖安全性高,zookeeper數據不易丟失

3、缺點
性能開銷比較高。因為其需要動態產生、刪除臨時順序節點,還需要監聽節點變化來實現鎖功能。

4、開源實現
curator開源庫中提供了分布式鎖的實現,python庫Kazoo中也可直接通過kazoo.recipe中的lock.Lock,調用acquire方法實現。
menagerie基於Zookeeper實現了java.util.concurrent包的一個分布式版本。

二、redis分布式鎖
1、實現原理
利用redis中的set命令來實現分布式鎖。
 
從 Redis 2.6.12 版本開始,set可以使用下列參數:
SET KEY VALUE [EX seconds] [PX milliseconds] [NX|XX]
 
  EX second :設置鍵的過期時間為 second 秒。 SET key value EX second 效果等同於 SETEX key second value 。
  PX millisecond :設置鍵的過期時間為 millisecond 毫秒。 SET key value PX millisecond 效果等同於 PSETEX key millisecond value 。
  NX :只在鍵不存在時,才對鍵進行設置操作。 SET key value NX 效果等同於 SETNX key value 。
  XX :只在鍵已經存在時,才對鍵進行設置操作。

返回值:
  SET 在設置操作成功完成時,才返回 OK 。
  如果設置了 NX 或者 XX ,但因為條件沒達到而造成設置操作未執行,那么命令返回空批量回復(NULL Bulk Reply)。

命令:
> SET key value EX ttl NX

大致思想是:
(a)SET lock currentTime+expireTime EX 600 NX,使用set設置lock值,並設置過期時間為600秒,如果成功,則獲取鎖;
(b)獲取鎖后,如果該節點掉線,則到過期時間ock值自動失效;
(c)釋放鎖時,使用del刪除lock鍵值;

使用redis單機來做分布式鎖服務,可能會出現單點問題,導致服務可用性差,因此在服務穩定性要求高的場合,官方建議使用redis集群(例如5台,成功請求鎖超過3台就認為獲取鎖),來實現redis分布式鎖。詳見RedLock。

2、優點
性能高,redis可持久化,也能保證數據不易丟失;
redis集群方式提高穩定性。

3、缺點
使用redis主從切換時可能丟失部分數據。

4、開源實現
python版本的開源實現:python-redis-lock。


三、memcached分布式鎖
1、實現原理
利用memcached的add函數實現分布式鎖。
add和set的區別在於:如果多線程並發set,則每個set都會成功,但最后存儲的值以最后的set的線程為准。而add的話則相反,add會添加第一個到達的值,並返回true,后續的添加則都會返回false。利用該點即可很輕松地實現分布式鎖。

2、優點
因為是全內存存儲,並發高效。

3、缺點
(1)memcached采用列入LRU置換策略,所以如果內存不夠,可能導致緩存中的鎖信息丟失。
(2)memcached無法持久化,一旦重啟,將導致信息丟失。

4、開源實現
待查。
 
 
 
參考
http://surlymo.iteye.com/blog/2082684
http://www.cnblogs.com/moonandstar08/p/5705619.html

zookeeper實現方式
http://graduter.iteye.com/blog/2024190
http://surlymo.iteye.com/blog/2082684
http://blog.csdn.net/xiaoliuliu2050/article/details/51226237

redis實現方式
https://redis.io/topics/distlock
http://blog.csdn.net/daiyudong2020/article/details/51760648
http://www.weizijun.cn/2016/03/17/聊一聊分布式鎖的設計/
http://blog.csdn.net/u013970991/article/details/52722680

 


免責聲明!

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



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