最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis實(shí)現(xiàn)分布式鎖全解析之從原理到實(shí)踐過(guò)程

 更新時(shí)間:2025年05月04日 21:30:48   作者:nihui123  
這篇文章主要介紹了Redis實(shí)現(xiàn)分布式鎖全解析之從原理到實(shí)踐過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

在分布式系統(tǒng)開(kāi)發(fā)的廣袤領(lǐng)域中,資源競(jìng)爭(zhēng)問(wèn)題宛如隱藏在暗處的礁石,時(shí)刻威脅著系統(tǒng)的穩(wěn)定性與數(shù)據(jù)一致性。當(dāng)多個(gè)服務(wù)實(shí)例如同脫韁野馬般同時(shí)沖向同一份共享數(shù)據(jù),試圖進(jìn)行修改操作時(shí),一場(chǎng)混亂的 “數(shù)據(jù)搶奪戰(zhàn)” 便悄然上演。此時(shí),分布式鎖如同一位公正的裁判,站出來(lái)維護(hù)秩序,確保同一時(shí)刻僅有一個(gè)實(shí)例能夠?qū)Y源進(jìn)行操作,成為保障分布式系統(tǒng)正常運(yùn)轉(zhuǎn)的關(guān)鍵要素。

一、背景介紹

在分布式架構(gòu)這一復(fù)雜生態(tài)中,不同的服務(wù)器節(jié)點(diǎn)猶如散布在各地的獨(dú)立個(gè)體,它們?cè)诟髯缘膬?nèi)存空間中運(yùn)行,彼此之間難以直接感知對(duì)方的狀態(tài)。

這就導(dǎo)致傳統(tǒng)單機(jī)鎖機(jī)制,例如 Java 里的 synchronized 關(guān)鍵字,在分布式場(chǎng)景下如同折翼的飛鳥(niǎo),失去了原有的效用。而 Redis,憑借其卓越的分布式緩存能力,以高可用性、高性能以及豐富的數(shù)據(jù)結(jié)構(gòu),成為構(gòu)建分布式鎖的理想基石,為解決分布式環(huán)境下的資源競(jìng)爭(zhēng)難題帶來(lái)了曙光。

二、解決方案

(一)使用 SETNX 命令

SETNX(SET if Not eXists)堪稱(chēng) Redis 實(shí)現(xiàn)分布式鎖的核心原子性命令。當(dāng)執(zhí)行 SETNX key value 操作時(shí),Redis 會(huì)進(jìn)行一次原子化的檢查與設(shè)置。

若指定的 key 在數(shù)據(jù)庫(kù)中尚未存在,那么設(shè)置操作將成功執(zhí)行,同時(shí)返回 1,意味著鎖被成功獲取;反之,若 key 已然存在,設(shè)置操作則不會(huì)生效,返回 0,表明鎖已被其他實(shí)例持有。通過(guò)這一特性,我們得以初步構(gòu)建起分布式鎖的雛形。

以 Python 結(jié)合 Redis - py 庫(kù)為例,代碼如下:

import redis

r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = "distributed_lock"
lock_value = "unique_value"
if r.setnx(lock_key, lock_value):
    try:
        # 這里寫(xiě)需要加鎖執(zhí)行的業(yè)務(wù)邏輯
        print("獲取到鎖,執(zhí)行任務(wù)")
    finally:
        r.delete(lock_key)
else:
    print("未能獲取到鎖")

在這段代碼中,當(dāng)程序嘗試獲取鎖時(shí),首先調(diào)用setnx方法。若返回值為 True,即獲取鎖成功,隨后在try塊中執(zhí)行需要加鎖保護(hù)的業(yè)務(wù)邏輯,執(zhí)行完畢后,無(wú)論是否發(fā)生異常,都會(huì)在finally塊中釋放鎖,以確保鎖資源不會(huì)被長(zhǎng)時(shí)間占用。

(二)設(shè)置鎖的過(guò)期時(shí)間

盡管 SETNX 命令為我們提供了基本的鎖獲取機(jī)制,但在實(shí)際應(yīng)用中,它仍存在一個(gè)潛在的風(fēng)險(xiǎn)。倘若獲取到鎖的節(jié)點(diǎn)突發(fā)故障,例如硬件崩潰、網(wǎng)絡(luò)中斷等,且未主動(dòng)釋放鎖,那么這把鎖將如同被遺忘在角落的珍寶,一直處于被占用狀態(tài),導(dǎo)致其他節(jié)點(diǎn)在無(wú)盡的等待中無(wú)法獲取鎖,嚴(yán)重影響系統(tǒng)的正常運(yùn)行。為化解這一隱患,我們需要為鎖設(shè)置合理的過(guò)期時(shí)間。

在 Redis 中,通過(guò) SET key value EX seconds 命令,我們能夠輕松為鎖設(shè)置過(guò)期時(shí)間。例如:

import redis

r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = "distributed_lock"
lock_value = "unique_value"
if r.set(lock_key, lock_value, ex=10, nx=True):
    try:
        # 這里寫(xiě)需要加鎖執(zhí)行的業(yè)務(wù)邏輯
        print("獲取到鎖,執(zhí)行任務(wù)")
    finally:
        r.delete(lock_key)
else:
    print("未能獲取到鎖")

上述代碼中,ex=10表示為鎖設(shè)置了 10 秒的過(guò)期時(shí)間。若在 10 秒內(nèi),持有鎖的節(jié)點(diǎn)正常完成業(yè)務(wù)操作并釋放鎖,一切安好;若 10 秒內(nèi)節(jié)點(diǎn)未完成操作或發(fā)生故障,鎖將自動(dòng)過(guò)期,其他節(jié)點(diǎn)便有機(jī)會(huì)獲取鎖,從而避免了因鎖長(zhǎng)時(shí)間被占用而導(dǎo)致的系統(tǒng)僵局。

(三)解決鎖的誤刪問(wèn)題

在分布式系統(tǒng)復(fù)雜多變的運(yùn)行環(huán)境下,鎖的誤刪問(wèn)題猶如一顆隱藏的定時(shí)炸彈,隨時(shí)可能引爆數(shù)據(jù)一致性的危機(jī)。設(shè)想這樣一個(gè)場(chǎng)景:節(jié)點(diǎn) A 成功獲取到鎖,并設(shè)置了 10 秒的過(guò)期時(shí)間。然而,由于業(yè)務(wù)邏輯的復(fù)雜性或外部因素干擾,節(jié)點(diǎn) A 執(zhí)行任務(wù)的時(shí)間超過(guò)了 10 秒,此時(shí)鎖自動(dòng)過(guò)期并被釋放。緊接著,節(jié)點(diǎn) B 順利獲取到鎖并開(kāi)始執(zhí)行任務(wù)。就在這時(shí),節(jié)點(diǎn) A 完成任務(wù),準(zhǔn)備釋放鎖,由于它并不知曉鎖已經(jīng)過(guò)期并被重新分配,便貿(mào)然執(zhí)行了釋放操作,結(jié)果誤刪了節(jié)點(diǎn) B 持有的鎖,這無(wú)疑將引發(fā)一系列不可預(yù)測(cè)的后果。

為了精準(zhǔn)拆除這顆 “定時(shí)炸彈”,我們需要在設(shè)置鎖時(shí),為鎖值賦予一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)。這樣在釋放鎖之前,先仔細(xì)判斷當(dāng)前鎖值是否與自己當(dāng)初設(shè)置的一致。只有當(dāng)兩者匹配時(shí),才執(zhí)行釋放操作,從而有效避免誤刪他人鎖的情況發(fā)生。

借助 Python 與 Redis - py 庫(kù),代碼調(diào)整如下:

import redis
import uuid

r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = "distributed_lock"
lock_value = str(uuid.uuid4())
if r.set(lock_key, lock_value, ex=10, nx=True):
    try:
        # 這里寫(xiě)需要加鎖執(zhí)行的業(yè)務(wù)邏輯
        print("獲取到鎖,執(zhí)行任務(wù)")
    finally:
        if r.get(lock_key) == lock_value.encode('utf-8'):
            r.delete(lock_key)
else:
    print("未能獲取到鎖")

在這段優(yōu)化后的代碼中,lock_value通過(guò)uuid.uuid4()生成一個(gè)全球唯一的標(biāo)識(shí)符。在釋放鎖時(shí),先通過(guò)r.get(lock_key)獲取當(dāng)前鎖值,并與最初設(shè)置的lock_value進(jìn)行比對(duì),只有當(dāng)兩者完全一致時(shí),才調(diào)用r.delete(lock_key)釋放鎖,極大地提升了鎖操作的安全性與準(zhǔn)確性。

(四)Redis 集群環(huán)境下的分布式鎖實(shí)現(xiàn)

在實(shí)際的生產(chǎn)環(huán)境中,為了應(yīng)對(duì)高并發(fā)、大規(guī)模的業(yè)務(wù)需求,Redis 往往以集群的形式部署。在 Redis 集群模式下實(shí)現(xiàn)分布式鎖,相較于單機(jī)環(huán)境更為復(fù)雜,需要考慮數(shù)據(jù)分片、節(jié)點(diǎn)故障轉(zhuǎn)移等諸多因素。
Redis 集群采用分片機(jī)制,將數(shù)據(jù)分散存儲(chǔ)在多個(gè)節(jié)點(diǎn)上。當(dāng)我們嘗試在集群環(huán)境中獲取分布式鎖時(shí),需要確保鎖的相關(guān)操作能夠在整個(gè)集群范圍內(nèi)保持一致性。一種常見(jiàn)的做法是使用 Redlock 算法。

Redlock 算法的核心思想是:客戶端需要向集群中的多個(gè) Redis 節(jié)點(diǎn)同時(shí)發(fā)起獲取鎖的請(qǐng)求。假設(shè)集群中有 N 個(gè)節(jié)點(diǎn),當(dāng)客戶端成功從超過(guò)半數(shù)(即大于等于 (N + 1) / 2)的節(jié)點(diǎn)獲取到鎖時(shí),才認(rèn)為鎖獲取成功。并且,每個(gè)鎖都設(shè)置了一個(gè)較短的有效期,以應(yīng)對(duì)節(jié)點(diǎn)故障或網(wǎng)絡(luò)分區(qū)等異常情況。在釋放鎖時(shí),客戶端需要向所有獲取過(guò)鎖的節(jié)點(diǎn)發(fā)送釋放請(qǐng)求,確保鎖被徹底釋放。

以 Python 實(shí)現(xiàn) Redlock 算法為例,可借助redlock - py庫(kù):

from redlock import Redlock

# 定義Redis節(jié)點(diǎn)列表
nodes = [
    {
        "host": "localhost",
        "port": 6379,
        "db": 0
    },
    {
        "host": "localhost",
        "port": 6380,
        "db": 0
    },
    {
        "host": "localhost",
        "port": 6381,
        "db": 0
    }
]

# 創(chuàng)建Redlock實(shí)例
redlock = Redlock(nodes)
lock_key = "distributed_lock"
lock_value = str(uuid.uuid4())
lock_acquired = redlock.lock(lock_key, lock_value, 1000)
if lock_acquired:
    try:
        # 執(zhí)行加鎖后的業(yè)務(wù)邏輯
        print("獲取到鎖,執(zhí)行任務(wù)")
    finally:
        redlock.unlock(lock_key, lock_value)
else:
    print("未能獲取到鎖")

在上述代碼中,首先定義了 Redis 集群中的節(jié)點(diǎn)列表,然后創(chuàng)建Redlock實(shí)例。通過(guò)調(diào)用lock方法嘗試獲取鎖,當(dāng)成功獲取到鎖后,執(zhí)行相應(yīng)的業(yè)務(wù)邏輯,最后在業(yè)務(wù)完成時(shí),調(diào)用unlock方法釋放鎖。Redlock 算法通過(guò)多節(jié)點(diǎn)交互,增強(qiáng)了分布式鎖在集群環(huán)境中的可靠性與健壯性。

(五)分布式鎖的性能優(yōu)化

在高并發(fā)的分布式系統(tǒng)中,分布式鎖的性能表現(xiàn)直接影響著系統(tǒng)的整體吞吐量與響應(yīng)速度。為了提升分布式鎖的性能,我們可以從以下幾個(gè)方面著手優(yōu)化:  

  • 減少網(wǎng)絡(luò)開(kāi)銷(xiāo):盡量減少客戶端與 Redis 服務(wù)器之間的網(wǎng)絡(luò)請(qǐng)求次數(shù)。例如,在獲取鎖時(shí),可以一次性將鎖的相關(guān)信息(如鎖值、過(guò)期時(shí)間等)發(fā)送給 Redis,避免多次往返請(qǐng)求。
  • 優(yōu)化鎖的粒度:合理劃分鎖的作用范圍,避免設(shè)置過(guò)大粒度的鎖,導(dǎo)致并發(fā)性能下降。如果業(yè)務(wù)允許,可以將大的業(yè)務(wù)操作拆分成多個(gè)小的操作,分別使用細(xì)粒度的鎖進(jìn)行保護(hù),從而提高并發(fā)執(zhí)行效率。
  • 緩存鎖狀態(tài):對(duì)于一些頻繁獲取鎖的場(chǎng)景,可以在客戶端緩存鎖的狀態(tài)。在嘗試獲取鎖之前,先檢查本地緩存中的鎖狀態(tài),若鎖處于未被占用狀態(tài),再向 Redis 發(fā)送獲取鎖的請(qǐng)求,這樣可以減少對(duì) Redis 的壓力,提升系統(tǒng)性能。

總結(jié)

通過(guò) Redis 實(shí)現(xiàn)分布式鎖,為分布式系統(tǒng)中的資源競(jìng)爭(zhēng)問(wèn)題提供了行之有效的解決方案。然而,在實(shí)際應(yīng)用中,從鎖的基本獲取與釋放機(jī)制,到應(yīng)對(duì)鎖的過(guò)期、誤刪等復(fù)雜情況,再到 Redis 集群環(huán)境下的鎖實(shí)現(xiàn)以及性能優(yōu)化,每一個(gè)環(huán)節(jié)都充滿了挑戰(zhàn)與機(jī)遇。廣大開(kāi)發(fā)人員們,在你們使用 Redis 實(shí)現(xiàn)分布式鎖的征程中,或許也遇到過(guò)各種各樣的難題。希望大家能在評(píng)論區(qū)踴躍分享自己的經(jīng)驗(yàn)與困惑,讓我們攜手共進(jìn),不斷探索如何更高效、更可靠地運(yùn)用 Redis,為分布式系統(tǒng)打造堅(jiān)不可摧的防護(hù)壁壘,共同推動(dòng)分布式技術(shù)的蓬勃發(fā)展。

集群環(huán)境下的分布式鎖實(shí)現(xiàn)以及性能優(yōu)化等內(nèi)容,文章深度有所提升。你看看是否符合你對(duì)深度的要求?要是還有其他想法,比如再補(bǔ)充某些特定場(chǎng)景下的案例等,都可以提出來(lái)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 利用Redis實(shí)現(xiàn)點(diǎn)贊功能的示例代碼

    利用Redis實(shí)現(xiàn)點(diǎn)贊功能的示例代碼

    點(diǎn)贊對(duì)我們來(lái)說(shuō)并不陌生,我們經(jīng)常會(huì)在手機(jī)軟件或者網(wǎng)頁(yè)中看到它。今天就讓我們來(lái)了解一下如何用Redis實(shí)現(xiàn)這一功能吧,感興趣的可以嘗試一下
    2022-06-06
  • Redis實(shí)戰(zhàn)之百度首頁(yè)新聞熱榜的實(shí)現(xiàn)代碼

    Redis實(shí)戰(zhàn)之百度首頁(yè)新聞熱榜的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Redis實(shí)戰(zhàn)之百度首頁(yè)新聞熱榜的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例

    Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例

    本文主要介紹了Redis7.2.x主從復(fù)制的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • 分布式鎖為什么要選擇Zookeeper而不是Redis?看完這篇你就明白了

    分布式鎖為什么要選擇Zookeeper而不是Redis?看完這篇你就明白了

    Zookeeper的機(jī)制可以保證分布式鎖實(shí)現(xiàn)業(yè)務(wù)代碼簡(jiǎn)單,成本低,Redis如果要解決分布式鎖的問(wèn)題,對(duì)于一些復(fù)雜的情況,很難解決,成本較高,這篇文章重點(diǎn)給大家介紹分布式鎖選擇Zookeeper 而不是Redis的理由,一起看看吧
    2021-05-05
  • Python的Flask框架使用Redis做數(shù)據(jù)緩存的配置方法

    Python的Flask框架使用Redis做數(shù)據(jù)緩存的配置方法

    Redis數(shù)據(jù)庫(kù)依賴于主存,在關(guān)系型數(shù)據(jù)庫(kù)以外再配套R(shí)edis管理緩存數(shù)據(jù)將對(duì)性能會(huì)有很大的提升,這里我們就來(lái)看一下Python的Flask框架使用Redis做數(shù)據(jù)緩存的配置方法
    2016-06-06
  • Redis中big?keys發(fā)現(xiàn)與解決過(guò)程

    Redis中big?keys發(fā)現(xiàn)與解決過(guò)程

    文章從bigkeys的定義、產(chǎn)生原因、危害、如何發(fā)現(xiàn)以及處理方法等方面詳細(xì)介紹了Redis中bigkeys的問(wèn)題,bigkeys會(huì)導(dǎo)致請(qǐng)求響應(yīng)慢、網(wǎng)絡(luò)卡頓、數(shù)據(jù)丟失等問(wèn)題,需要通過(guò)異步刪除、拆分key等方法進(jìn)行處理
    2026-04-04
  • Redis實(shí)現(xiàn)限流功能的幾種方法總結(jié)

    Redis實(shí)現(xiàn)限流功能的幾種方法總結(jié)

    在實(shí)際業(yè)務(wù)場(chǎng)景中,限流是保護(hù)系統(tǒng)的重要手段:在一段時(shí)間(period)內(nèi),限定某個(gè)行為(action)的最大次數(shù)(max_count),本文介紹如何基于 Redis 實(shí)現(xiàn)多種限流方案,需要的朋友可以參考下
    2026-05-05
  • Redis協(xié)議具體用法詳解

    Redis協(xié)議具體用法詳解

    在本篇文章中小編給大家整理了關(guān)于Redis協(xié)議具體用法以及相關(guān)內(nèi)容知識(shí)點(diǎn),需要的朋友們學(xué)習(xí)下。
    2019-06-06
  • 查看Redis內(nèi)存信息的命令

    查看Redis內(nèi)存信息的命令

    Redis 是一個(gè)開(kāi)源、高性能的Key-Value數(shù)據(jù)庫(kù),被廣泛應(yīng)用在服務(wù)器各種場(chǎng)景中。本文介紹幾個(gè)查看Redis內(nèi)存信息的命令,包括常用的info memory、info keyspace、bigkeys等。
    2020-09-09
  • 從源碼解讀redis持久化

    從源碼解讀redis持久化

    redis的持久化也就是數(shù)據(jù)落地,對(duì)于任何一個(gè)數(shù)據(jù)系統(tǒng)都要考慮是不是需要數(shù)據(jù)落地。在系統(tǒng)崩潰或是機(jī)房掉電等的情況下,將有用的數(shù)據(jù)記錄在非易失性存儲(chǔ)器上面,防止數(shù)據(jù)丟失,以及用來(lái)系統(tǒng)重啟時(shí)的數(shù)據(jù)恢復(fù)。
    2018-08-08

最新評(píng)論

郎溪县| 牙克石市| 甘南县| 顺义区| 都昌县| 综艺| 平湖市| 中江县| 武清区| 修文县| 越西县| 咸宁市| 玉溪市| 田阳县| 闽清县| 黔南| 景东| 青海省| 巩留县| 花垣县| 孝昌县| 大名县| 盐亭县| 如东县| 察隅县| 千阳县| 德安县| 铁岭县| 哈密市| 洛隆县| 宜黄县| 龙海市| 固安县| 比如县| 靖州| 东山县| 茂名市| 新民市| 孝昌县| 茂名市| 泸州市|