分佈式鎖
需要加鎖條件
- 共享資源
- 共享互斥鎖
- 多任務環境
基於MySQL 的分佈式鎖
流程
MySQL中的字段
- 每個程序去搶MySQL中的一個字段
- 查詢這個字段是否已經存在
- 插入一個數據到這個字段
- 還原這個字段讓其他的程序獲取鎖
- 操作資源
- 釋放資源
問題
- 資源浪費
- 當有程序使用到這把鎖的時候,其他程序在等待,且其他程序需要每隔一段時間去查看這把鎖是否釋放
- 死鎖問題
- 在一個程序獲取到這把鎖且在操作中的時候這個程序奔潰了,那麼MySQL中的這個字段將永遠無法被還原
解決死鎖方案
用一個外部進程監視這個鎖,當超時的時候則將這把鎖給釋放(將字段還原)。這個超時時間很難去把握,實際生產中一般不適用MySQL做分佈式鎖。
基於redis 的分佈式鎖
流程
- 每個程序去搶redis中的一個字段並設置有效期
- 查詢這個字段是否已經存在
- 插入一個數據到這個字段
- 還原這個字段讓其他的程序獲取鎖
- 操作資源
- 釋放資源
問題
redis 是通過設置有效期來解決MySQL中的死鎖問題,可問題就在於這個有效期很難把握。
基於zookeeper的分佈式鎖
zookeeper 是一個分佈式一致性服務框架
客戶端在操作一個zookeeper節點,其他的zookeeper都會被同步
zookeeper 可以存儲數據,文件系統,zookeeper的目錄是可以存儲數據的
zookeeper的目錄類型分爲四種
- 持久化目錄 (客戶端操作zookeeper會將目錄持久化)
- 臨時目錄 (客戶端與zookeeper斷開連接目錄自動刪除)
- 持久有順序目錄
- 臨時有順序目錄
- zookeeper支持事件回調機制
流程
- 程序去zookeeper獲取一個臨時序號(去/locks/ 下面獲取一個需要)
- 序號最小的去訪問資源
- 之後其他的序號需要找到比他序號小1的目錄註冊一個刪除回調事件
- 回調事件通知訪問資源
好處
-
節省了資源
-
通過有序臨時節點和事件通知機制巧妙的解決了死鎖問題