国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

深入理解PHP+Redis實(shí)現(xiàn)分布式鎖的相關(guān)問(wèn)題

這篇具有很好參考價(jià)值的文章主要介紹了深入理解PHP+Redis實(shí)現(xiàn)分布式鎖的相關(guān)問(wèn)題。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

概念

PHP使用分布式鎖,受語(yǔ)言本身的限制,有一些局限性。

  • 通俗理解單機(jī)鎖問(wèn)題:自家的鎖鎖自家的門,只能保證自家的事,管不了別人家不鎖門引發(fā)的問(wèn)題,于是有了分布式鎖。
  • 分布式鎖概念:是針對(duì)多個(gè)節(jié)點(diǎn)的鎖。避免出現(xiàn)數(shù)據(jù)不一致或者并發(fā)沖突的問(wèn)題,讓每個(gè)節(jié)點(diǎn)確保在任意時(shí)刻只有一個(gè)節(jié)點(diǎn)能夠?qū)操Y源進(jìn)行操作,單機(jī)的鎖只能夠單節(jié)點(diǎn)使用,多節(jié)點(diǎn)防不住。
  • 核心原理:分布式鎖的核心原理,就是在每個(gè)節(jié)點(diǎn)執(zhí)行時(shí),先去一個(gè)公共的地方判斷是否持有鎖,如果有鎖就說(shuō)明資源被占用,沒(méi)鎖就可以持有該資源。
  • 通俗舉例:多個(gè)部門,開(kāi)部門會(huì)議,需要占用會(huì)議室的位置,發(fā)現(xiàn)會(huì)議室門關(guān)著,不知道里面有沒(méi)有人,此時(shí)門外面有個(gè)牌子說(shuō)明是會(huì)議中,還是會(huì)議結(jié)束,離老遠(yuǎn)就知道會(huì)議室是不是被占用了,避免會(huì)議競(jìng)爭(zhēng)引起的錯(cuò)亂。

應(yīng)用場(chǎng)景

  • 分布式排它:保證只有一個(gè)節(jié)點(diǎn)被訪問(wèn),常用于秒殺,等并發(fā)問(wèn)題的處理。
  • 分布式任務(wù)調(diào)度:在分布式任務(wù)調(diào)度系統(tǒng)中,多個(gè)節(jié)點(diǎn)可能會(huì)競(jìng)爭(zhēng)執(zhí)行同一個(gè)任務(wù),使用分布式鎖可以確保只有一個(gè)節(jié)點(diǎn)能夠執(zhí)行該任務(wù),避免重復(fù)執(zhí)行和沖突。
  • 并發(fā)下數(shù)據(jù)庫(kù)事務(wù)幻讀問(wèn)題:并發(fā)下的MySQL事務(wù)當(dāng)中,插入數(shù)據(jù)前先判斷有沒(méi)有,沒(méi)有再插入,從而避免重復(fù),但是其它事務(wù)未提交,就檢測(cè)不到(RR的隔離級(jí)別導(dǎo)致的),但是插入相同數(shù)據(jù),又會(huì)導(dǎo)致唯一約束起作用從而報(bào)錯(cuò),添加分布式鎖,從而避免報(bào)錯(cuò)。(這場(chǎng)景適用于唯一約束沖突報(bào)錯(cuò)很多的場(chǎng)景功能,否則使用了會(huì)影響性能)。

分布式鎖的特點(diǎn)

  1. 互斥性,相同時(shí)間,只能有一個(gè)節(jié)點(diǎn)會(huì)獲取該鎖,其它節(jié)點(diǎn)要么等待要么直接返回失敗。
  2. 可重入(單個(gè)節(jié)點(diǎn)可重復(fù)獲取該鎖且不會(huì)發(fā)生阻塞),PHP的語(yǔ)言特性不支持。
  3. 安全(獲取鎖的節(jié)點(diǎn)崩潰或失去連接、鎖資源會(huì)釋放)。

可用的存儲(chǔ)組件選擇

Redis、MySQL(樂(lè)觀鎖、或悲觀鎖)、ZooKeeper、Etcd、Memcache等存儲(chǔ)組件都可以實(shí)現(xiàn)分布式鎖。
ZooKeeper、Etcd是Java生態(tài),PHP幾乎不用。
Memcache很少用了,一般都會(huì)用redis。
MySQL性能比不了Redis,高并發(fā)過(guò)來(lái)容易被夯住,數(shù)據(jù)不會(huì)自動(dòng)過(guò)期刪除,需要邏輯判斷。所以也不用。

分布式鎖要求高性能,和自動(dòng)過(guò)期的兜底特性,所以用Redis的set命令剛好。
Redis分布式鎖,又稱為Redis Distributed Lock,也叫RedLock。

用Redis手動(dòng)實(shí)現(xiàn)分布式鎖(示例)

這是花十分鐘寫出來(lái)的例子,不建議商用。

class RedLock {
    //聲明redis
    private $redis;

    /**
     * @function 構(gòu)造方法初始化redis
     * @other    void
     */
    public function __construct() {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        $this->redis = $redis;
    }


    /**
     * @function 非阻塞分布式鎖
     * @param    $key string 鎖名稱
     * @param    $ttl int    key自動(dòng)過(guò)期時(shí)間,單位毫秒
     * @return   array|false 成功返回?cái)?shù)組,失敗返回false
     * @other    void
     */
    public function redLock($lock_name, $ttl = 10000) {
        $val = base64_encode(openssl_random_pseudo_bytes(32));
        $set = $this->redis->set($lock_name, $val, ['NX', 'PX' => $ttl]);
        if($set === false) {
            return false;
        }

        return ['key' => $lock_name, 'val' => $val];
    }



    /**
     * @function 阻塞式分布式鎖
     * @param    $key string 鎖名稱
     * @param    $ttl int    key自動(dòng)過(guò)期時(shí)間,單位毫秒
     * @param    $ttl int    超時(shí)時(shí)間,單位毫秒
     * @return   array|false 成功返回?cái)?shù)組,失敗返回false
     * @other    void
     */
    public function redLockSpin($lock_name, $ttl = 10000, $timeout = 3000) {
        $start = bcmul(microtime(true), 1000, 2);
        $val = base64_encode(openssl_random_pseudo_bytes(32));
        $set = $this->redis->set($lock_name, $val, ['NX', 'PX' => $ttl]);
        if($set === false) {
            while(true) {
                //超時(shí)
                $start_loop = bcmul(microtime(true), 1000, 2);
                if(bcadd($start, $timeout, 2) <= $start_loop) {
                    return false;
                }

                //嘗試獲取鎖
                $set_loop = $this->redis->set($lock_name, $val, ['NX', 'PX' => $ttl]);
                if($set_loop) {
                    return ['key' => $lock_name, 'val' => $val];
                }

                usleep(50000);
            }
        }

        return ['key' => $lock_name, 'val' => $val];
    }


    /**
     * @function 釋放鎖資源
     * @param    $key array|false 鎖資源
     * @return   bool
     * @other    void
     */
    public function unLock($lock) {
        if($lock === false) {
            return false;
        }

        $script = '
            if redis.call("GET", KEYS[1]) == ARGV[1] then
                return redis.call("DEL", KEYS[1])
            else
                return 0
            end
        ';

        if(! $this->redis->eval($script, [$lock['key'], $lock['val']], 1)) {
            return false;
        }

        return true;
    }
}

$redLock = new RedLock();
if($lock = $redLock->redLockSpin('test_key')) {
    echo '搶到鎖了,處理一些業(yè)務(wù)邏輯';
} else {
    echo '鎖沒(méi)有搶到';
}

$redLock->unLock($lock);

現(xiàn)有的解決方案

java實(shí)現(xiàn)分布式鎖有redisson,PHP也有自己的包。
看過(guò)一些博主的用PHP實(shí)現(xiàn)分布式鎖,好多沒(méi)有使用Lua,這沒(méi)辦法保證多條Redis語(yǔ)句原子性的執(zhí)行。
項(xiàng)目中能用到這種東西的,對(duì)于高可用、原子性、穩(wěn)定性有很強(qiáng)的依賴,所以推薦使用成熟的擴(kuò)展包。

composer require signe/redlock-php
文檔:https://packagist.org/packages/signe/redlock-php
執(zhí)行之后看使用redis的monitor指令查看,發(fā)現(xiàn)用了Lua,說(shuō)明這個(gè)包,兼顧了原子性的操作。
我這個(gè)是示例,記得無(wú)論最后執(zhí)行成功還是失敗,都記得及時(shí)釋放鎖資源。

非自旋寫法
$server = new \Redis;
$server->connect('127.0.0.1', 6379);
$servers = [$server,];

$redLock = new \RedLock\RedLock($servers);
$lock = $redLock->lock('my_resource_name', 10000);

if($lock) {
    echo '加鎖成功';
    這里運(yùn)行某些代碼,有個(gè)問(wèn)題,PHP缺少機(jī)制,
    $redLock->unlock($lock);
} else {
    echo '加鎖失敗';
}


自旋寫法
$server = new \Redis;
$server->connect('127.0.0.1', 6379);
$servers = [$server,];

$redLock = new \RedLock\RedLock($servers);
$lock = $redLock->lock('my_resource_name', 10000);

if($lock) {
    echo '加鎖成功';
//    $redLock->unlock($lock);
} else {
    while(true) {
        $lock2 = $redLock->lock('my_resource_name', 10000);
        if($lock2) {
            echo '加鎖成功2';
            //運(yùn)行某些代碼
            $redLock->unlock($lock2);
            return '';
        } 
    }
}

如果需要:拿到鎖后,釋放鎖前,業(yè)務(wù)邏輯代碼塊再對(duì)拿到鎖的分布式鎖續(xù)期。
因?yàn)閞edis的key與val值都不變,只變動(dòng)過(guò)期時(shí)間,所以使用PEXPIRE指令,也可使用PSETEX指令。
又需要防止這個(gè)鎖自動(dòng)過(guò)期,已經(jīng)被其它節(jié)點(diǎn)占用,已經(jīng)改成了其它節(jié)點(diǎn)的數(shù)據(jù),所以value值需要驗(yàn)證是不是當(dāng)前鎖的value值。
兩個(gè)操作為了保證原子性,就用到了Lua。

//$redLock = new \RedLock\RedLock($servers);
//$lock = $redLock->lock('my_resource_name', 20000);

$script = '
            if redis.call("GET", KEYS[1]) == ARGV[1] then
            	return redis.call("PEXPIRE", KEYS[1], KEYS[2])
            else
                return 0
            end
        ';
$server->eval($script, [$lock['resource'], '毫秒過(guò)期時(shí)間', $lock['token']], 2);

PHP使用分布式鎖的局限性問(wèn)題

  • 重入性無(wú)法實(shí)現(xiàn):PHP這門語(yǔ)言有局限性,不適合和redis結(jié)合做分布式鎖,分布式鎖的重入性無(wú)法實(shí)現(xiàn),因?yàn)槟_本能執(zhí)行完內(nèi)存就被回收了,無(wú)法像C/C++那樣輕松操控進(jìn)程和線程。
  • 超時(shí)問(wèn)題沒(méi)有監(jiān)控機(jī)制:沒(méi)有像redisson一樣的watch dog看門狗的機(jī)制,去監(jiān)控業(yè)務(wù)執(zhí)行過(guò)長(zhǎng)導(dǎo)致redis分布式鎖自動(dòng)釋放,被其它鎖占用的問(wèn)題。

PHP使用分布式鎖,有種東施效顰的感覺(jué)。

為什么加鎖時(shí)set指令要加NX

set指令加nx表示,只有在key不存在的情況下才能設(shè)置鍵值對(duì)。
多個(gè)節(jié)點(diǎn)加鎖,獲取分布式鎖資源,實(shí)質(zhì)就是在redis中設(shè)置一條值。因?yàn)榉植际芥i的排它性,同一時(shí)間內(nèi)只能有一個(gè)節(jié)點(diǎn)可以拿到該鎖。
若用set,不加nx,就會(huì)產(chǎn)生覆蓋,造成業(yè)務(wù)錯(cuò)亂。

客戶端宕機(jī)導(dǎo)致鎖資源無(wú)法釋放的死鎖問(wèn)題

redis單線程通常不會(huì)發(fā)生死鎖問(wèn)題。
Redis在客戶端掛掉的情況的情況,會(huì)導(dǎo)致分布式鎖鎖資源無(wú)法及時(shí)釋放,這可能會(huì)導(dǎo)致其它節(jié)點(diǎn)無(wú)法加鎖從而阻塞,類似死鎖的效果。
添加過(guò)期時(shí)間做兜底即可。

對(duì)高可用:MySQL可以主從,Redis也可以,從而保證分布式鎖存儲(chǔ)的高可用性。

分布式鎖redis操作的原子性問(wèn)題

就算是redis事務(wù)(multi)也是弱事務(wù),仍舊會(huì)出現(xiàn)并發(fā)安全問(wèn)題,最好使用Lua+Redis的方式去實(shí)現(xiàn)原子性的分布式鎖,這會(huì)把一些指令集當(dāng)做一個(gè)任務(wù)隊(duì)列去處理,保證原子性。

如何設(shè)置拿到鎖資源后的超時(shí)時(shí)間

對(duì)于Java,redisson有watch dog的自動(dòng)監(jiān)控機(jī)制,但是PHP沒(méi)有。
PHP也很難實(shí)現(xiàn),原因有2:

  • 不知道自動(dòng)續(xù)期的時(shí)機(jī):業(yè)務(wù)流程沒(méi)走完,分布式鎖臨近過(guò)期才續(xù)期,業(yè)務(wù)流程走完了還續(xù)什么期?這個(gè)時(shí)機(jī),高并發(fā)場(chǎng)景下難以獲取,凈增加復(fù)雜度。
  • PHP語(yǔ)言本身缺少鎖機(jī)制:就算知道了要續(xù)期,加鎖與續(xù)期監(jiān)控,缺少鎖機(jī)制的強(qiáng)關(guān)聯(lián),加鎖一個(gè)進(jìn)程,監(jiān)控又一個(gè)進(jìn)程,進(jìn)程間通信是一個(gè)問(wèn)題,PHP進(jìn)程間通信與Redis操作無(wú)法原子執(zhí)行又是一個(gè)問(wèn)題,也就是說(shuō)就算被通知要續(xù)期了,再續(xù)期時(shí),鎖資源超時(shí)自動(dòng)釋放后,可能都被別的節(jié)點(diǎn)占用了。

PHP能做的只能是設(shè)置更多的超時(shí)時(shí)間,來(lái)防止鎖資源自動(dòng)釋放被其它節(jié)點(diǎn)搶走。
缺點(diǎn)也很明顯,一旦這個(gè)節(jié)點(diǎn)掛掉,鎖資源需要很長(zhǎng)時(shí)間才能釋放,這個(gè)時(shí)間段的分布式鎖無(wú)法被任意一個(gè)節(jié)點(diǎn)使用。

鎖資源的錯(cuò)誤釋放問(wèn)題

時(shí)序圖:

步驟 客戶端1 客戶端2 補(bǔ)充
1 獲取鎖成功 / /
2 執(zhí)行中 獲取鎖失敗 客戶端1的鎖阻塞了客戶端2
3 執(zhí)行中 獲取鎖失敗 客戶端2自旋,不斷嘗試獲取鎖
4 鎖資源到期自動(dòng)釋放 獲取鎖成功 由于客戶端1的鎖資源過(guò)期,才導(dǎo)致客戶端2拿到的分布式鎖
5 釋放鎖 執(zhí)行中 這一步才是客戶端1真正釋放(刪)鎖的時(shí)刻,但是由于沒(méi)做驗(yàn)證,這個(gè)釋放(刪)的過(guò)程,會(huì)把會(huì)話2創(chuàng)建的鎖給釋放(刪)掉,造成誤刪除

為了避免這個(gè)問(wèn)題,val值可設(shè)置為節(jié)點(diǎn)標(biāo)識(shí)。
所以redis在get值的時(shí)候,需要判斷,val值是不是當(dāng)前的節(jié)點(diǎn)標(biāo)識(shí)。
為了保證原子性,查詢和刪除兩個(gè)操作需要用Lua腳本。

其次要注意,不管節(jié)點(diǎn)程序執(zhí)行成功或者失敗,只要該走的流程走完了,都需要及時(shí)釋放鎖。

分布式鎖的可重入問(wèn)題

PHP解決不了。
假設(shè)同一個(gè)節(jié)點(diǎn),遞歸或循環(huán)添加分布式鎖,是否讓同一節(jié)點(diǎn)重復(fù)加同一把鎖,大部分場(chǎng)景不需要,但是也得看業(yè)務(wù)場(chǎng)景。
這種機(jī)制是為了避免第一層循環(huán)添加成功,之后失敗的問(wèn)題。

對(duì)于非PHP而言,重入問(wèn)題,還需要再維持一個(gè)redis hash,key為鎖名,field為節(jié)點(diǎn)的唯一標(biāo)識(shí),value為重入次數(shù),重入1次次數(shù)加1。因?yàn)橹厝胂喈?dāng)于重新獲取鎖,但是不會(huì)新增鎖資源,如果這個(gè)時(shí)間被刪掉,那么重入時(shí)會(huì)加鎖成功,但鎖資源被強(qiáng)制釋放,此時(shí)重入后的業(yè)務(wù)邏輯還不一定執(zhí)行完畢。所以刪除時(shí)需要判斷value值是否為0,如果不為0,說(shuō)明有重入,這兩步操作,也是需要再一個(gè)Lua腳本中。

分布式鎖的自旋機(jī)制

自旋可以理解為內(nèi)部死循環(huán),內(nèi)部不斷重試,直到滿足條件,直觀感受就是被阻塞。
如果沒(méi)有自旋,10個(gè)節(jié)點(diǎn),只有1個(gè)能加鎖成功,其余9個(gè)失敗,如果這9個(gè)全部失敗掉,看起來(lái)差點(diǎn)意思。

因此可以選擇被阻塞,期間不斷重試,所謂的自旋方案,其實(shí)很好理解,重試偽代碼如下:

while(加鎖失敗) {
	usleep(10000);
	重新嘗試加鎖代碼
	if(加鎖成功) {
		return '加鎖成功';
	}
}

此處也可以添加一個(gè)次數(shù)限制,防止永久死循環(huán)的兜底策略
$retry_count = 0;
while(true) {
    $retry_count ++;
    if('加鎖成功') {
        return '加鎖成功';
    }

    if($retry_count > 20) {
        echo 1;
        return '重試次數(shù)過(guò)多';
    }
    
    usleep(30000);
}

也可以根據(jù)時(shí)間去做限制,防止永久死循環(huán)的兜底策略
$start_time = microtime(true);
while('加鎖失敗') {
	if(false) {
		return '加鎖成功';
	}

	if($start_time + 5 <= microtime(true)) {
		return '超時(shí)';	
	}

	usleep(30000);
}

Redis主從架構(gòu)對(duì)分布式鎖的高可用問(wèn)題。

節(jié)點(diǎn)1再master上獲取到了分布式鎖,叫l(wèi)ock1,此時(shí)master還沒(méi)有同步到slave,結(jié)果master掛掉了。
此時(shí)故障轉(zhuǎn)移,slave做頂梁柱,節(jié)點(diǎn)2也獲取到了slave的分布式鎖,也叫l(wèi)ock1。
這種情況違背了分布式鎖的排它性。概率很小,但是有可能發(fā)生。
setnx無(wú)法解決分布式場(chǎng)景下的鎖排它性問(wèn)題。
這個(gè)是運(yùn)維層面要考慮的東西。

手動(dòng)實(shí)現(xiàn)分布式鎖容易被忽略的問(wèn)題

分布式鎖這種工程化的東西,每個(gè)零件都有用,雖然RedLock底層用redis set指令實(shí)現(xiàn)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-842659.html

  • 若忘記加超時(shí)時(shí)間:上鎖的節(jié)點(diǎn)掛掉沒(méi)有釋放鎖資源,其它節(jié)點(diǎn)會(huì)一直拿不到鎖,嚴(yán)重影響業(yè)務(wù)。
  • 若忘記加value值判斷去釋放鎖:A節(jié)點(diǎn)在執(zhí)行業(yè)務(wù)邏輯超時(shí),自動(dòng)釋放鎖資源被B節(jié)點(diǎn)搶去,等A節(jié)點(diǎn)執(zhí)行完業(yè)務(wù)代碼后釋放鎖,會(huì)把B節(jié)點(diǎn)的鎖刪除。
  • 若忘記用Lua腳本:這導(dǎo)致redis在執(zhí)行任務(wù)期間,同一客戶端的多個(gè)腳本不會(huì)在一個(gè)Redis內(nèi)置的任務(wù)隊(duì)列處理,保證不了原子性,超賣的并發(fā)安全問(wèn)題就是這樣產(chǎn)生的。
  • 覆蓋問(wèn)題:redis分布式鎖設(shè)置值時(shí),用的setnx思想(有值則不設(shè)置,避免覆蓋),若用set,整不好把原先的覆蓋掉了。
  • 對(duì)于像Java(PHP不行)語(yǔ)言:手動(dòng)實(shí)現(xiàn)可能缺少key的監(jiān)控過(guò)期,以及重入性問(wèn)題。

到了這里,關(guān)于深入理解PHP+Redis實(shí)現(xiàn)分布式鎖的相關(guān)問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Redis】Redis分布式鎖的10個(gè)坑

    【Redis】Redis分布式鎖的10個(gè)坑

    日常開(kāi)發(fā)中,經(jīng)常會(huì)碰到秒殺搶購(gòu)等業(yè)務(wù)。為了避免并發(fā)請(qǐng)求造成的庫(kù)存超賣等問(wèn)題,我們一般會(huì)用到Redis分布式鎖。但是使用Redis分布式鎖,很容易踩坑哦~ 本文將給大家分析闡述,Redis分布式鎖的10個(gè)坑~ 一說(shuō)到實(shí)現(xiàn)Redis的分布式鎖,很多小伙伴馬上就會(huì)想到setnx+ expire命令。

    2024年02月05日
    瀏覽(26)
  • Redis——》Redis的部署方式對(duì)分布式鎖的影響

    Redis——》Redis的部署方式對(duì)分布式鎖的影響

    推薦鏈接: ????總結(jié)——》【Java】 ????總結(jié)——》【Mysql】 ????總結(jié)——》【Redis】 ????總結(jié)——》【Kafka】 ????總結(jié)——》【Spring】 ????總結(jié)——》【SpringBoot】 ????總結(jié)——》【MyBatis、MyBatis-Plus】 ????總結(jié)——》【Linux】 ????總結(jié)——》【MongoDB】 ???

    2024年02月10日
    瀏覽(23)
  • 【面試題24】你是如何使用Redis分布式鎖的

    本文已收錄于PHP全棧系列專欄:PHP面試專區(qū)。 計(jì)劃將全覆蓋PHP開(kāi)發(fā)領(lǐng)域所有的面試題, 對(duì)標(biāo)資深工程師/架構(gòu)師序列 ,歡迎大家提前關(guān)注鎖定。 Redis分布式鎖是一種利用Redis實(shí)現(xiàn)的分布式鎖機(jī)制。它通過(guò)在共享的Redis實(shí)例上設(shè)置一個(gè)特定的鍵值對(duì)來(lái)實(shí)現(xiàn)對(duì)資源的互斥訪問(wèn)。今

    2024年02月11日
    瀏覽(17)
  • 【征服redis15】分布式鎖的功能與整體設(shè)計(jì)方案

    【征服redis15】分布式鎖的功能與整體設(shè)計(jì)方案

    目錄 ?1. 分布式鎖的概念 2.基于數(shù)據(jù)庫(kù)做分布式鎖 2.1 基于表主鍵唯一做分布式鎖 2.2 基于表字段版本號(hào)做分布式鎖 2.3 基于數(shù)據(jù)庫(kù)排他鎖做分布式鎖 3.使用Redis做分布式鎖 3.1 redis實(shí)現(xiàn)分布式鎖的基本原理 3.2 問(wèn)題一:增加超時(shí)機(jī)制,防止長(zhǎng)期持有的情況 3.3 問(wèn)題2:重入的問(wèn)題

    2024年01月22日
    瀏覽(22)
  • 分布式鎖的幾種實(shí)現(xiàn)方式:

    redis是基于單線程,在某個(gè)時(shí)刻只會(huì)有一個(gè)線程執(zhí)行命令,可以利用set原子性的操作,配合set nx(RedisStringCommands.SetOption.SET_IF_ABSENT) ,這樣,當(dāng)多個(gè)線程或多個(gè)節(jié)點(diǎn)嘗試獲取鎖時(shí),只有一個(gè)可以成功,其他的會(huì)因?yàn)殒i已存在而獲取失敗。這種方式通過(guò) Redis 來(lái)實(shí)現(xiàn)分布式鎖,

    2024年01月18日
    瀏覽(18)
  • ZooKeeper分布式鎖的實(shí)現(xiàn)與應(yīng)用

    ZooKeeper是一種分布式應(yīng)用程序協(xié)調(diào)服務(wù),它可以管理大規(guī)模的集群,并提供可靠的、有序的、高效的數(shù)據(jù)通信。其中,ZooKeeper提供的分布式鎖是一種常見(jiàn)的分布式鎖實(shí)現(xiàn),本文將對(duì)其進(jìn)行詳細(xì)介紹。 在分布式系統(tǒng)中,多個(gè)進(jìn)程或節(jié)點(diǎn)可能需要同時(shí)訪問(wèn)共享資源。為了確保數(shù)據(jù)

    2024年02月02日
    瀏覽(21)
  • 高并發(fā)緩存問(wèn)題分析以及分布式鎖的實(shí)現(xiàn)

    高并發(fā)緩存問(wèn)題分析以及分布式鎖的實(shí)現(xiàn)

    在高并發(fā)的環(huán)境下,比如淘寶,京東不定時(shí)的促銷活動(dòng),大量的用戶訪問(wèn)會(huì)導(dǎo)致數(shù)據(jù)庫(kù)的性能下降,進(jìn)而有可能數(shù)據(jù)庫(kù)宕機(jī)從而不能產(chǎn)生正常的服務(wù),一般一個(gè)系統(tǒng)最大的性能瓶頸,就是數(shù)據(jù)庫(kù)的io操作,如果發(fā)生大量的io那么他的問(wèn)題也會(huì)隨之而來(lái)。從數(shù)據(jù)庫(kù)入手也是調(diào)優(yōu)性價(jià)比最高

    2024年01月19日
    瀏覽(33)
  • 從原理到實(shí)踐,分析 Redisson 分布式鎖的實(shí)現(xiàn)方案(二)

    從原理到實(shí)踐,分析 Redisson 分布式鎖的實(shí)現(xiàn)方案(二)

    ????????上篇講解了如何用 Redis 實(shí)現(xiàn)分布式鎖的方案,它提供了簡(jiǎn)單的原語(yǔ)來(lái)實(shí)現(xiàn)基于Redis的分布式鎖。然而,Redis作為分布式鎖的實(shí)現(xiàn)方式也存在一些缺點(diǎn)。本文將引入Redisson來(lái)實(shí)現(xiàn)分布式鎖。 ????????Redisson是一個(gè)基于Redis的分布式Java框架。它提供了豐富的功能和工

    2024年02月15日
    瀏覽(17)
  • 【Xiao.Lei】- Git詳解:深入理解分布式版本控制

    【Xiao.Lei】- Git詳解:深入理解分布式版本控制

    在現(xiàn)代軟件開(kāi)發(fā)中,版本控制是一個(gè)至關(guān)重要的方面。Git,作為最流行的分布式版本控制系統(tǒng)之一,為開(kāi)發(fā)者提供了高效、靈活的協(xié)作和版本管理工具。本文將深入探討Git的各個(gè)方面,包括基礎(chǔ)概念、工作流程、分支管理、團(tuán)隊(duì)協(xié)作等,并結(jié)合詳細(xì)的命令說(shuō)明,旨在幫助讀者

    2024年01月21日
    瀏覽(22)
  • “深入解析Redis:高性能緩存與分布式數(shù)據(jù)存儲(chǔ)“

    標(biāo)題:深入解析Redis:高性能緩存與分布式數(shù)據(jù)存儲(chǔ) 摘要:本文將深入解析Redis,介紹其作為高性能緩存和分布式數(shù)據(jù)存儲(chǔ)的特點(diǎn)和功能,并提供示例代碼展示其使用方法。 正文: 一、引言 Redis是一個(gè)開(kāi)源的內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)系統(tǒng),它以其高性能、靈活的數(shù)據(jù)結(jié)構(gòu)以及豐富的

    2024年02月17日
    瀏覽(25)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包