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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

高并发-Redis分布式锁setnx,setex连用

發布時間:2023/12/13 综合教程 31 生活家
生活随笔 收集整理的這篇文章主要介紹了 高并发-Redis分布式锁setnx,setex连用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Lua在Redis中的使用方式

? redis中內嵌了Lua腳本的解釋器,并提供了執行Lua腳本的入口“eval”命令,

? 格式為 EVAL script numkeys key [key ...] arg [arg...] .

? 其中eval 為命令, script為執行的命令腳本, numkeys 為腳本中共涉及到的key的數量,后續接收若干個key的輸入和若干個arg的輸入.

? 整個腳本中使用KEYS[index],和ARGS[index]來獲取實際的輸入有點類似于SQL的占位符。另外一層原因由于Redis集群的固有模式導致EVAL在集群中涉及多個KEY的操作時要求所有的KEY都在同一個Hash Solt上,集群環境中調用EVAL Redis會對腳本先做一個的校驗。
KEYS[1] KEYS[2],是要操作的鍵,可以指定多個,在lua腳本中通過KEYS[1], KEYS[2]獲取。【特別注意】這些鍵要現在redis中存在,不然就獲取不到對應的值。
ARGV[1] ARGV[2],參數在lua腳本中通過ARGV[1], ARGV[2]獲取。

redis 執行Lua的保證

? Redis中保證對一個Lua腳本執行的完整性,也就是說一個Lua腳本的執行只會有成功和失敗,且保證在Redis Server端同時只會有一個Lua腳本在運行,這樣就意味著Lua腳本中的操作是一個完整的原子操作,不會伴隨中間狀態和資源競爭,同時也意味著在Lua腳本中不適合進行一些耗時長的操作.由于有以上的保證,使用Redis來進行一些復雜的原子操作就在合適不過了,setNx方法的局限性也被Redis Lua進行了彌補.

? Redis對嵌入的Lua做了若干的限制,包保證腳本不對Redis 造成破壞.不提供訪問系統狀態的庫,禁止使用loadfile函數,禁止帶有隨機性質的命令或者帶有副作用的命令, 對隨機讀命令的結果進行排序,替換math原有的random方法,不允許定義函數,不允許聲明全局變量等等.

要注意的是Lua中 0 為 true。

在腳本中調用redis命令
在腳本中可以使用redis.call函數調用Redis命令

  redis.call('set', 'foo', 'bar')
  local value=redis.call('get', 'foo') --value的值為bar

redis.call函數的返回值就是Redis命令的執行結果

Redis命令的返回值有5種類型,redis.call函數會將這5種類型的回復轉換成對應的Lua的數據類型。

Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在時,為 key 設置指定的值。

Redis分布式鎖

分布鎖滿足兩個條件,一個是加有效時間的鎖,一個是高性能解鎖

采用redis命令setnx(set if not exist)、setex(set expire value)實現

【千萬記住】解鎖流程不能遺漏,否則導致任務執行一次就永不過期

分布式鎖setnx、setex的缺陷,在setnx和setex中間發生了服務down機

從Redis宕機講解分布式鎖執行的異常場景流程

從Server服務宕機講解分布式鎖執行的異常場景流程

在setnx和setex中間發生了服務down機 那么key將沒有超時時間 會一直存在,新的請求永遠進不來

解決方案:

由于setnx與setex是分步進行,那么我們將兩步合成一步,放在同一個原子中即可

怎么一次性執行過一條命令而不會出現問題,采用Lua腳本

Redis從2.6之后支持setnx、setex連用

Lua簡介

  從 Redis 2.6.0 版本開始,通過內置的 Lua 解釋器,可以使用 EVAL 命令對 Lua 腳本進行求值。
  * Redis 使用單個 Lua 解釋器去運行所有腳本,并且, Redis 也保證腳本會以原子性(atomic)的方式執行:當某個腳本正在運行的時候,不會有其他腳本或 Redis 命令被執行。這和使用 MULTI / EXEC 包圍的事務很類似。在其他別的客戶端看來,腳本的效果(effect)要么是不可見的(not visible),要么就是已完成的(already completed)。
在 Lua 腳本中,可以使用redis.call()來執行 Redis 命令

Lua腳本配置流程

  1、在resource目錄下面新增一個后綴名為.lua結尾的文件
  2、編寫lua腳本

      local lockKey = KEYS[1]
      local lockTime = KEYS[2]
      local lockValue = KEYS[3]

      -- setnx info
      local result_1 = redis.call('SETNX', lockKey, lockValue)
      if result_1 == 1
      then
      local result_2= redis.call('SETEX', lockKey,lockTime, lockValue)
      return result_2
      else
      return 'faild'
      end

3、傳入lua腳本的key和arg
4、調用redisTemplate.execute方法執行腳本

總結

以上是生活随笔為你收集整理的高并发-Redis分布式锁setnx,setex连用的全部內容,希望文章能夠幫你解決所遇到的問題。

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