lua 菜鳥教程:https://www.runoob.com/lua/lua-tutorial.html
在 Redis 使用 lua 腳本的好處:
- 減少網絡開銷??梢詫⒍鄠€請求通過腳本的形式一次發(fā)送,減少網絡時延及開銷
- 原子性操作。Redis會將整個腳本作為一個整體執(zhí)行,中間不會被其他請求插入。因此在腳本運行過程中無需擔心會出現(xiàn)競態(tài)條件,無需使用事務
- 復用。客戶端發(fā)送的腳本會永久存在redis中,這樣其他客戶端可以復用這一腳本,而不需要使用代碼完成相同的邏輯
1. 常用命令
-
EVAL
:將腳本 script 添加到腳本緩存中,并且立即執(zhí)行這個腳本- 語法:
EVAL script numkeys key [key …] arg [arg …]
- 參數含義:
- script:是 Lua5.1 腳本程序。此Lua腳本不需要也不應該定義函數,它運行在 Redis 服務器中
- numkeys:鍵名參數的個數。即:key [key …] 中 key 的個數。如沒有 key,則為 0
- key[]:鍵名參數,表示在腳本中所用到的那些 Redis 鍵(key),這些鍵名參數可以在 lua 中通過全局變量 KEYS 數組。在 lua 腳本中通過 KEYS[1],KEYS[2] 獲取
- arg [arg …] :不是鍵名參數的附加參數,可以在 lua 中通過全局變量 ARGV 數組訪問。在 lua 腳本中通過 ARGV[1],ARGV[2] 獲取
- 案例
- 調用 set 方法:
EVAL "return redis.call('set', 'name', 'bob')" 0
- 調用 set 方法(使用參數):
EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 name jack
- 調用 set 方法:
- 語法:
-
EVALSHA
:根據給定的 sha1 校驗碼,執(zhí)行緩存在服務器中的腳本。將腳本緩存到服務器的操作可以通過SCRIPT LOAD
命令進行。這個命令的其他地方,比如參數的傳入方式,都和EVAL
命令一樣- 語法:
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
- 語法:
-
SCRIPT LOAD
:將腳本 script 添加到腳本緩存中,但并不立即執(zhí)行這個腳本。 在腳本被加入到緩存之后,通過EVALSHA
命令,可以使用腳本的SHA1
校驗和來調用這個腳本。
腳本可以在緩存中保留無限長的時間,直到執(zhí)行 SCRIPT FLUSH 為止- 語法:
SCRIPT LOAD script
。 - 返回:腳本的 SHA1 校驗和
- 語法:
-
SCRIPT EXISTS
:校驗指定的腳本是否已經被保存在緩存當中- 語法:
SCRIPT EXISTS sha1 [sha1 ...]
- 語法:
-
SCRIPT FLUSH
:清除 Redis 服務端所有 lua 腳本緩存 -
SCRIPT KILL
:用于殺死當前正在運行的 lua 腳本,當且僅當這個腳本沒有執(zhí)行過任何寫操作時,這個命令才生效。這個命令主要用于終止運行時間過長的腳本,比如一個因為 BUG 而發(fā)生無限循環(huán)的腳本
案例:
redis 127.0.0.1:6379> SCRIPT LOAD "return 'hello moto'" # 載入一個腳本
"232fd51614574cf0867b83d384a5e898cfd24e5a"
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 1
redis 127.0.0.1:6379> SCRIPT FLUSH # 清空緩存
OK
redis 127.0.0.1:6379> SCRIPT EXISTS 232fd51614574cf0867b83d384a5e898cfd24e5a
1) (integer) 0
2. 具體業(yè)務使用案例
基于 Redis 的分布式鎖
釋放鎖的流程:
- 獲取鎖中的線程標識
- 判斷是否與指定的標識(當前線程標識)一致
- 如果一致,則刪除;否則,什么都不做
unlock.lua 如下:resources/unlock.lua
文章來源:http://www.zghlxwxcb.cn/news/detail-730379.html
-- 比較線程標示與鎖中的標示是否一致
if(redis.call('get', KEYS[1]) == ARGV[1]) then
-- 釋放鎖 del key
return redis.call('del', KEYS[1])
end
return 0
在 Java 中調用:文章來源地址http://www.zghlxwxcb.cn/news/detail-730379.html
// 初始化 lua 腳本文件
private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
static {
UNLOCK_SCRIPT = new DefaultRedisScript<>();
//lua腳本位置
UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));
//返回值類型
UNLOCK_SCRIPT.setResultType(Long.class);
}
// 使用 lua 腳本釋放鎖
public void unlock(String lockKey,String lockValue){
// 調用lua腳本
redisTemplate.execute(
UNLOCK_SCRIPT,
Collections.singletonList(lockKey),
lockValue);
}
到了這里,關于【Redis】Redis 的學習教程(十二)之在 Redis使用 lua 腳本的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!