日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

淺談分布式鎖

分布式鎖是一個在分布式環(huán)境中重要的原語,它表明不同進程間采用互斥的方式操作共享資源 。本文將談?wù)劮植际较嚓P(guān)的內(nèi)容 。
1
分布式鎖概述
從進程鎖到分布式鎖
在單進程環(huán)境中,為了防止多線程同時對共享資源進行讀寫操作,我們通常使用內(nèi)核或者類庫實現(xiàn)線程間的互斥 。當(dāng)擴展到分布式系統(tǒng)下,我們需要提供相同功能的分布式鎖服務(wù),不同的主機通過該服務(wù)獲取一把鎖,而獲取該鎖的機器就可以排他性的訪問共享資源 。

淺談分布式鎖


在單機環(huán)境下,操作系統(tǒng)知道自己進程的狀態(tài),當(dāng)進程掛掉的時候該進程會釋放自己持有的鎖資源,但在分布式環(huán)境下,存在宕機、網(wǎng)絡(luò)分區(qū)、時延等各種異常狀態(tài),因此需要給分布式鎖提供新的特性:可用性 。
分布式鎖的系統(tǒng)分類
基于鎖資源的安全性,可以將分布式鎖分為以下兩部分:
  1. 基于異步復(fù)制的分布式系統(tǒng),例如:redis、mysql
  2. 基于paxos協(xié)議的分布式一致性系統(tǒng),例如:etcd、zookeeper
基于異步復(fù)制的分布式系統(tǒng),存在丟鎖的風(fēng)險,不夠安全,通常使用TTL機制承擔(dān)細(xì)粒度的鎖服務(wù),該系統(tǒng)接入簡單,適用于對事件很敏感,期望設(shè)置一個較短的有效時間,執(zhí)行短期任務(wù),丟鎖對業(yè)務(wù)影響相對可控的服務(wù) 。
基于paxos協(xié)議的分布式系統(tǒng),通過一致性協(xié)議保證數(shù)據(jù)的多副本,數(shù)據(jù)的安全性高,通常使用lease機制承擔(dān)粗粒度的鎖服務(wù),適用于對安全性很敏感,希望長期持有鎖,不希望發(fā)生丟鎖現(xiàn)象的服務(wù) 。
2
基于 redis 的分布式鎖
通??梢允褂胹etnx(set if not exists)實現(xiàn)排他的獲取鎖操作,但是由于分布式系統(tǒng)中進程可能隨時宕機,因此獲取鎖時,需要添加TTL保證鎖不會因為進程掛掉之后變成死鎖狀態(tài),但是此時又出現(xiàn)了第二個問題,那就是setnx和expire操作必須是原子操作,因為setnx之后,如果進程掛掉,expire有可能沒有機會執(zhí)行,這同樣會導(dǎo)致死鎖 。正確的操作如下:
【淺談分布式鎖】SET lock_name value NX EX lock_time
  1. EX second:設(shè)置 key 的過期時間,單位是秒
  2. NX:當(dāng) key 不存在的時候進行設(shè)置,等同于 SETNX 操作
釋放鎖時,只需要調(diào)用DEL命令刪除鎖即可:
DEL lock_name需要注意的是,這里有可能出現(xiàn)錯誤刪除鎖的問題 。場景如下:
  1. 進程A加鎖成功,鎖超時時間20秒 。由于進程A業(yè)務(wù)邏輯執(zhí)行過長,20秒之后,鎖過期自動釋放 。
  2. 此時進程B接著加鎖,加鎖成功后,執(zhí)行業(yè)務(wù)邏輯 。這期間,進程A結(jié)束執(zhí)行,使用DEL釋放鎖 。
這樣就導(dǎo)致進程A錯誤的釋放進程B的鎖 。因此,為了不被錯誤的釋放鎖,我們在加鎖的時候需要設(shè)置UUID 。例如:
SET lock_name uuid NX EX lock_time釋放鎖時,需要先獲取鎖的UUID,如果是自己分配的,則釋放鎖 。但是這里的比較和釋放操作必須是原子操作,否則會出現(xiàn)獲獲取鎖比對的時候正確,此時正好TTL過期,另一個進程加鎖成功,這樣的話還是會出現(xiàn)錯誤釋放鎖的操作 。可以使用Lua腳本實現(xiàn)判斷與刪除的原子操作 。
3
基于 etcd/zookeeper 的分布式鎖
排他鎖(exclusive locks)
排他鎖(寫鎖、獨占鎖)表現(xiàn)如下:
進程p1對數(shù)據(jù)d1加上排他鎖,那么在整個加鎖期間,只允許進程p1對數(shù)據(jù)d1進行讀取和更新操作,其他任何進程都不能再對整個數(shù)據(jù)進行任何類型的操作 。直到p1釋放排他鎖 。
通過在zk/etcd上的數(shù)據(jù)節(jié)點來表示一個鎖

推薦閱讀