亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

Redis上實現分布式鎖以提高性能的方案研究

2020-03-17 12:41:26
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Redis上實現分布式鎖以提高性能的方案研究,其中重點需要理解異步算法與鎖的自動釋放,需要的朋友可以參考下
 

背景:

在很多互聯網產品應用中,有些場景需要加鎖處理,比如:秒殺,全局遞增ID,樓層生成等等。大部分是解決方案基于DB實現的,Redis為單進程單線程模式,采用隊列模式將并發訪問變成串行訪問,且多客戶端對Redis的連接并不存在競爭關系。

 

項目實踐

任務隊列用到分布式鎖的情況比較多,在將業務邏輯中可以異步處理的操作放入隊列,在其他線程中處理后出隊,此時隊列中使用了分布式鎖,保證入隊和出隊的一致性。關于redis隊列這塊的邏輯分析,我將在下一次對其進行總結,此處先略過。


接下來對redis實現的分布式鎖的邏輯代碼進行詳細的分析和理解:

1、為避免特殊原因導致鎖無法釋放, 在加鎖成功后, 鎖會被賦予一個生存時間(通過 lock 方法的參數設置或者使用默認值), 超出生存時間鎖將被自動釋放.

2、鎖的生存時間默認比較短(秒級, 具體見 lock 方法), 因此若需要長時間加鎖, 可以通過 expire 方法延長鎖的生存時間為適當的時間. 比如在循環內調用 expire
3、系統級的鎖當進程無論因為任何原因出現crash,操作系統會自己回收鎖,所以不會出現資源丟失。
4、但分布式鎖不同。若一次性設置很長的時間,一旦由于各種原因進程 crash 或其他異常導致 unlock 未被調用,則該鎖在剩下的時間就變成了垃圾鎖,導致其他進程或進程重啟后無法進入加鎖區域。

 

<?php require_once 'RedisFactory.php'; /*** 在 Redis 上實現的分布式鎖*/class RedisLock {  //單例模式  private static $_instance = null;  public static function instance() {    if(self::$_instance == null) {      self::$_instance = new RedisLock();    }    return self::$_instance;  }   //redis對象變量  private $redis;  //存放被鎖的標志名的數組  private $lockedNames = array();   public function __construct() {    //獲取一個 RedisString 實例    $this->redis = RedisFactory::instance()->getString();  }   /**   * 加鎖  *  * @param string 鎖的標識名  * @param int 獲取鎖失敗時的等待超時時間(秒), 在此時間之內會一直嘗試獲取鎖直到超時. 為 0 表示失敗后直接返回不等待  * @param int 當前鎖的最大生存時間(秒), 必須大于 0 . 如果超過生存時間后鎖仍未被釋放, 則系統會自動將其強制釋放  * @param int 獲取鎖失敗后掛起再試的時間間隔(微秒)  */  public function lock($name, $timeout = 0, $expire = 15, $waitIntervalUs = 100000) {    if(empty($name)) return false;     $timeout = (int)$timeout;    $expire = max((int)$expire, 5);    $now = microtime(true);    $timeoutAt = $now + $timeout;    $expireAt = $now + $expire;     $redisKey = "Lock:$name";    while(true) {      $result = $this->redis->setnx($redisKey, (string)$expireAt);      if($result !== false) {        //對$redisKey設置生存時間        $this->redis->expire($redisKey, $expire);        //將最大生存時刻記錄在一個數組里面        $this->lockedNames[$name] = $expireAt;        return true;      }       //以秒為單位,返回$redisKey 的剩余生存時間      $ttl = $this->redis->ttl($redisKey);      // TTL 小于 0 表示 key 上沒有設置生存時間(key 不會不存在, 因為前面 setnx 會自動創建)      // 如果出現這種情況, 那就是進程在某個實例 setnx 成功后 crash 導致緊跟著的 expire 沒有被調用. 這時可以直接設置 expire 并把鎖納為己用      if($ttl < 0) {        $this->redis->set($redisKey, (string)$expireAt, $expire);        $this->lockedNames[$name] = $expireAt;        return true;      }       // 設置了不等待或者已超時      if($timeout <= 0 || microtime(true) > $timeoutAt) break;       // 掛起一段時間再試      usleep($waitIntervalUs);    }     return false;  }   /**  * 給當前鎖增加指定的生存時間(秒), 必須大于 0  *  * @param string 鎖的標識名  * @param int 生存時間(秒), 必須大于 0  */  public function expire($name, $expire) {    if($this->isLocking($name)) {      if($this->redis->expire("Lock:$name", max($expire, 1))) {        return true;      }    }    return false;  }   /**  * 判斷當前是否擁有指定名稱的鎖  *  * @param mixed $name  */  public function isLocking($name) {    if(isset($this->lockedNames[$name])) {      return (string)$this->lockedNames[$name] == (string)$this->redis->get("Lock:$name");    }    return false;  }   /**  * 釋放鎖  *  * @param string 鎖的標識名  */  public function unlock($name) {    if($this->isLocking($name)) {      if($this->redis->deleteKey("Lock:$name")) {        unset($this->lockedNames[$name]);        return true;      }    }    return false;  }   /** 釋放當前已經獲取到的所有鎖 */  public function unlockAll() {    $allSuccess = true;    foreach($this->lockedNames as $name => $item) {      if(false === $this->unlock($name)) {        $allSuccess = false;      }    }    return $allSuccess;  }}

此類很多代碼都寫上了注釋,只要認真理解下,就很容易懂得如何在redis實現分布式鎖了。



注:相關教程知識閱讀請移步到Redis頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
综合久久五月天| 日韩一区二区久久久| 91视频免费网站| 久久久亚洲影院| 亚洲女在线观看| 国产精品久久激情| 538国产精品一区二区免费视频| 久久免费高清视频| 国产日本欧美一区| 亚洲视频欧洲视频| 美日韩精品免费视频| 国产精品福利在线观看| 欧美精品福利视频| 亚洲成人久久久| 亚洲午夜激情免费视频| 在线精品高清中文字幕| 91av在线视频观看| 亚洲一区二区三区成人在线视频精品| 97碰在线观看| 亚洲综合色激情五月| 日本精品一区二区三区在线播放视频| 尤物九九久久国产精品的特点| 宅男66日本亚洲欧美视频| 欧美激情高清视频| 日韩中文字幕在线观看| 国产精品一区二区3区| 欧美俄罗斯性视频| 九九热精品视频| 色无极亚洲影院| 成人精品一区二区三区电影免费| 国产美女搞久久| 国产精品都在这里| 成人午夜在线视频一区| 欧美激情日韩图片| 久久久久久久国产精品视频| 欧美亚洲另类制服自拍| 久久久www成人免费精品张筱雨| 欧美一二三视频| 一本久久综合亚洲鲁鲁| 91精品国产高清久久久久久91| 成人福利网站在线观看| 狠狠做深爱婷婷久久综合一区| 亚洲男人天堂2023| 国产精品视频网| 在线观看久久av| 97超级碰在线看视频免费在线看| 久久精品美女视频网站| 亚洲精品丝袜日韩| 国产精品偷伦视频免费观看国产| 亚洲精品短视频| 中文字幕在线看视频国产欧美| 国产91精品高潮白浆喷水| 亚洲人午夜精品| 日韩禁在线播放| 美女国内精品自产拍在线播放| 国产精品免费久久久| 欧美性生活大片免费观看网址| 国产成人在线一区| 午夜精品在线视频| 国产不卡一区二区在线播放| 成人免费看黄网站| 久久天天躁狠狠躁夜夜躁| 欧美丝袜美女中出在线| 国产美女扒开尿口久久久| 日本成人黄色片| 欧美精品一本久久男人的天堂| 亚洲一区二区三区sesese| 久久97久久97精品免视看| 成人黄色短视频在线观看| 亚洲精品一区av在线播放| 97超级碰在线看视频免费在线看| 久久国产精品久久国产精品| 欧美性生活大片免费观看网址| 成人免费在线视频网址| 夜夜嗨av一区二区三区四区| 国产裸体写真av一区二区| 欧美孕妇性xx| 亚洲成av人片在线观看香蕉| 国产玖玖精品视频| 日韩精品在线第一页| 欧美日韩高清在线观看| 日韩精品中文字幕在线播放| 日韩美女视频免费在线观看| 97香蕉超级碰碰久久免费的优势| 久久99精品久久久久久青青91| 欧美人与物videos| 91夜夜揉人人捏人人添红杏| 欧美成人国产va精品日本一级| 亚洲国产私拍精品国模在线观看| 富二代精品短视频| 欧美日韩国产黄| 午夜精品久久久久久99热| 综合国产在线视频| 亚洲成人激情在线| 久久精品国产免费观看| 欧美日韩中文在线观看| 亚洲成人999| 国产极品jizzhd欧美| 亚洲r级在线观看| 国产精品2018| 欧美野外猛男的大粗鳮| 国产91精品久久久| 91精品综合久久久久久五月天| 日产日韩在线亚洲欧美| 黑人欧美xxxx| 国产精品91一区| 成人免费黄色网| 欧美日本精品在线| 日韩一二三在线视频播| 欧美在线免费观看| 2019中文字幕免费视频| 精品日韩中文字幕| 91久久中文字幕| 国产主播在线一区| 亚洲成人久久网| 欧美精品18videos性欧美| 欧美亚洲国产成人精品| 国产精品一区二区三区久久| 性欧美xxxx视频在线观看| 日韩av中文字幕在线免费观看| 欧美日韩国产在线| 色综合天天狠天天透天天伊人| 国外色69视频在线观看| 一区二区三区天堂av| 亚洲精品videossex少妇| 中文字幕在线精品| 日韩av大片免费看| 欧美片一区二区三区| 欧美日韩国产中字| 日本中文字幕久久看| 亚洲人成网站999久久久综合| 亚洲精品自拍第一页| 欧美一级大片视频| 精品国产拍在线观看| 国产一区二区三区高清在线观看| 午夜精品一区二区三区av| 亚洲xxxx妇黄裸体| 久久久久中文字幕2018| 91亚洲精品久久久| 亚洲免费高清视频| 国产精品第七影院| 国产成人免费av电影| 国产精品美女免费| 狠狠躁夜夜躁人人爽天天天天97| 国产一区二区三区日韩欧美| 伊人av综合网| 日韩精品视频免费专区在线播放| 欧美肥婆姓交大片| 国产一区二区香蕉| 亚洲色图17p| 亚洲精品v欧美精品v日韩精品| 久久精品美女视频网站| 亚洲成年网站在线观看| 欧亚精品中文字幕| 国产精品视频精品视频| 九九精品在线观看| 国产999精品久久久影片官网| 欧美日韩美女在线观看| 欧美黄色免费网站| 亚洲色图校园春色| 少妇高潮久久久久久潘金莲| 亚洲国产中文字幕在线观看| 日韩精品免费观看| 午夜精品在线观看|