redis lua 學習筆記
最近工作中要做一個秒殺系統,使用者的秒殺次數、分享數、優惠券的餘額等都存放在了redis中,所以需要對redis的操作保證原子性。
當然可以在伺服器端做鎖操作,不過更為方便的是在redis端操作。
於是想到了redis的lua指令碼,lua指令碼能夠保證redis執行的原子性(當然如果lua指令碼報錯的話,無法回滾掉已執行的部分程式碼的)
lua學習:
redis中如果想要使用lua指令碼,只需要呼叫eval命令即可。如果是在Java環境中,也有對應的eval(...)方法。
lua 中也分為區域性變數和全域性變數,不過redis為了防止資料汙染,就限定了lua指令碼中只允許使用區域性變數
區域性變數以local定義,比如:
local temp = keys[1]
eval 命令:
eval命令分為,指令碼、key 數量,keys ,argv等,格式如下:
eval "local key = KEYS[1] local c = redis.call('set',KEYS[2],ARGV[1]) if key == 'a' then return c else return 1 end " 2 b a 3
"local key = KEYS[1] #定義區域性變數,將外部設定的key賦值給key變數
local c = redis.call('set',KEYS[2],ARGV[1]) #將值賦值給key2 然後set到redis中,並給一個返回值
if key == 'a' then #判斷傳入的key
return c
else
return 1
end "
最終的返回值為1
利用lua來實現setnx並新增expire
local res ={} local key = KEYS[1] local ttl = tonumber(ARGV[1]) local k = redis.call('setnx',key,1) redis.call('expire',key,ttl) if k == 1 then res[1] = 'ok' else res[1] = 'no' end return res