成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

【大廠面試題】Redis中是如何實現分布式鎖的?

開發 后端 分布式 Redis
你對Redis使用熟悉嗎?Redis中是如何實現分布式鎖的。下面讓我們來看一下吧。

 分布式鎖常見的三種實現方式:

  1.  數據庫樂觀鎖;
  2.  基于Redis的分布式鎖;
  3.  基于ZooKeeper的分布式鎖。

本地面試考點是,你對Redis使用熟悉嗎?Redis中是如何實現分布式鎖的。

要點

Redis要實現分布式鎖,以下條件應該得到滿足

互斥性

  •  在任意時刻,只有一個客戶端能持有鎖。

不能死鎖

  •  客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保證后續其他客戶端能加鎖。

容錯性

  •  只要大部分的Redis節點正常運行,客戶端就可以加鎖和解鎖。

實現

可以直接通過 set key value px milliseconds nx 命令實現加鎖, 通過Lua腳本實現解鎖。 

  1. //獲取鎖(unique_value可以是UUID等)  
  2. SET resource_name unique_value NX PX  30000  
  3. //釋放鎖(lua腳本中,一定要比較value,防止誤解鎖)  
  4. if redis.call("get",KEYS[1]) == ARGV[1] then  
  5.     return redis.call("del",KEYS[1]) 
  6.  else  
  7.     return 0  
  8. end 

代碼解釋

  •  set 命令要用 set key value px milliseconds nx,替代 setnx + expire 需要分兩次執行命令的方式,保證了原子性,
  •  value 要具有唯一性,可以使用UUID.randomUUID().toString()方法生成,用來標識這把鎖是屬于哪個請求加的,在解鎖的時候就可以有依據;
  •  釋放鎖時要驗證 value 值,防止誤解鎖;
  •  通過 Lua 腳本來避免 Check And Set 模型的并發問題,因為在釋放鎖的時候因為涉及到多個Redis操作 (利用了eval命令執行Lua腳本的原子性);

加鎖代碼分析

首先,set()加入了NX參數,可以保證如果已有key存在,則函數不會調用成功,也就是只有一個客戶端能持有鎖,滿足互斥性。其次,由于我們對鎖設置了過期時間,即使鎖的持有者后續發生崩潰而沒有解鎖,鎖也會因為到了過期時間而自動解鎖(即key被刪除),不會發生死鎖。最后,因為我們將value賦值為requestId,用來標識這把鎖是屬于哪個請求加的,那么在客戶端在解鎖的時候就可以進行校驗是否是同一個客戶端。

解鎖代碼分析

將Lua代碼傳到jedis.eval()方法里,并使參數KEYS[1]賦值為lockKey,ARGV[1]賦值為requestId。在執行的時候,首先會獲取鎖對應的value值,檢查是否與requestId相等,如果相等則解鎖(刪除key)。

存在的風險

如果存儲鎖對應key的那個節點掛了的話,就可能存在丟失鎖的風險,導致出現多個客戶端持有鎖的情況,這樣就不能實現資源的獨享了。

  1.  客戶端A從master獲取到鎖
  2.  在master將鎖同步到slave之前,master宕掉了(Redis的主從同步通常是異步的)。

    主從切換,slave節點被晉級為master節點

      3.  客戶端B取得了同一個資源被客戶端A已經獲取到的另外一個鎖。導致存在同一時刻存不止一個線程獲取到鎖的情況。

redlock算法出現

這個場景是假設有一個 redis cluster,有 5 個 redis master 實例。然后執行如下步驟獲取一把鎖:

  1.  獲取當前時間戳,單位是毫秒;
  2.  跟上面類似,輪流嘗試在每個 master 節點上創建鎖,過期時間較短,一般就幾十毫秒;
  3.  嘗試在大多數節點上建立一個鎖,比如 5 個節點就要求是 3 個節點 n / 2 + 1;
  4.  客戶端計算建立好鎖的時間,如果建立鎖的時間小于超時時間,就算建立成功了;
  5.  要是鎖建立失敗了,那么就依次之前建立過的鎖刪除;
  6.  只要別人建立了一把分布式鎖,你就得不斷輪詢去嘗試獲取鎖。

Redis 官方給出了以上兩種基于 Redis 實現分布式鎖的方法,詳細說明可以查看:

https://redis.io/topics/distlock

Redisson實現

Redisson是一個在Redis的基礎上實現的Java駐內存數據網格(In-Memory Data Grid)。它不僅提供了一系列的分布式的Java常用對象,還實現了可重入鎖(Reentrant Lock)、公平鎖(Fair Lock、聯鎖(MultiLock)、 紅鎖(RedLock)、 讀寫鎖(ReadWriteLock)等,還提供了許多分布式服務。

Redisson提供了使用Redis的最簡單和最便捷的方法。Redisson的宗旨是促進使用者對Redis的關注分離(Separation of Concern),從而讓使用者能夠將精力更集中地放在處理業務邏輯上。

Redisson 分布式重入鎖用法

Redisson 支持單點模式、主從模式、哨兵模式、集群模式,這里以單點模式為例: 

  1. // 1.構造redisson實現分布式鎖必要的Config  
  2. Config config = new Config();  
  3. config.useSingleServer().setAddress("redis://127.0.0.1:5379").setPassword("123456").setDatabase(0);  
  4. // 2.構造RedissonClient  
  5. RedissonClient redissonClient = Redisson.create(config);  
  6. // 3.獲取鎖對象實例(無法保證是按線程的順序獲取到)  
  7. RLock rLock = redissonClient.getLock(lockKey);  
  8. try {  
  9.     /**  
  10.      * 4.嘗試獲取鎖  
  11.      * waitTimeout 嘗試獲取鎖的最大等待時間,超過這個值,則認為獲取鎖失敗  
  12.      * leaseTime   鎖的持有時間,超過這個時間鎖會自動失效(值應設置為大于業務處理的時間,確保在鎖有效期內業務能處理完)  
  13.      */ 
  14.     boolean res = rLock.tryLock((long)waitTimeout, (long)leaseTime, TimeUnit.SECONDS);  
  15.     if (res) {  
  16.         //成功獲得鎖,在這里處理業務  
  17.     }  
  18. } catch (Exception e) {  
  19.     throw new RuntimeException("aquire lock fail");  
  20. }finally{  
  21.     //無論如何, 最后都要解鎖  
  22.     rLock.unlock();  

加鎖流程圖

解鎖流程圖

我們可以看到,RedissonLock是可重入的,并且考慮了失敗重試,可以設置鎖的最大等待時間, 在實現上也做了一些優化,減少了無效的鎖申請,提升了資源的利用率。

需要特別注意的是,RedissonLock 同樣沒有解決 節點掛掉的時候,存在丟失鎖的風險的問題。而現實情況是有一些場景無法容忍的,所以 Redisson 提供了實現了redlock算法的 RedissonRedLock,RedissonRedLock 真正解決了單點失敗的問題,代價是需要額外的為 RedissonRedLock 搭建Redis環境。

所以,如果業務場景可以容忍這種小概率的錯誤,則推薦使用 RedissonLock, 如果無法容忍,則推薦使用 RedissonRedLock。 

 

責任編輯:龐桂玉 來源: 民工哥技術之路
相關推薦

2023-08-21 19:10:34

Redis分布式

2022-08-11 18:27:50

面試Redis分布式鎖

2024-10-07 10:07:31

2024-04-01 05:10:00

Redis數據庫分布式鎖

2022-01-06 10:58:07

Redis數據分布式鎖

2019-06-19 15:40:06

分布式鎖RedisJava

2024-06-13 09:34:35

JWTTokenSpring

2021-02-02 16:37:25

Redis分布式

2024-02-20 09:50:02

Redis分布式

2019-02-26 09:51:52

分布式鎖RedisZookeeper

2023-03-01 08:07:51

2024-09-24 16:30:46

分布式鎖Redis數據中間件

2022-10-27 10:44:14

分布式Zookeeper

2021-11-01 12:25:56

Redis分布式

2024-01-02 13:15:00

分布式鎖RedissonRedis

2023-10-11 09:37:54

Redis分布式系統

2024-11-28 15:11:28

2020-07-30 09:35:09

Redis分布式鎖數據庫

2020-07-15 16:50:57

Spring BootRedisJava

2019-12-25 14:35:33

分布式架構系統
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 韩国理论电影在线 | 国产原创视频 | 青青久视频 | 国产一区二区三区欧美 | 国产精品久久久久久吹潮 | 超碰在线人人 | 国产在线a | 久久国产高清 | 琪琪午夜伦伦电影福利片 | 精品在线观看一区二区 | 黄色亚洲网站 | 四虎永久免费影院 | 国产精品高潮呻吟久久aⅴ码 | 亚洲一区二区精品视频在线观看 | 99在线免费视频 | 亚洲精品成人 | 亚洲精品在线国产 | 黄色激情毛片 | 香蕉大人久久国产成人av | 99精品欧美一区二区三区 | 日韩精品一区二区三区中文在线 | 亚洲精品一区二区 | 97视频网站 | 毛片在线免费 | 一级在线毛片 | 国产精品无码永久免费888 | 亚洲区一区二区 | 久久久91精品国产一区二区三区 | 久久中文字幕一区 | 精品无码三级在线观看视频 | 日韩成人免费av | 欧美一级黑人aaaaaaa做受 | 国产精品亚洲视频 | yeyeav| a在线视频| 日韩中文字幕 | 永久免费在线观看 | 国产一区二区在线播放视频 | 久久精品视频网站 | 亚洲一区视频在线 | 久久久激情视频 |