主頁(yè) > 知識(shí)庫(kù) > 詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式

詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式

熱門(mén)標(biāo)簽:龍圖酒吧地圖標(biāo)注 百度地圖標(biāo)注地方備注 地圖標(biāo)注圖標(biāo)素材入駐 電銷(xiāo)機(jī)器人價(jià)格多少錢(qián)一臺(tái) 400電話(huà)申請(qǐng)什么好 好搜地圖標(biāo)注 怎么申請(qǐng)400電話(huà)申請(qǐng) 怎么辦理400電話(huà)呢 電話(huà)機(jī)器人免費(fèi)嗎

目前幾乎很多大型網(wǎng)站及應(yīng)用都是分布式部署的,分布式場(chǎng)景中的數(shù)據(jù)一致性問(wèn)題一直是一個(gè)比較重要的話(huà)題。分布式的CAP理論告訴我們“任何一個(gè)分布式系統(tǒng)都無(wú)法同時(shí)滿(mǎn)足一致性(Consistency)、可用性(Availability)和分區(qū)容錯(cuò)性(Partition tolerance),最多只能同時(shí)滿(mǎn)足兩項(xiàng)。”所以,很多系統(tǒng)在設(shè)計(jì)之初就要對(duì)這三者做出取舍。在互聯(lián)網(wǎng)領(lǐng)域的絕大多數(shù)的場(chǎng)景中,都需要犧牲強(qiáng)一致性來(lái)?yè)Q取系統(tǒng)的高可用性,系統(tǒng)往往只需要保證“最終一致性”,只要這個(gè)最終時(shí)間是在用戶(hù)可以接受的范圍內(nèi)即可。

在很多場(chǎng)景中,我們?yōu)榱吮WC數(shù)據(jù)的最終一致性,需要很多的技術(shù)方案來(lái)支持,比如分布式事務(wù)、分布式鎖等。有的時(shí)候,我們需要保證一個(gè)方法在同一時(shí)間內(nèi)只能被同一個(gè)線(xiàn)程執(zhí)行。在單機(jī)環(huán)境中,Java中其實(shí)提供了很多并發(fā)處理相關(guān)的API,但是這些API在分布式場(chǎng)景中就無(wú)能為力了。也就是說(shuō)單純的Java Api并不能提供分布式鎖的能力。所以針對(duì)分布式鎖的實(shí)現(xiàn)目前有多種方案。

針對(duì)分布式鎖的實(shí)現(xiàn),目前比較常用的有以下幾種方案:

基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖
基于緩存(redis,memcached,tair)實(shí)現(xiàn)分布式鎖
 基于Zookeeper實(shí)現(xiàn)分布式鎖

在分析這幾種實(shí)現(xiàn)方案之前我們先來(lái)想一下,我們需要的分布式鎖應(yīng)該是怎么樣的?(這里以方法鎖為例,資源鎖同理)

可以保證在分布式部署的應(yīng)用集群中,同一個(gè)方法在同一時(shí)間只能被一臺(tái)機(jī)器上的一個(gè)線(xiàn)程執(zhí)行。
這把鎖要是一把可重入鎖(避免死鎖)
這把鎖最好是一把阻塞鎖(根據(jù)業(yè)務(wù)需求考慮要不要這條)
有高可用的獲取鎖和釋放鎖功能
獲取鎖和釋放鎖的性能要好

基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖

基于數(shù)據(jù)庫(kù)表

要實(shí)現(xiàn)分布式鎖,最簡(jiǎn)單的方式可能就是直接創(chuàng)建一張鎖表,然后通過(guò)操作該表中的數(shù)據(jù)來(lái)實(shí)現(xiàn)了。
當(dāng)我們要鎖住某個(gè)方法或資源時(shí),我們就在該表中增加一條記錄,想要釋放鎖的時(shí)候就刪除這條記錄。

創(chuàng)建這樣一張數(shù)據(jù)庫(kù)表:

CREATE TABLE `methodLock` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
 `method_name` varchar(64) NOT NULL DEFAULT '' COMMENT '鎖定的方法名',
 `desc` varchar(1024) NOT NULL DEFAULT '備注信息',
 `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '保存數(shù)據(jù)時(shí)間,自動(dòng)生成',
 PRIMARY KEY (`id`),
 UNIQUE KEY `uidx_method_name` (`method_name `) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='鎖定中的方法';

當(dāng)我們想要鎖住某個(gè)方法時(shí),執(zhí)行以下SQL:

insert into methodLock(method_name,desc) values (‘method_name',‘desc')

因?yàn)槲覀儗?duì)method_name做了唯一性約束,這里如果有多個(gè)請(qǐng)求同時(shí)提交到數(shù)據(jù)庫(kù)的話(huà),數(shù)據(jù)庫(kù)會(huì)保證只有一個(gè)操作可以成功,那么我們就可以認(rèn)為操作成功的那個(gè)線(xiàn)程獲得了該方法的鎖,可以執(zhí)行方法體內(nèi)容。

當(dāng)方法執(zhí)行完畢之后,想要釋放鎖的話(huà),需要執(zhí)行以下Sql:

delete from methodLock where method_name ='method_name'

上面這種簡(jiǎn)單的實(shí)現(xiàn)有以下幾個(gè)問(wèn)題:

1、這把鎖強(qiáng)依賴(lài)數(shù)據(jù)庫(kù)的可用性,數(shù)據(jù)庫(kù)是一個(gè)單點(diǎn),一旦數(shù)據(jù)庫(kù)掛掉,會(huì)導(dǎo)致業(yè)務(wù)系統(tǒng)不可用。
2、這把鎖沒(méi)有失效時(shí)間,一旦解鎖操作失敗,就會(huì)導(dǎo)致鎖記錄一直在數(shù)據(jù)庫(kù)中,其他線(xiàn)程無(wú)法再獲得到鎖。
3、這把鎖只能是非阻塞的,因?yàn)閿?shù)據(jù)的insert操作,一旦插入失敗就會(huì)直接報(bào)錯(cuò)。沒(méi)有獲得鎖的線(xiàn)程并不會(huì)進(jìn)入排隊(duì)隊(duì)列,要想再次獲得鎖就要再次觸發(fā)獲得鎖操作。
4、這把鎖是非重入的,同一個(gè)線(xiàn)程在沒(méi)有釋放鎖之前無(wú)法再次獲得該鎖。因?yàn)閿?shù)據(jù)中數(shù)據(jù)已經(jīng)存在了。

當(dāng)然,我們也可以有其他方式解決上面的問(wèn)題。

數(shù)據(jù)庫(kù)是單點(diǎn)?搞兩個(gè)數(shù)據(jù)庫(kù),數(shù)據(jù)之前雙向同步。一旦掛掉快速切換到備庫(kù)上。
沒(méi)有失效時(shí)間?只要做一個(gè)定時(shí)任務(wù),每隔一定時(shí)間把數(shù)據(jù)庫(kù)中的超時(shí)數(shù)據(jù)清理一遍。
非阻塞的?搞一個(gè)while循環(huán),直到insert成功再返回成功。
非重入的?在數(shù)據(jù)庫(kù)表中加個(gè)字段,記錄當(dāng)前獲得鎖的機(jī)器的主機(jī)信息和線(xiàn)程信息,那么下次再獲取鎖的時(shí)候先查詢(xún)數(shù)據(jù)庫(kù),如果當(dāng)前機(jī)器的主機(jī)信息和線(xiàn)程信息在數(shù)據(jù)庫(kù)可以查到的話(huà),直接把鎖分配給他就可以了。

基于數(shù)據(jù)庫(kù)排他鎖

除了可以通過(guò)增刪操作數(shù)據(jù)表中的記錄以外,其實(shí)還可以借助數(shù)據(jù)中自帶的鎖來(lái)實(shí)現(xiàn)分布式的鎖。

我們還用剛剛創(chuàng)建的那張數(shù)據(jù)庫(kù)表??梢酝ㄟ^(guò)數(shù)據(jù)庫(kù)的排他鎖來(lái)實(shí)現(xiàn)分布式鎖。 基于MySql的InnoDB引擎,可以使用以下方法來(lái)實(shí)現(xiàn)加鎖操作:

public Boolean lock(){
	connection.setAutoCommit(false)
	  while(true){
		try{
			result = select * from methodLock where method_name=xxx for update;
			if(result==null){
				return true;
			}
		}
		catch(Exception e){
		}
		sleep(1000);
	}
	return false;
}

在查詢(xún)語(yǔ)句后面增加for update,數(shù)據(jù)庫(kù)會(huì)在查詢(xún)過(guò)程中給數(shù)據(jù)庫(kù)表增加排他鎖(這里再多提一句,InnoDB引擎在加鎖的時(shí)候,只有通過(guò)索引進(jìn)行檢索的時(shí)候才會(huì)使用行級(jí)鎖,否則會(huì)使用表級(jí)鎖。這里我們希望使用行級(jí)鎖,就要給method_name添加索引,值得注意的是,這個(gè)索引一定要?jiǎng)?chuàng)建成唯一索引,否則會(huì)出現(xiàn)多個(gè)重載方法之間無(wú)法同時(shí)被訪(fǎng)問(wèn)的問(wèn)題。重載方法的話(huà)建議把參數(shù)類(lèi)型也加上。)。當(dāng)某條記錄被加上排他鎖之后,其他線(xiàn)程無(wú)法再在該行記錄上增加排他鎖。

我們可以認(rèn)為獲得排它鎖的線(xiàn)程即可獲得分布式鎖,當(dāng)獲取到鎖之后,可以執(zhí)行方法的業(yè)務(wù)邏輯,執(zhí)行完方法之后,再通過(guò)以下方法解鎖:

public void unlock(){
  connection.commit();
}

通過(guò)connection.commit()操作來(lái)釋放鎖。

這種方法可以有效的解決上面提到的無(wú)法釋放鎖和阻塞鎖的問(wèn)題。

阻塞鎖? for update語(yǔ)句會(huì)在執(zhí)行成功后立即返回,在執(zhí)行失敗時(shí)一直處于阻塞狀態(tài),直到成功。
鎖定之后服務(wù)宕機(jī),無(wú)法釋放?使用這種方式,服務(wù)宕機(jī)之后數(shù)據(jù)庫(kù)會(huì)自己把鎖釋放掉。

但是還是無(wú)法直接解決數(shù)據(jù)庫(kù)單點(diǎn)和可重入問(wèn)題。

這里還可能存在另外一個(gè)問(wèn)題,雖然我們對(duì)method_name 使用了唯一索引,并且顯示使用for update來(lái)使用行級(jí)鎖。但是,MySql會(huì)對(duì)查詢(xún)進(jìn)行優(yōu)化,即便在條件中使用了索引字段,但是否使用索引來(lái)檢索數(shù)據(jù)是由 MySQL 通過(guò)判斷不同執(zhí)行計(jì)劃的代價(jià)來(lái)決定的,如果 MySQL 認(rèn)為全表掃效率更高,比如對(duì)一些很小的表,它就不會(huì)使用索引,這種情況下 InnoDB 將使用表鎖,而不是行鎖。如果發(fā)生這種情況就悲劇了。。。

還有一個(gè)問(wèn)題,就是我們要使用排他鎖來(lái)進(jìn)行分布式鎖的lock,那么一個(gè)排他鎖長(zhǎng)時(shí)間不提交,就會(huì)占用數(shù)據(jù)庫(kù)連接。一旦類(lèi)似的連接變得多了,就可能把數(shù)據(jù)庫(kù)連接池?fù)伪?br />

總結(jié)

總結(jié)一下使用數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)分布式鎖的方式,這兩種方式都是依賴(lài)數(shù)據(jù)庫(kù)的一張表,一種是通過(guò)表中的記錄的存在情況確定當(dāng)前是否有鎖存在,另外一種是通過(guò)數(shù)據(jù)庫(kù)的排他鎖來(lái)實(shí)現(xiàn)分布式鎖。

數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn)

直接借助數(shù)據(jù)庫(kù),容易理解。

數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的缺點(diǎn)

會(huì)有各種各樣的問(wèn)題,在解決問(wèn)題的過(guò)程中會(huì)使整個(gè)方案變得越來(lái)越復(fù)雜。
操作數(shù)據(jù)庫(kù)需要一定的開(kāi)銷(xiāo),性能問(wèn)題需要考慮。
使用數(shù)據(jù)庫(kù)的行級(jí)鎖并不一定靠譜,尤其是當(dāng)我們的鎖表并不大的時(shí)候。

基于緩存實(shí)現(xiàn)分布式鎖

相比較于基于數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖的方案來(lái)說(shuō),基于緩存來(lái)實(shí)現(xiàn)在性能方面會(huì)表現(xiàn)的更好一點(diǎn)。而且很多緩存是可以集群部署的,可以解決單點(diǎn)問(wèn)題。

目前有很多成熟的緩存產(chǎn)品,包括Redis,memcached以及我們公司內(nèi)部的Tair。

這里以Tair為例來(lái)分析下使用緩存實(shí)現(xiàn)分布式鎖的方案。關(guān)于Redis和memcached在網(wǎng)絡(luò)上有很多相關(guān)的文章,并且也有一些成熟的框架及算法可以直接使用。

基于Tair的實(shí)現(xiàn)分布式鎖其實(shí)和Redis類(lèi)似,其中主要的實(shí)現(xiàn)方式是使用TairManager.put方法來(lái)實(shí)現(xiàn)。

public boolean trylock(String key) {
  ResultCode code = ldbTairManager.put(NAMESPACE, key, "This is a Lock.", 2, 0);
  if (ResultCode.SUCCESS.equals(code))
    return true;
  else
    return false;
}
public boolean unlock(String key) {
  ldbTairManager.invalid(NAMESPACE, key);
}

以上實(shí)現(xiàn)方式同樣存在幾個(gè)問(wèn)題:

1、這把鎖沒(méi)有失效時(shí)間,一旦解鎖操作失敗,就會(huì)導(dǎo)致鎖記錄一直在tair中,其他線(xiàn)程無(wú)法再獲得到鎖。
2、這把鎖只能是非阻塞的,無(wú)論成功還是失敗都直接返回。
3、這把鎖是非重入的,一個(gè)線(xiàn)程獲得鎖之后,在釋放鎖之前,無(wú)法再次獲得該鎖,因?yàn)槭褂玫降膋ey在tair中已經(jīng)存在。無(wú)法再執(zhí)行put操作。

當(dāng)然,同樣有方式可以解決。

沒(méi)有失效時(shí)間?tair的put方法支持傳入失效時(shí)間,到達(dá)時(shí)間之后數(shù)據(jù)會(huì)自動(dòng)刪除。
非阻塞?while重復(fù)執(zhí)行。
非可重入?在一個(gè)線(xiàn)程獲取到鎖之后,把當(dāng)前主機(jī)信息和線(xiàn)程信息保存起來(lái),下次再獲取之前先檢查自己是不是當(dāng)前鎖的擁有者。

但是,失效時(shí)間我設(shè)置多長(zhǎng)時(shí)間為好?如何設(shè)置的失效時(shí)間太短,方法沒(méi)等執(zhí)行完,鎖就自動(dòng)釋放了,那么就會(huì)產(chǎn)生并發(fā)問(wèn)題。如果設(shè)置的時(shí)間太長(zhǎng),其他獲取鎖的線(xiàn)程就可能要平白的多等一段時(shí)間。這個(gè)問(wèn)題使用數(shù)據(jù)庫(kù)實(shí)現(xiàn)分布式鎖同樣存在

總結(jié)

可以使用緩存來(lái)代替數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)分布式鎖,這個(gè)可以提供更好的性能,同時(shí),很多緩存服務(wù)都是集群部署的,可以避免單點(diǎn)問(wèn)題。并且很多緩存服務(wù)都提供了可以用來(lái)實(shí)現(xiàn)分布式鎖的方法,比如Tair的put方法,redis的setnx方法等。并且,這些緩存服務(wù)也都提供了對(duì)數(shù)據(jù)的過(guò)期自動(dòng)刪除的支持,可以直接設(shè)置超時(shí)時(shí)間來(lái)控制鎖的釋放。

使用緩存實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn)

性能好,實(shí)現(xiàn)起來(lái)較為方便。

使用緩存實(shí)現(xiàn)分布式鎖的缺點(diǎn)

通過(guò)超時(shí)時(shí)間來(lái)控制鎖的失效時(shí)間并不是十分的靠譜。

基于Zookeeper實(shí)現(xiàn)分布式鎖

基于zookeeper臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。

大致思想即為:每個(gè)客戶(hù)端對(duì)某個(gè)方法加鎖時(shí),在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。 判斷是否獲取鎖的方式很簡(jiǎn)單,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)。 當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可。同時(shí),其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無(wú)法釋放,而產(chǎn)生的死鎖問(wèn)題。

來(lái)看下Zookeeper能不能解決前面提到的問(wèn)題。

鎖無(wú)法釋放?使用Zookeeper可以有效的解決鎖無(wú)法釋放的問(wèn)題,因?yàn)樵趧?chuàng)建鎖的時(shí)候,客戶(hù)端會(huì)在ZK中創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn),一旦客戶(hù)端獲取到鎖之后突然掛掉(Session連接斷開(kāi)),那么這個(gè)臨時(shí)節(jié)點(diǎn)就會(huì)自動(dòng)刪除掉。其他客戶(hù)端就可以再次獲得鎖。
非阻塞鎖?使用Zookeeper可以實(shí)現(xiàn)阻塞的鎖,客戶(hù)端可以通過(guò)在ZK中創(chuàng)建順序節(jié)點(diǎn),并且在節(jié)點(diǎn)上綁定監(jiān)聽(tīng)器,一旦節(jié)點(diǎn)有變化,Zookeeper會(huì)通知客戶(hù)端,客戶(hù)端可以檢查自己創(chuàng)建的節(jié)點(diǎn)是不是當(dāng)前所有節(jié)點(diǎn)中序號(hào)最小的,如果是,那么自己就獲取到鎖,便可以執(zhí)行業(yè)務(wù)邏輯了。

不可重入?使用Zookeeper也可以有效的解決不可重入的問(wèn)題,客戶(hù)端在創(chuàng)建節(jié)點(diǎn)的時(shí)候,把當(dāng)前客戶(hù)端的主機(jī)信息和線(xiàn)程信息直接寫(xiě)入到節(jié)點(diǎn)中,下次想要獲取鎖的時(shí)候和當(dāng)前最小的節(jié)點(diǎn)中的數(shù)據(jù)比對(duì)一下就可以了。如果和自己的信息一樣,那么自己直接獲取到鎖,如果不一樣就再創(chuàng)建一個(gè)臨時(shí)的順序節(jié)點(diǎn),參與排隊(duì)。

單點(diǎn)問(wèn)題?使用Zookeeper可以有效的解決單點(diǎn)問(wèn)題,ZK是集群部署的,只要集群中有半數(shù)以上的機(jī)器存活,就可以對(duì)外提供服務(wù)。

可以直接使用zookeeper第三方庫(kù)Curator客戶(hù)端,這個(gè)客戶(hù)端中封裝了一個(gè)可重入的鎖服務(wù)。

public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
  try {
    return interProcessMutex.acquire(timeout, unit);
  } catch (Exception e) {
    e.printStackTrace();
  }
  return true;
}
public boolean unlock() {
  try {
    interProcessMutex.release();
  } catch (Throwable e) {
    log.error(e.getMessage(), e);
  } finally {
    executorService.schedule(new Cleaner(client, path), delayTimeForClean, TimeUnit.MILLISECONDS);
  }
  return true;
}

Curator提供的InterProcessMutex是分布式鎖的實(shí)現(xiàn)。acquire方法用戶(hù)獲取鎖,release方法用于釋放鎖。

使用ZK實(shí)現(xiàn)的分布式鎖好像完全符合了本文開(kāi)頭我們對(duì)一個(gè)分布式鎖的所有期望。但是,其實(shí)并不是,Zookeeper實(shí)現(xiàn)的分布式鎖其實(shí)存在一個(gè)缺點(diǎn),那就是性能上可能并沒(méi)有緩存服務(wù)那么高。因?yàn)槊看卧趧?chuàng)建鎖和釋放鎖的過(guò)程中,都要?jiǎng)討B(tài)創(chuàng)建、銷(xiāo)毀瞬時(shí)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)鎖功能。ZK中創(chuàng)建和刪除節(jié)點(diǎn)只能通過(guò)Leader服務(wù)器來(lái)執(zhí)行,然后將數(shù)據(jù)同不到所有的Follower機(jī)器上。

其實(shí),使用Zookeeper也有可能帶來(lái)并發(fā)問(wèn)題,只是并不常見(jiàn)而已。考慮這樣的情況,由于網(wǎng)絡(luò)抖動(dòng),客戶(hù)端可ZK集群的session連接斷了,那么zk以為客戶(hù)端掛了,就會(huì)刪除臨時(shí)節(jié)點(diǎn),這時(shí)候其他客戶(hù)端就可以獲取到分布式鎖了。就可能產(chǎn)生并發(fā)問(wèn)題。這個(gè)問(wèn)題不常見(jiàn)是因?yàn)閦k有重試機(jī)制,一旦zk集群檢測(cè)不到客戶(hù)端的心跳,就會(huì)重試,Curator客戶(hù)端支持多種重試策略。多次重試之后還不行的話(huà)才會(huì)刪除臨時(shí)節(jié)點(diǎn)。(所以,選擇一個(gè)合適的重試策略也比較重要,要在鎖的粒度和并發(fā)之間找一個(gè)平衡。)

總結(jié)

使用Zookeeper實(shí)現(xiàn)分布式鎖的優(yōu)點(diǎn)

有效的解決單點(diǎn)問(wèn)題,不可重入問(wèn)題,非阻塞問(wèn)題以及鎖無(wú)法釋放的問(wèn)題。實(shí)現(xiàn)起來(lái)較為簡(jiǎn)單。

使用Zookeeper實(shí)現(xiàn)分布式鎖的缺點(diǎn)

性能上不如使用緩存實(shí)現(xiàn)分布式鎖。 需要對(duì)ZK的原理有所了解。

三種方案的比較

上面幾種方式,哪種方式都無(wú)法做到完美。就像CAP一樣,在復(fù)雜性、可靠性、性能等方面無(wú)法同時(shí)滿(mǎn)足,所以,根據(jù)不同的應(yīng)用場(chǎng)景選擇最適合自己的才是王道。

從理解的難易程度角度(從低到高)
數(shù)據(jù)庫(kù) > 緩存 > Zookeeper

從實(shí)現(xiàn)的復(fù)雜性角度(從低到高)
Zookeeper >= 緩存 > 數(shù)據(jù)庫(kù)

從性能角度(從高到低)
緩存 > Zookeeper >= 數(shù)據(jù)庫(kù)

從可靠性角度(從高到低)
Zookeeper > 緩存 > 數(shù)據(jù)庫(kù)

總結(jié)

以上就是本文關(guān)于詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式的全部?jī)?nèi)容,感興趣的朋友可以繼續(xù)參閱:詳解java中的互斥鎖信號(hào)量和多線(xiàn)程等待機(jī)制 、apache zookeeper使用方法實(shí)例詳解 、幾個(gè)比較重要的MySQL變量 以及本站其他相關(guān)專(zhuān)題,希望對(duì)大家有所幫助。有什么問(wèn)題可以隨時(shí)留言,小編定會(huì)及時(shí)回復(fù),給大家提供更好的閱讀體驗(yàn)和幫助,感謝朋友們對(duì)本站的支持!

您可能感興趣的文章:
  • redisson實(shí)現(xiàn)分布式鎖原理
  • Redis上實(shí)現(xiàn)分布式鎖以提高性能的方案研究
  • 基于Redis實(shí)現(xiàn)分布式鎖以及任務(wù)隊(duì)列
  • redis中使用java腳本實(shí)現(xiàn)分布式鎖

標(biāo)簽:內(nèi)江 固原 防疫工作 汕尾 撫順 溫州 浙江 廣西

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式》,本文關(guān)鍵詞  詳細(xì),解讀,分布式,鎖,原理,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于詳細(xì)解讀分布式鎖原理及三種實(shí)現(xiàn)方式的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章