redis事務和腳本
阿新 • • 發佈:2019-03-03
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
執行有啥好處:
- lua腳本是作為一個整體執行的.所以中間不會被其他命令插入;
- 可以把多條命令一次性打包,所以可以有效減少網絡開銷;
- 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事務和腳本