1. 程式人生 > 資訊 >領英中國總裁陸堅:領英沒有減少對中國的投入,還會加大

領英中國總裁陸堅:領英沒有減少對中國的投入,還會加大

分散式鎖

1,基於資料庫表實現
機制:在資料庫中建立一個表,表中包含方法名等欄位,並在方法名欄位上建立唯一索引,想要執行某個方法,就使用這個方法名向表中插入資料,成功插入則獲取鎖,執行完成後刪除對應的行資料釋放鎖。
1,首先建立一個 分散式鎖表
DROP TABLE IF EXISTS `distributed_lock`;
CREATE TABLE `distributed_lock` (
`distributed_lock_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`method_name` VARCHAR(64) NOT
NULL COMMENT '加鎖的方法名', `distributed_lock_desc` VARCHAR(255) NOT NULL COMMENT '備註', `inserted_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`distributed_lock_id`), UNIQUE KEY `unique_key_method_name` (`method_name`) USING BTREE ) ENGINE
=INNODB DEFAULT CHARSET=utf8 COMMENT='分散式鎖';

2,將要執行的方法名作為引數,儲存到分散式鎖表中

INSERT INTO distributed_lock (distributed_lock_id,method_name, distributed_lock_desc) VALUES (816374617763712,'要加鎖的方法名稱', '描述資訊');

如果可以插入成功,代表獲得了鎖,可以執行操作;邏輯執行完畢後,刪除資料,釋放鎖

DELETE FROM distributed_lock WHERE method_name ='要釋放鎖的方法名稱
';

缺點:

1,需要考慮資料的效能以及保證資料庫高可用

2,不具備可重入的特性

3,如果宕機,會造成死鎖

4,獲取不到鎖,直接返回失敗,需要程式碼做迴圈獲取鎖

2,基於Redis實現(redis,redission,redLock,lua指令碼,看門狗機制)
機制:jedis.set(String key, String value, String nx, String px, int time);
引數說明:
key:鎖,保證唯一
value:競爭者的ID,例如執行緒名,釋放鎖的時候需要判斷釋放者是否未該鎖的持有者
nx:SET IF NOT EXIST,即當key不存在時進行set操作;當key已存在則不做任何操作。
px:表示要給當前的鎖設定一個過期時間,防止死鎖
time:key的過期時間
執行set()方法只有兩種結果:

  1.當key不存在(沒有鎖),進行加鎖操作,並對鎖設定一個過期時間,同時value為加鎖的執行緒名。

  2.已經有鎖存在,不做任何操作。

解鎖:
  1. 判斷當前解鎖競爭者的執行緒名是否為鎖的持有者,如果不是直接返回失敗,如果是則進入第2步。
  2. 刪除key,如果刪除成功,返回解鎖成功,否則解鎖失敗。
缺點:
1,死鎖問題
2,不可重入
3,因為設定了過期時間,如果業務執行時間超過過期時間,會自動釋放鎖
4,需要保證redis的高可用
3,基於Zookeeper實現
機制:利用Zookeeper建立臨時有序節點來實現分散式鎖
  1. 當客戶端來請求時,在鎖空間下面建立一個臨時有序節點。
  2. 如果當前節點的排序是這個空間下面最小的,則代表加鎖成功,否則加鎖失敗,加鎖失敗後設置Watcher,等待前面節點的通知。
  3. 當前節點監聽其前面一個節點,如果前面一個節點刪除了就通知當前節點。
  4. 當解鎖時當前節點通知其後繼節點,並刪除當前節點。
缺點:
需要保證zk的高可用





作者:wxw_wang 出處:https://www.cnblogs.com/chauvet/

-------------------------------------------

個性簽名:做一個靈魂有趣的人!

如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!

萬水千山總是情,打賞一分行不行,所以如果你心情還比較高興,也是可以掃碼打賞博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!