亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

redis實(shí)現(xiàn)加鎖的幾種方法示例詳解

 更新時(shí)間:2017年09月24日 09:18:13   作者:Dennis  
這篇文章主要給大家介紹了關(guān)于redis實(shí)現(xiàn)加鎖的幾種方法,加鎖命令分別是INCR、SETNX和SET,文中給出了詳細(xì)的示例代碼,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

本文主要給大家介紹了關(guān)于redis實(shí)現(xiàn)加鎖的幾種方法,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。

1. redis加鎖分類

redis能用的的加鎖命令分表是INCR、SETNX、SET

2. 第一種鎖命令I(lǐng)NCR

這種加鎖的思路是, key 不存在,那么 key 的值會先被初始化為 0 ,然后再執(zhí)行 INCR 操作進(jìn)行加一。
然后其它用戶在執(zhí)行 INCR 操作進(jìn)行加一時(shí),如果返回的數(shù)大于 1 ,說明這個(gè)鎖正在被使用當(dāng)中。

    1、 客戶端A請求服務(wù)器獲取key的值為1表示獲取了鎖 

    2、 客戶端B也去請求服務(wù)器獲取key的值為2表示獲取鎖失敗

    3、 客戶端A執(zhí)行代碼完成,刪除鎖

    4、 客戶端B在等待一段時(shí)間后在去請求的時(shí)候獲取key的值為1表示獲取鎖成功

    5、 客戶端B執(zhí)行代碼完成,刪除鎖

 $redis->incr($key);
 $redis->expire($key, $ttl); //設(shè)置生成時(shí)間為1秒

3. 第二種鎖SETNX

這種加鎖的思路是,如果 key 不存在,將 key 設(shè)置為 value

如果 key 已存在,則 SETNX 不做任何動(dòng)作

    1、 客戶端A請求服務(wù)器設(shè)置key的值,如果設(shè)置成功就表示加鎖成功

    2、 客戶端B也去請求服務(wù)器設(shè)置key的值,如果返回失敗,那么就代表加鎖失敗

    3、 客戶端A執(zhí)行代碼完成,刪除鎖

    4、 客戶端B在等待一段時(shí)間后在去請求設(shè)置key的值,設(shè)置成功

    5、 客戶端B執(zhí)行代碼完成,刪除鎖   

  $redis->setNX($key, $value);
  $redis->expire($key, $ttl);

4. 第三種鎖SET

上面兩種方法都有一個(gè)問題,會發(fā)現(xiàn),都需要設(shè)置 key 過期。那么為什么要設(shè)置key過期呢?如果請求執(zhí)行因?yàn)槟承┰蛞馔馔顺隽耍瑢?dǎo)致創(chuàng)建了鎖但是沒有刪除鎖,那么這個(gè)鎖將一直存在,以至于以后緩存再也得不到更新。于是乎我們需要給鎖加一個(gè)過期時(shí)間以防不測。

但是借助 Expire 來設(shè)置就不是原子性操作了。所以還可以通過事務(wù)來確保原子性,但是還是有些問題,所以官方就引用了另外一個(gè),使用 SET 命令本身已經(jīng)從版本 2.6.12 開始包含了設(shè)置過期時(shí)間的功能。

    1、 客戶端A請求服務(wù)器設(shè)置key的值,如果設(shè)置成功就表示加鎖成功

    2、 客戶端B也去請求服務(wù)器設(shè)置key的值,如果返回失敗,那么就代表加鎖失敗

    3、 客戶端A執(zhí)行代碼完成,刪除鎖

    4、 客戶端B在等待一段時(shí)間后在去請求設(shè)置key的值,設(shè)置成功

    5、 客戶端B執(zhí)行代碼完成,刪除鎖

  $redis->set($key, $value, array('nx', 'ex' => $ttl)); //ex表示秒

5. 其它問題

雖然上面一步已經(jīng)滿足了我們的需求,但是還是要考慮其它問題?

    1、 redis發(fā)現(xiàn)鎖失敗了要怎么辦?中斷請求還是循環(huán)請求?

    2、 循環(huán)請求的話,如果有一個(gè)獲取了鎖,其它的在去獲取鎖的時(shí)候,是不是容易發(fā)生搶鎖的可能?

    3、 鎖提前過期后,客戶端A還沒執(zhí)行完,然后客戶端B獲取到了鎖,這時(shí)候客戶端A執(zhí)行完了,會不會在刪鎖的時(shí)候把B的鎖給刪掉?

6. 解決辦法

針對問題1:使用循環(huán)請求,循環(huán)請求去獲取鎖

針對問題2:針對第二個(gè)問題,在循環(huán)請求獲取鎖的時(shí)候,加入睡眠功能,等待幾毫秒在執(zhí)行循環(huán)

針對問題3:在加鎖的時(shí)候存入的key是隨機(jī)的。這樣的話,每次在刪除key的時(shí)候判斷下存入的key里的value和自己存的是否一樣

    do { //針對問題1,使用循環(huán)
      $timeout = 10;
      $roomid = 10001;
      $key = 'room_lock';
      $value = 'room_'.$roomid; //分配一個(gè)隨機(jī)的值針對問題3
      $isLock = Redis::set($key, $value, 'ex', $timeout, 'nx');//ex 秒
      if ($isLock) {
        if (Redis::get($key) == $value) { //防止提前過期,誤刪其它請求創(chuàng)建的鎖
          //執(zhí)行內(nèi)部代碼
          Redis::del($key);
          continue;//執(zhí)行成功刪除key并跳出循環(huán)
        }
      } else {
        usleep(5000); //睡眠,降低搶鎖頻率,緩解redis壓力,針對問題2
      }
    } while(!$isLock);

7. 另外一個(gè)鎖

以上的鎖完全滿足了需求,但是官方另外還提供了一套加鎖的算法,這里以PHP為例

  $servers = [
    ['127.0.0.1', 6379, 0.01],
    ['127.0.0.1', 6389, 0.01],
    ['127.0.0.1', 6399, 0.01],
  ];
  
  $redLock = new RedLock($servers);
  
  //加鎖
  $lock = $redLock->lock('my_resource_name', 1000);
  
  //刪除鎖
  $redLock->unlock($lock)

上面是官方提供的一個(gè)加鎖方法,就是和第6的大體方法一樣,只不過官方寫的更健壯。所以可以直接使用官方提供寫好的類方法進(jìn)行調(diào)用。官方提供了各種語言如何實(shí)現(xiàn)鎖。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Redis實(shí)戰(zhàn)之商城購物車功能的實(shí)現(xiàn)代碼

    Redis實(shí)戰(zhàn)之商城購物車功能的實(shí)現(xiàn)代碼

    這篇文章主要介紹了Redis實(shí)戰(zhàn)之商城購物車功能的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02
  • Redis中的bitmap詳解

    Redis中的bitmap詳解

    BitMap是通過一個(gè)bit位來表示某個(gè)元素對應(yīng)的值或者狀態(tài),其中的key就是對應(yīng)元素本身。我們知道8個(gè)bit可以組成一個(gè)Byte,所以bitmap本身會極大的節(jié)省儲存空間,下面通過本文給大家介紹Redis中的bitmap知識,感興趣的朋友一起看看吧
    2021-10-10
  • redis與memcached的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    redis與memcached的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Memcached是以LiveJurnal旗下Danga Interactive公司的Bard Fitzpatric為首開發(fā)的高性能分布式內(nèi)存緩存服務(wù)器。那么redis與memcached有什么區(qū)別呢?下面小編給大家介紹下redis與memcached的區(qū)別,感興趣的朋友參考下吧
    2017-08-08
  • redis簡單介紹及安裝使用小結(jié)

    redis簡單介紹及安裝使用小結(jié)

    本文主要是對于redis初步學(xué)習(xí)的小結(jié)內(nèi)容,包括了redis介紹,redis安裝以及最簡單的使用,希望大家能夠喜歡
    2018-11-11
  • redis.clients.jedis.exceptions.JedisBusyException無法處理異常的解決方法

    redis.clients.jedis.exceptions.JedisBusyException無法處理異常的解決方法

    redis.clients.jedis.exceptions.JedisBusyException異常通常不是 Jedis客戶端直接拋出的標(biāo)準(zhǔn)異常,本文就來介紹一下異常的解決方法,感興趣的可以了解一下
    2024-05-05
  • Redis 緩存實(shí)現(xiàn)存儲和讀取歷史搜索關(guān)鍵字的操作方法

    Redis 緩存實(shí)現(xiàn)存儲和讀取歷史搜索關(guān)鍵字的操作方法

    這篇文章主要介紹了Redis 緩存實(shí)現(xiàn)存儲和讀取歷史搜索關(guān)鍵字,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • 淺談redis緩存在項(xiàng)目中的使用

    淺談redis緩存在項(xiàng)目中的使用

    最近由于項(xiàng)目需要,在系統(tǒng)緩存服務(wù)部分上用到了redis,本文就淺談下在redis緩存在項(xiàng)目中的使用,感興趣的小伙伴們可以參考一下
    2021-05-05
  • redis禁止幾個(gè)危險(xiǎn)命令的方法

    redis禁止幾個(gè)危險(xiǎn)命令的方法

    今天小編就為大家分享一篇redis禁止幾個(gè)危險(xiǎn)命令的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Govern Service 基于 Redis 的服務(wù)治理平臺安裝過程詳解

    Govern Service 基于 Redis 的服務(wù)治理平臺安裝過程詳解

    Govern Service 是一個(gè)輕量級、低成本的服務(wù)注冊、服務(wù)發(fā)現(xiàn)、 配置服務(wù) SDK,通過使用現(xiàn)有基礎(chǔ)設(shè)施中的 Redis 不用給運(yùn)維部署帶來額外的成本與負(fù)擔(dān),接下來通過本文給大家分享Govern Service 基于 Redis 的服務(wù)治理平臺的相關(guān)知識,感興趣的朋友一起看看吧
    2021-05-05
  • 在ssm項(xiàng)目中使用redis緩存查詢數(shù)據(jù)的方法

    在ssm項(xiàng)目中使用redis緩存查詢數(shù)據(jù)的方法

    本文主要簡單的使用Java代碼進(jìn)行redis緩存,即在查詢的時(shí)候先在service層從redis緩存中獲取數(shù)據(jù)。如果大家對在ssm項(xiàng)目中使用redis緩存查詢數(shù)據(jù)的相關(guān)知識感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-03-03

最新評論