Redis提供了豐富的指令集,可是仍然不能知足全部場景,在一些特定場景下,須要自定義一些指定來完成某些功能。所以,Redis提供了Lua腳本支持,用戶能夠本身編寫腳原本實現想要的功能。redis
Lua是一種功能強大的,高效,輕量級,可嵌入的腳本語言。它是動態類型語言,經過使用基於寄存器的虛擬機解釋字節碼運行,並具備增量垃圾收集的自動內存管理,是配置,腳本和快速原型設計的最佳選擇。數組
Redis中可使用EVAL命令執行相應的Lua腳本bash
> EVAL 'local val="Hello Jackey" return val' 0
"Hello Jackey"
複製代碼
你能夠像這樣在交互模式下執行Lua腳本,這樣更方便處理錯誤。只是這樣還不夠,有時候,咱們須要給Lua腳本傳入一些參數。細心的同窗必定注意到了,腳本的後面還有一個數字0,它的意思的不傳入參數。服務器
那怎麼傳參數呢?ui
> EVAL 'local val=KEYS[1] return val.." "..ARGV[1]' 1 Hello Redis
"Hello Redis"
複製代碼
其實也很簡單,傳入的參數都是kv形式的,這個數字表明傳入參數的key的數量,再後面就是n個key和n個value。在腳本中,能夠理解爲從KEYS數組和ARGV數組中獲取對應的值,下標是從1開始的。lua
上面例子中的兩個點是Lua腳本中字符串鏈接的操做符spa
如今咱們已經知道怎麼在Redis中執行Lua腳本了,但是這樣的腳本和Redis沒有關係啊,怎麼才能操做Redis中的數據呢?請繼續看我表演設計
> get my_name
"Jackeyzhe"
> EVAL 'local val=ARGV[1].." "..redis.call("get",KEYS[1]) return val' 1 my_name Hello
"Hello Jackeyzhe"
複製代碼
使用redis.call或redis.pcall(之後會提到)就能夠操做redis了。日誌
須要注意的是,若是返回下面的錯誤,說明要獲取的key不存在code
> EVAL 'local val=ARGV[1].." "..redis.call("get",KEYS[1]) return val' 1 me Hello
(error) ERR Error running script (call to f_eb11f8ddeeee07cc88d1f3bd103069284b83c5d8): @user_script:1: user_script:1: attempt to concatenate a boolean value
複製代碼
咱們可使用上面這種方法執行一些簡單的Lua腳本,若是要執行更加複雜的Lua腳本,用EVAL命令就會顯得臃腫且凌亂。因此Redis又提供了一種方法。
咱們能夠先寫一個Lua文件,而後使用redis-cli命令來執行。
local name=redis.call("get", KEYS[1])
local greet=ARGV[1]
local result=greet.." "..name
return result
複製代碼
> redis-cli --eval hello.lua my_name , Hello
"Hello Jackey"
複製代碼
這樣,咱們就能夠先寫一個.lua文件,而後再使用redis-cli命令來執行了,看起來也不會很凌亂,使用這種方式傳入參數時,不須要指定key的數量,而是用逗號分隔key和argv。
你覺得到這就結束了嗎?那就too naive了。若是咱們在Redis交互模式中,想要執行腳本文件怎麼辦?每次都退出來,執行完再鏈接一次?這未免太麻煩了。Redis提供了EVALSHA命令,使咱們能夠在交互模式執行腳本文件。
首先,須要上傳腳本文件
$ redis-cli SCRIPT LOAD "$(cat hello.lua)"
"463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46"
複製代碼
會獲得一串十六進制的數字,這是這個腳本的惟一標識。拿到這個數字後,表示咱們已經將腳本上傳到服務器了,接下來就可使用這個標識來執行腳本了。
> EVALSHA 463ff2ca9e78e36cd66ee9d37ee0dcd59100bf46 1 my_name Hello
"Hello Jackeyzhe"
複製代碼
Redis中Lua腳本到默認執行時長是5秒,通常狀況下腳本的執行時間都是毫秒級的,若是執行超時,腳本也不會中止,而是記錄錯誤日誌。
終止腳本執行的方法有兩種
不過不建議手動終止腳本
本文簡要介紹了什麼是Lua,以及Redis執行和終止Lua腳本的方法。若是都掌握了,那麼恭喜你已經從Lua小學畢業了。在Lua中學你會學到Redis關於Lua命令的更詳細介紹。