Redis在2.6版引入了對(duì)Lua的支持。
- 使用Lua可以非常明顯的提升Redis的效率。
Redis的一些命令
-
EVAL
執(zhí)行Lua腳本 -
EVALSHA
執(zhí)行Lua腳本的sha1 -
SCRIPT LOAD
加載Lua腳本到Redis Script -
SCRIPT FLUSH
清空Redis Script -
SCRIPT EXISTS
判斷是否存在Rdis Script中
EVAL
127.0.0.1:6379> eval "return 'Hello, world' " 0
"Hello, world"
在服務(wù)器中的Lua環(huán)境相當(dāng)于定義了以下函數(shù), 并且運(yùn)行函數(shù):
func f_9d4977f841f29202b7138237c28943c49565851b()
return 'Hello, world'
end
格式是固定的妄辩,為f_
+ Lua腳本的sha1值
EVALSHA
127.0.0.1:6379> evalsha 9d4977f841f29202b7138237c28943c49565851b 0
"Hello, world"
}
在服務(wù)器中的Lua環(huán)境中直接調(diào)用函數(shù)。
f_9d4977f841f29202b7138237c28943c49565851b()
這個(gè)地方需要特別注意的是请梢,在沒有執(zhí)行過eval
或script load
的lua腳本,直接調(diào)用會(huì)報(bào)錯(cuò),錯(cuò)誤信息如下:(error) NOSCRIPT No matching script. Please use EVAL.
SCRIPT LOAD
127.0.0.1:6379> script load "return 'Hello, world' "
"9d4977f841f29202b7138237c28943c49565851b"
script load
會(huì)將Lua腳本加載到lua_script字典中。
SCRIPT EXISTS
127.0.0.1:6379> script exists 9d4977f841f29202b7138237c28943c49565851b
1) (integer) 1
檢查L(zhǎng)ua腳本的sha1值是否存在lua_scripot字典中界弧。
SCRIPT FLUSH
127.0.0.1:6379> script flush
OK
清空lua_script字典。
Redis 執(zhí)行Lua腳本的過程
發(fā)送命令請(qǐng)求
EVAL "return redis.call('DBSIZE')" 0
Caller ------------------------------------------> Redis
為腳本 "return redis.call('DBSIZE')"
創(chuàng)建 Lua 函數(shù)
Redis ------------------------------------------> Lua
綁定超時(shí)處理鉤子
Redis ------------------------------------------> Lua
執(zhí)行腳本函數(shù)
Redis ------------------------------------------> Lua
執(zhí)行 redis.call('DBSIZE')
Fake Client <------------------------------------- Lua
偽客戶端向服務(wù)器發(fā)送
DBSIZE 命令請(qǐng)求
Fake Client -------------------------------------> Redis
服務(wù)器將 DBSIZE 的結(jié)果
(Redis 回復(fù))返回給偽客戶端
Fake Client <------------------------------------- Redis
將命令回復(fù)轉(zhuǎn)換為 Lua 值
并返回給 Lua 環(huán)境
Fake Client -------------------------------------> Lua
返回函數(shù)執(zhí)行結(jié)果(一個(gè) Lua 值)
Redis <------------------------------------------ Lua
將 Lua 值轉(zhuǎn)換為 Redis 回復(fù)
并將該回復(fù)返回給客戶端
Caller <------------------------------------------ Redis
Redis使用Lua的注意事項(xiàng)
- 如果Lua腳本中包括全局變量時(shí)搭综,會(huì)報(bào)錯(cuò)夹纫。定義變量時(shí)不要落下
local
關(guān)鍵字。 - 一定要確保Lua腳本已經(jīng)通過
load script
或eval
加載或執(zhí)行腳本之后再調(diào)用evalsha
设凹。 - 在一主多從的環(huán)境中,一定要注意使用
evalsha
時(shí)茅姜,從服務(wù)有可能會(huì)出現(xiàn)未成功加載lua腳本的情況闪朱。 - redis配置文件中一定要設(shè)置lua超時(shí)鉤子
lua-time-limit 5000
。