日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis(七)分布式锁

發布時間:2025/3/8 数据库 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis(七)分布式锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面學習了Redis的數據結構以及命令、Redis中的事務和Redis對Lua腳本的支持。

這一章就對Redis這些特性做一下實戰性應用——基于Redis的分布式鎖實現。

Lock和Distributed Lock

在這之前先來認識下鎖(Lock)和分布式鎖(Distributed Lock):

In computer science, a lock or mutex (from mutual exclusion) is a synchronization mechanism for enforcing limits on access to a resource in an environment where there are many threads of execution. A lock is designed to enforce a mutual exclusion concurrency control policy.

參考wiki的解釋:在計算機科學領域中,鎖是為了限制多線程環境訪問一個資源的一種同步機制。鎖被設計相互排斥的并發策略。

Lock的前提條件:

  • 同一臺機器上的共同資源;
  • 多線程環境訪問共同資源;

Lock目標:

  • 保證多線程訪問資源的一致性;

Lock的實現:

  • 單核處理器上禁用中斷,使得同步資源能夠被訪問結束;
  • 硬件支持的原子指令,“比較和交換”等等,用于測試鎖是否是空閑,如果空閑獲取鎖;

Operating systems use lock managers to organise and serialise the access to resources. A distributed lock manager (DLM) runs in every machine in a cluster, with an identical copy of a cluster-wide lock database. In this way a DLM provides software applications which are distributed across a cluster on multiple machines with a means to synchronize their accesses to shared resources.

參考wiki解釋分布式鎖:操作系統用鎖管理器實現有組織有順序的訪問資源。分布式鎖運行在集群環境中的每臺機器上,使得數據具有相同的副本。分布式鎖提供分布式軟件應用同步訪問共享資源。

Distribute Lock的前提條件:

  • 分布式軟件應用;
  • 分布式軟件中的共享資源;

Distribute Lock目標:

  • 保證分布式應用訪問共享資源的一致性

Distribute Lock實現方式:

  • 基于Redis實現;
  • 基于Zookeeper實現;
  • 基于Etcd或者Consul實現;
  • Google開發的Chubby(Lock Service);

獨占式鎖的特點和影響

按照用途、場景劃分,鎖的類型非常多。如:排它鎖(獨占式鎖)、共享鎖,自旋鎖、互斥鎖,讀鎖、寫鎖。但是在分布式環境中的所謂的分布式鎖,大多數情況下都是指:分布式獨占式鎖。

1.特點分析:

  • 每次只能一個占用鎖;
  • 可以重復進入鎖;
  • 只有占用者才可以解鎖;
  • 獲取鎖和釋放鎖都需要原子
  • 不能產生死鎖
  • 盡量滿足性能

本質:同步互斥,使得處理任務能夠一個一個逐步的過臨界資源。

造成的影響:

  • 降低并發數,使得多任務處理,只能一個一個的進行;
  • 任務的換進換出造成切換上的開銷;

本質:使得吞吐量大打折扣。

基于Redis的實現

Redis實現分布式鎖的基礎

1.Redis本身就是單線程:

  • 單個命令執行具有原子性、無競態條件,這個特點符合一次只有一個客戶端爭用鎖;

2.Redis提供了set if not exists操作:

  • 存在即不設置,這個特點符合鎖的獨占性(排它特點);

下面來先來看下獲取鎖:

return jedis.set(lockKey, lockValue, NX, EX, expireTime) != null ? true : false;

這里使用set指令,具有原子操作特點,不會被其他客戶端操作中斷,在分布式環境中,是安全的,沒有競態條件產生,一次只能有一個客戶端爭用鎖;使用nx,即存在不設置,符合獨占特點;設置ex,有過期效果,不會產生永久獨占即死鎖;最后設置了lockValue,這樣就和當前加鎖任務做了綁定,后面可以用其作為解鎖的鑰匙;

再來看下解鎖操作:

static final String RELEASE_LOCK_LUA = "if redis.call('get', KEYS[1]) == ARGV[1] " +"then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(RELEASE_LOCK_LUA, 1, lockKey, lockValue);

這里解鎖是用了Lua腳本,上篇文章中介紹了Redis內置一個Lua解釋器,Redis調用解釋器執行Lua腳本也是具有原子性的,即同一時刻只有一個客戶端的操作能被執行,所以這里使用Lua腳本解鎖無競態條件;解鎖符合是占用鎖的任務釋放的原理;

但是以上實現的分布式鎖缺點是:

  • 不具有重入性,即當前任務獲取了鎖,在下次獲取時將會死鎖;
  • 不能自旋獲取,即獲取失敗時,將會立即返回失敗;

本人對其進行了改造,分別做了適應以上兩種場景的分布式鎖,詳情可以戮[Distributed Lock],歡迎大家一起來完善。

總結

本文從What、Features、How的角度分析了分布式鎖。總的來說,單機應用中的多線程或者多進程的鎖的放大版基本上就是分布式鎖了。萬變不離其宗,實現獨占鎖的關鍵性要素:

  • 目標:互斥同步,資源訪問原子化;
  • 實現:一次只能有一個爭用到鎖,爭用過程是個原子過程,只能爭用到的解鎖,不會發生死鎖;
參考

Redis 分布式鎖的正確實現方式
Rewriting our lock
Lock

題外話

參考Rewriting our lock中使用setnx實現的分布式,嚴格意義上來說是有死鎖問題的。setnx和expire不具有原子性。當setnx成功后,expire前應用發生宕機,這會導致鎖永遠不會過期,別的應用始終爭用不到鎖。當然這種情況比較特殊,但是做代碼是一件嚴謹的事!

轉載于:https://www.cnblogs.com/lxyit/p/9829132.html

總結

以上是生活随笔為你收集整理的Redis(七)分布式锁的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。