校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁(yè) > 知識(shí)庫(kù) > Redis如何實(shí)現(xiàn)分布式鎖

Redis如何實(shí)現(xiàn)分布式鎖

熱門標(biāo)簽:魔獸2青云地圖標(biāo)注 山東外呼銷售系統(tǒng)招商 宿遷便宜外呼系統(tǒng)平臺(tái) 北京400電話辦理收費(fèi)標(biāo)準(zhǔn) 日本中國(guó)地圖標(biāo)注 貴州電銷卡外呼系統(tǒng) 鄭州人工智能電銷機(jī)器人系統(tǒng) 超呼電話機(jī)器人 十堰營(yíng)銷電銷機(jī)器人哪家便宜

今天我們來(lái)聊一聊分布式鎖的那些事。

相信大家對(duì)鎖已經(jīng)不陌生了,我們?cè)诙嗑€程環(huán)境中,如果需要對(duì)同一個(gè)資源進(jìn)行操作,為了避免數(shù)據(jù)不一致,我們需要在操作共享資源之前進(jìn)行加鎖操作。在計(jì)算機(jī)科學(xué)中,鎖(lock)或互斥(mutex)是一種同步機(jī)制,用于在有許多執(zhí)行線程的環(huán)境中強(qiáng)制對(duì)資源的訪問(wèn)限制。

比如你去相親,發(fā)現(xiàn)你和一大哥同時(shí)和一個(gè)女的相親,那怎么行呢...,搞不好還要被揍一頓。

那什么是分布式鎖呢。當(dāng)多個(gè)客戶端需要爭(zhēng)搶鎖時(shí),我們就需要分布式鎖。這把鎖不能是某個(gè)客戶端本地的鎖,否則的話,其它客戶端是無(wú)法訪問(wèn)的。所以分布式鎖是需要存儲(chǔ)在共享存儲(chǔ)系統(tǒng)中的,比如Redis、Zookeeper等,可以被多個(gè)客戶端共享訪問(wèn)和獲取。今天我們就來(lái)看一下如何使用Redis來(lái)實(shí)現(xiàn)分布式鎖。

一、前言

在正式開(kāi)始之前,我們先來(lái)了解兩個(gè)Redis的命令:

SETNX key value

這個(gè)命名的含義是,當(dāng)key存在時(shí),不做任何賦值操作;當(dāng)key不存在時(shí),就創(chuàng)建key,并賦值成value,即(不存在即設(shè)置)。

SET key value [EX seconds | PX milliseconds] NX

SET后加NX選項(xiàng),就和SETNX命令類似了,也實(shí)現(xiàn)不存在即設(shè)置的功能。此外,這個(gè)命令在執(zhí)行時(shí),可以通過(guò)EX或者PX設(shè)置鍵值對(duì)的過(guò)期時(shí)間。

二、正文

開(kāi)始之前,我們先引入一個(gè)場(chǎng)景:

假設(shè)要給某個(gè)商品舉行秒殺活動(dòng),我們事先把庫(kù)存數(shù)據(jù)100已經(jīng)存入到了redis中,我們現(xiàn)在需要來(lái)進(jìn)行庫(kù)存扣減。

如圖所示,我們假設(shè)有1000個(gè)客戶端來(lái)進(jìn)行庫(kù)存扣減操作,那我們?cè)撊绾巫觯拍鼙WC庫(kù)存扣減順序一致且不會(huì)超扣呢。

我們首先想到的就是加鎖,在進(jìn)行庫(kù)存扣減之前,我們先拿到鎖,然后進(jìn)行扣減,最后再釋放鎖。在redis中我們創(chuàng)建一個(gè)key來(lái)代表一個(gè)鎖變量,然后對(duì)應(yīng)的值來(lái)表示鎖變量的值。我們來(lái)看一下如何進(jìn)行加鎖。

假設(shè)1000個(gè)客戶端同時(shí)進(jìn)行加鎖請(qǐng)求。因?yàn)閞edis使用單線程來(lái)處理請(qǐng)求,所以redis會(huì)串行執(zhí)行他們的請(qǐng)求操作。假設(shè)redis先處理客戶端2的請(qǐng)求,讀取lock_key的值,發(fā)現(xiàn)lock_key為0,所以客戶端2就把lock_key的value設(shè)置成1,表示已經(jīng)進(jìn)行了加鎖操作。如果此時(shí)客戶端3被處理,發(fā)現(xiàn)lock_key的值已經(jīng)為1了,所以就返回加鎖失敗的信息。

當(dāng)拿到鎖的客戶端2處理完共享資源后,就要進(jìn)行釋放鎖的操作,釋放鎖很簡(jiǎn)單,就是將lock_key重新設(shè)置為0。

由于加鎖操作包含了三個(gè)操作(讀取鎖變量、判斷鎖變量的值以及把鎖變量的值設(shè)置成1),而這三個(gè)操作在執(zhí)行的過(guò)程中需要保證原子性。那怎么保證原子性呢?

我們可以使用SETNX命令來(lái)實(shí)現(xiàn)加鎖操作,SETNX命令表示key不存在時(shí)就創(chuàng)建,key存在時(shí)就不做任何賦值操作,當(dāng)加鎖時(shí)候,我們執(zhí)行

SETNX lock_key 1

對(duì)于釋放鎖操作來(lái)說(shuō),我們可以使用DEL命令來(lái)刪除鎖變量。比如客戶端2進(jìn)行加鎖,執(zhí)行SETNX lock_key 1,如果lock_key不存在,則會(huì)創(chuàng)建lock_key,返回加鎖成功,此時(shí)客戶端2可以進(jìn)行共享資源的訪問(wèn)。如果這時(shí)客戶端1來(lái)發(fā)起請(qǐng)求加鎖操作,而此時(shí)lock_key已經(jīng)存在,SETNX lock_key 1不做任何賦值操作操作,返回加鎖失敗,所以客戶端1加鎖失敗。當(dāng)客戶端2執(zhí)行完共享資源訪問(wèn)后,執(zhí)行DEL命令來(lái)釋放鎖。此時(shí)當(dāng)有其它客戶端再來(lái)訪問(wèn)時(shí),lock_key已經(jīng)不存在了,就可以進(jìn)行正常的加鎖操作了。所以,我們可以使用SETNX和DEL命令組合來(lái)進(jìn)行加鎖和釋放鎖的操作。

不過(guò)這里有兩個(gè)問(wèn)題:

1.當(dāng)某個(gè)客戶端執(zhí)行完SETNX命令、加鎖后,此時(shí)發(fā)生了異常,結(jié)果一直沒(méi)有執(zhí)行DEL操作命令來(lái)釋放鎖。因此,這個(gè)客戶端一直占用著這個(gè)鎖,其它客戶端無(wú)法拿到鎖。

解決這個(gè)問(wèn)題,一個(gè)有效的方法就是,給鎖變量設(shè)置一個(gè)過(guò)期時(shí)間。這樣一來(lái),即使持有鎖的客戶端發(fā)生了異常,無(wú)法主動(dòng)的釋放鎖,Redis也會(huì)根據(jù)鎖變量的過(guò)期時(shí)間把它刪除。其它客戶端在鎖變量過(guò)期后,就可以重新進(jìn)行加鎖操作了。

2.如果客戶端1執(zhí)行了SETNX命令加鎖后。如果此時(shí)客戶端2執(zhí)行DEL命令刪除鎖,這時(shí),客戶端A的鎖就被誤釋放了。這是我們不能接受的。

為了解決這個(gè)問(wèn)題,我們需要能區(qū)分來(lái)自不同客戶端的鎖操作。我們?cè)撊绾巫瞿兀课覀兛梢越o每個(gè)客戶端生成一個(gè)唯一值,在進(jìn)行加鎖時(shí),我們把鎖變量賦值成這個(gè)唯一值。這樣在釋放鎖的時(shí)候,客戶端需要判斷,當(dāng)前鎖變量的值是否和自己的唯一標(biāo)識(shí)相等,在相等的情況下,才能釋放鎖。

下面來(lái)看一下如何在Redis中進(jìn)行實(shí)現(xiàn)。我們可以使用SET加EX/PX和NX選項(xiàng),來(lái)進(jìn)行加鎖操作。

SET lock_key uuid NX PX 100

 其中l(wèi)ock_key是鎖變量,uuid表示客戶端的唯一標(biāo)識(shí),PX 100表示100ms過(guò)期。由于我們?cè)卺尫沛i時(shí)需要對(duì)比客戶端的標(biāo)識(shí)和鎖變量的值是否一致,這包含了多個(gè)操作,為了保證原子性,我們需要使用lua腳本,下面是lua腳本的實(shí)現(xiàn)。

if redis.call("get",KEYS[1]) == ARGV[1] then  
   return redis.call("del",KEYS[1])
else 
   return 0
end

其中KEY[1]表示lock_key,ARGV[1]表示當(dāng)前客戶端的唯一標(biāo)識(shí),這兩個(gè)值是我們?cè)趫?zhí)行l(wèi)ua腳本時(shí)作為參數(shù)傳入的。下面我們來(lái)看一下完整的代碼實(shí)現(xiàn)。

import redis
import traceback
import uuid
import time
 
class Inventory(object):
    def __init__(self):
        pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True)
        client = redis.StrictRedis(connection_pool=pool, max_connections=20)
        self.client=client
        self.uuid=str(uuid.uuid1())
        print(self.uuid)
        self.key="lock_key"
        self.inventory_key="inventory"
    def unlock(self):
        unlock_script="" \

                      "if redis.call(\"get\",KEYS[1]) == ARGV[1] then" \

                      "   return redis.call(\"del\",KEYS[1])" \

                      "else" \

                      "   return 0 " \

                      "end"
        try:
            unlock_cmd=self.client.register_script(unlock_script)
            result=unlock_cmd(keys=[self.key],args=[self.uuid])
            if result==1:
                print("釋放成功")
            else:
                print("釋放出錯(cuò)")
        except:
            print(traceback.format_exc())
 
    def lock(self):
        try:
          while True:
             result=self.client.set(self.key,self.uuid,px=100,nx=True)
             print(result)
             if result==1:
                 break
 
             print("sleep 1s")
             time.sleep(1)
          print("加鎖成功")
          return True
        except:
          print(traceback.format_exc())
    def inventory(self):
        if self.lock():
           print("庫(kù)存扣減")
           self.client.decr(self.inventory_key)
           print("扣減完成")
           self.unlock()
 
 
inv=Inventory()
inv.inventory()

到此,我們就把Redis實(shí)現(xiàn)分布式鎖就聊完了。既然都讀到了這里,不妨給個(gè)「三連」吧,你的三連就是我最大的動(dòng)力。

到此這篇關(guān)于Redis如何實(shí)現(xiàn)分布式鎖的文章就介紹到這了,更多相關(guān)Redis 分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Redis實(shí)現(xiàn)分布式鎖的幾種方法總結(jié)
  • 詳解Java如何實(shí)現(xiàn)基于Redis的分布式鎖
  • 淺談Redis分布式鎖的正確實(shí)現(xiàn)方式
  • Redis分布式鎖實(shí)現(xiàn)方式及超時(shí)問(wèn)題解決
  • Redis上實(shí)現(xiàn)分布式鎖以提高性能的方案研究
  • Java Redis分布式鎖的正確實(shí)現(xiàn)方式詳解
  • 基于redis分布式鎖實(shí)現(xiàn)秒殺功能

標(biāo)簽:江蘇 大慶 北京 楊凌 果洛 吉安 臺(tái)州 朝陽(yáng)

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Redis如何實(shí)現(xiàn)分布式鎖》,本文關(guān)鍵詞  Redis,如何,實(shí)現(xiàn),分布式,;如發(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)文章
  • 下面列出與本文章《Redis如何實(shí)現(xiàn)分布式鎖》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Redis如何實(shí)現(xiàn)分布式鎖的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    欧美色电影在线| 国产精品免费视频一区| 欧美xingq一区二区| 国产精品免费aⅴ片在线观看| 亚洲一区二区三区四区的| 久久成人久久爱| 99国产精品国产精品久久| 91精品国产麻豆| 国产精品久久久久国产精品日日| 久久精品国产成人一区二区三区| 成人中文字幕电影| 91精品国产福利| 亚洲老妇xxxxxx| 国产成人精品免费看| 在线综合亚洲欧美在线视频| 亚洲欧美一区二区视频| 国产成人在线视频网址| 日韩一区二区免费视频| 亚洲女人****多毛耸耸8| 国产美女一区二区三区| 8v天堂国产在线一区二区| 亚洲人成精品久久久久久| 亚洲综合无码一区二区| av在线不卡免费看| 久久久久国产精品麻豆ai换脸| 欧美国产日韩a欧美在线观看| 久久精品国产秦先生| 在线不卡一区二区| 午夜精品免费在线| 一本一道综合狠狠老| 日韩一区在线播放| 9色porny自拍视频一区二区| 国产亚洲精品aa| 国产盗摄视频一区二区三区| 久久久久久综合| 国产剧情一区二区三区| 久久久久久久久免费| 国产一区在线看| 久久久精品欧美丰满| 久久精品免费观看| 日韩免费一区二区三区在线播放| 麻豆精品视频在线观看| 日韩一区二区视频| 蜜桃视频在线观看一区| 日韩免费看网站| 国产一区二区在线观看视频| 亚洲精品一区二区三区福利| 国产九色精品成人porny | 欧美日韩一区小说| 亚洲免费观看高清在线观看| 99精品国产91久久久久久| 国产精品久久久久影视| 一本色道久久综合狠狠躁的推荐| 综合精品久久久| 在线欧美小视频| 亚洲成av人片www| 日韩免费视频线观看| 国产乱码精品一区二区三区忘忧草| 欧美激情一区二区三区四区| 色综合视频在线观看| 亚洲高清在线精品| 91精品欧美久久久久久动漫| 久久激情五月激情| 中文字幕欧美日本乱码一线二线| av电影天堂一区二区在线观看| 亚洲视频1区2区| 欧美精品亚洲一区二区在线播放| 蜜桃精品视频在线观看| 国产精品三级久久久久三级| 在线观看一区二区精品视频| 麻豆一区二区三| 国产精品色呦呦| 欧美日韩激情一区二区| 国产麻豆精品theporn| 亚洲精品日日夜夜| 精品对白一区国产伦| 一本大道av伊人久久综合| 天天操天天干天天综合网| 久久久久久久久伊人| 91福利在线看| 狠狠色伊人亚洲综合成人| 亚洲欧洲av另类| 91精品国产高清一区二区三区| 国产成人99久久亚洲综合精品| 亚洲一区在线观看网站| 精品福利一区二区三区 | 欧美在线免费观看亚洲| 久久成人av少妇免费| 亚洲美女少妇撒尿| 久久久精品tv| 欧美日韩国产色站一区二区三区| 国内精品伊人久久久久av影院 | 久久久久久久久久久久电影| 一本大道久久精品懂色aⅴ| 精品一区二区三区日韩| 亚洲综合在线观看视频| 国产网站一区二区三区| 欧美日韩在线一区二区| 99久久久国产精品| 国产一区欧美日韩| 午夜精品久久久久久久久久| 国产精品亲子伦对白| 日韩你懂的在线观看| 欧美人与禽zozo性伦| 一本一道久久a久久精品 | www.亚洲激情.com| 久久国产福利国产秒拍| 亚洲成a人片在线不卡一二三区| 中文字幕一区视频| 久久精品视频免费观看| 91精品国产综合久久福利| 欧美中文字幕一二三区视频| 成人av动漫网站| 懂色av一区二区夜夜嗨| 国产美女精品一区二区三区| 久久综合综合久久综合| 日韩成人午夜精品| 香蕉久久一区二区不卡无毒影院| 亚洲丝袜自拍清纯另类| 中文字幕免费观看一区| 久久久久久久久久美女| 国产色婷婷亚洲99精品小说| ww久久中文字幕| 精品美女一区二区| 精品国产一区二区国模嫣然| 欧美大白屁股肥臀xxxxxx| 69p69国产精品| 欧美精品乱人伦久久久久久| 欧美精品丝袜中出| 678五月天丁香亚洲综合网| 欧美日韩精品三区| 欧美老肥妇做.爰bbww| 在线观看日韩毛片| 欧美日韩午夜精品| 69堂成人精品免费视频| 91精品国产黑色紧身裤美女| 日韩午夜在线观看| 精品精品欲导航| 久久久久99精品国产片| 亚洲国产精华液网站w| 日韩美女视频一区| 亚洲综合在线视频| 人人爽香蕉精品| 国产剧情在线观看一区二区| 成人激情小说乱人伦| 91免费视频网址| 精品视频资源站| 欧美一级久久久久久久大片| 精品国产不卡一区二区三区| 亚洲国产精品成人综合| 一区二区三区在线免费视频| 亚洲成人av一区| 国模大尺度一区二区三区| 成人精品免费网站| 欧美中文字幕一区二区三区亚洲| 91麻豆精品国产| 国产视频一区二区三区在线观看 | 亚洲免费电影在线| 日韩av不卡在线观看| 国产在线视视频有精品| 93久久精品日日躁夜夜躁欧美| 欧美影视一区在线| 精品成人一区二区三区四区| 国产精品久久久爽爽爽麻豆色哟哟| 亚洲最新在线观看| 国产一区二区在线看| 日本精品一区二区三区四区的功能| 欧美高清视频一二三区| 欧美高清在线一区二区| 亚洲国产成人av网| 国产传媒欧美日韩成人| 欧美视频一区二区在线观看| 精品99999| 亚洲一区成人在线| 成熟亚洲日本毛茸茸凸凹| 欧美美女网站色| 国产片一区二区三区| 天堂久久久久va久久久久| 丁香婷婷综合激情五月色| 777亚洲妇女| 亚洲欧美日韩一区二区 | 国产成人综合在线观看| 欧美性生活影院| 久久久久青草大香线综合精品| 亚洲福中文字幕伊人影院| 成人免费看片app下载| 欧美一区二区免费观在线| 中文字幕一区二区三区在线观看 | 五月天一区二区| k8久久久一区二区三区| 日韩女优av电影在线观看| 亚洲一区二区精品3399| a级高清视频欧美日韩| 久久婷婷久久一区二区三区| 午夜日韩在线电影| 欧洲精品一区二区三区在线观看| 欧美国产激情一区二区三区蜜月| 久久不见久久见中文字幕免费| 欧美日韩一区二区三区不卡| 亚洲欧美另类小说|