您好,登錄后才能下訂單哦!
這篇文章主要講解了“redis分布式鎖的實現原理是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“redis分布式鎖的實現原理是什么”吧!
借助于redis中的命令setnx(key, value),key不存在就新增,存在就什么都不做。同時有多個客戶端發送setnx命令,只有一個客戶端可以成功,返回1(true);其他的客戶端返回0(false)。
本教程操作環境:windows7系統、Redis5.0.10版、DELL G3電腦。
分布式鎖的實現
隨著業務發展的需要,原單體單機部署的系統被演化成分布式集群系統后,由于分布式系統多線程、多進程并且分布在不同機器上,這將使原單機部署情況下的并發控制鎖策略失效,單純的Java API并不能提供分布式鎖的能力。為了解決這個問題就需要一種跨JVM的互斥機制來控制共享資源的訪問,這就是分布式鎖要解決的問題!
分布式鎖主流的實現方案:
基于數據庫實現分布式鎖
基于緩存(Redis等)
基于Zookeeper
這里,我們就基于redis實現分布式鎖。
基本實現
借助于redis中的命令setnx(key, value),key不存在就新增,存在就什么都不做。同時有多個客戶端發送setnx命令,只有一個客戶端可以成功,返回1(true);其他的客戶端返回0(false)。
主要使用Redis Setnx 命令
在指定的 key 不存在時,為 key 設置指定的值
設置成功,返回 1 。 設置失敗,返回 0
redis> EXISTS job # job 不存在 (integer) 0 redis> SETNX job "programmer" # job 設置成功 (integer) 1 redis> SETNX job "code-farmer" # 嘗試覆蓋 job ,失敗 (integer) 0 redis> GET job # 沒有被覆蓋 "programmer"
java代碼
public void testLock() { // 執行redis的setnx命令 String uuid = UUID.randomUUID().toString(); Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 5, TimeUnit.SECONDS); // 判斷是否拿到鎖 if (lock) { // 執行業務邏輯代碼 // ... // 釋放鎖資源 (保證獲取值和刪除操作的原子性) LUA腳本保證刪除的原子性 String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; this.redisTemplate.execute(new DefaultRedisScript<>(script), Arrays.asList("lock"), Arrays.asList(uuid)); // if (StrUtil.equals(uuid,redisTemplate.opsForValue().get("lock"))){ // redisTemplate.delete("lock"); // } } else { // 其他請求嘗試獲取鎖 testLock(); } }
為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件:
互斥性。在任意時刻,只有一個客戶端能持有鎖。
不會發生死鎖。即使有一個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保證后續其他客戶端能加鎖。
解鈴還須系鈴人。加鎖和解鎖必須是同一個客戶端,客戶端自己不能把別人加的鎖給解了。
感謝各位的閱讀,以上就是“redis分布式鎖的實現原理是什么”的內容了,經過本文的學習后,相信大家對redis分布式鎖的實現原理是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。