1. 程式人生 > >redis事務和腳本

redis事務和腳本

key 全部 short 邏輯 solid zadd 字符 height line

事務,簡單理解就是,一組動作,要麽全部執行,要麽就全部不執行.從而避免出現數據不一致的情況。

redis提供了簡單的事務功能,將一組需要的命令放到multi和exec兩個命令之間。multi代表事務開始,exec代碼事務結束。

eg:

技術分享圖片
可以看到sadd命令一開始返回的結果是QUEUED,代表命令並沒有真正執行,只是暫時存在redis中,只有當exec執行了,這組命令才算是完成。

如果事務中的命令出現錯誤:

  • 命令錯誤:比如說語法錯誤, set寫成了sett,整個的事務將無法執行
  • 運行時錯誤:比如說應該用sadd,卻誤寫成了zadd,從語法上講,是沒有毛病的,但是上面的寫對的命令,已經執行入庫了, 這種情況就需要開發人員自己修復了。

所以說redis不支持事務中的回滾特性.無法實現命令之間的邏輯關系計算。

所以在開發中,還可以采用lua腳本來實現事務的,簡單理解:使用lua語言編寫腳本傳到redis中執行。

Lua

執行有啥好處:

  1. lua腳本是作為一個整體執行的.所以中間不會被其他命令插入;
  2. 可以把多條命令一次性打包,所以可以有效減少網絡開銷;
  3. lua腳本可以常駐在redis內存中,所以在使用的時候,可以直接拿來復用.也減少了代碼量.

使用上舉個例子

訪問控制 ,10秒內最多訪問3次,訪問頻率在10s內小於等於3次時返回1,否則返回0

local times = redis.call(incr,KEYS[1])
 
if times == 1 then redis.call(expire,KEYS[1], ARGV[1]) end if times > tonumber(ARGV[2]) then return 0 end return 1 redis

客戶端,測試腳本:

技術分享圖片
eval命令和--eval 本質是一樣的.客戶端如果想要執行lua腳本,首先要在客戶端編寫好lua腳本代碼,然後把腳本作為字符串發送給服務端,服務端把執行結果返回給客戶端

--eval 是告訴redis-cli讀取並運行後面的腳本, ratelimiting.lua是腳本的位置.後面是腳本的參數. 這裏10 是腳本中ARGV[1] 3是 ARGV[2]

, 前的rate.limiting:127.0.0.1 是要操作的鍵,對應的是腳本中KEYS[1]

這個應用場景算是限速.比如說每次登陸,讓用戶輸入手機驗證碼,從而確定是否是用戶本人,但是如果用戶瘋狂的點,獲取驗證碼,那麽短信的這個接口就會一直被調用.那麽咱們這邊就可以進行限制. 如果不用lua腳本, 用代碼也是可以實現的.這裏寫上偽代碼

phoneNum= "1573262xxxx"
key="shortMsg:limit:"+phoneNum;
isExists=redis.set(key,1,"EX 600" "NX");
if(isExist!=null) || redis.incr(key) <=n{
    //通過
}else{
    //限速
}

redis事務和腳本