參考:
eval
為什麼要用lua指令碼操作redis資料庫?
1.減少開銷–減少向redis伺服器的請求次數
2.原子操作–redis將lua指令碼作為乙個原子執行
3.可復用–其他客戶端可以使用已經執行過的lua指令碼
4.增加redis靈活性–lua指令碼可以幫助redis做更多的事情
lua指令碼本身體積小,啟動速度快.
因此,從redis 2.6.0開始,redis在伺服器端內建lua直譯器
eval script numkeys key [key …] arg [arg …]
eval —lua程式的執行環境上下文
script —lua指令碼
numkeys —引數的個數(key的個數)
key —redis鍵 訪問下標從1開始,例如:keys[1]
arg —redis鍵的附加引數
eval和evalsha用redis內建的lua編譯器執行指令碼
舉例說明:
127.0.0.1:6379> eval
"return "
2 username password test 123456
1) "username"
2) "password"
3) "test"
4) "123456"
127.0.0.1:6379>
上面lua指令碼的意思是返回以lua陣列的形式返回key1,key2和value1,value2,2是key的個數.
主要有兩個函式來執行redis命令
redis.call() – 出錯時返回具體錯誤資訊,並且終止指令碼執行
redis.pcall() –出錯時返回lua table的包裝錯誤,但不引發錯誤
舉例說明:
127.0.0.1:6379> eval
"return redis.call('set',keys[1],argv[1])"
1 name redis
ok127.0.0.1:6379>
該指令碼中的函式作用是類似於執行 set name redis 的redis命令.並返回執行結果,ok
redis.call()出錯時:
.0.1:6379> eval "return redis.call('get',keys[1],argv[1])"
1name redis
(error) err error running
script (call to f_b943d620b079a29d99eccaaa7317e05f8eb8ce88): @user_script:1: @user_script: 1: wrong number
of args calling redis command from lua script
127.0
.0.1:6379>
redis.pcall()出錯時:
.0.1:6379> eval "return redis.pcall('get',keys[1],argv[1])"
1name redis
(error) @user_script: 1: wrong number
of args calling redis command from lua script
127.0
.0.1:6379>
lua通過redis.call()或者redis.pcall()函式執行redis命令的返回值被轉換成了lua資料結構,當然了,當lua指令碼在redis的內建直譯器裡執行時,lua指令碼的返回值也會被轉換成redis資料結構,然後由eval將值返回給客戶端.
那麼lua和redis資料型別之間時如何轉換的呢?對應關係又是怎樣的呢?
redis資料型別
lua資料型別
integer
number
bulk
string
multi bulk
table
status
包含ok域的table
error
包含err域的table
nil bulk
false
從redis資料型別到lua資料型別或者從lua資料型別到redis資料型別,都有以上對應規則,但是從
從lua轉換到redis有一條額外的對應規則
eval命令在每次執行指令碼時,都傳送一次指令碼主體,而evalsha並非如此,它的第乙個引數時指令碼的sha1校驗和.
evalsha命令的機制如下:
+ 如果伺服器記得sha1校驗和指定的指令碼,那麼執行該指令碼
+ 如果伺服器不記得sha1校驗和指定的指令碼,那麼它返回乙個錯誤,提醒使用者使用eval代替evalsha
因此在指令碼主體不變的情況下使用evalsha,可以使指令碼復用,而節省頻寬
指令碼需要被寫成純函式
對於同樣的資料輸入,給定相同的引數,指令碼執行的redis寫命令的結果總是相同的.
為此,redis做了以下事情:
+ lua沒有訪問系統時間或者其他內部狀態的命令
+ redis阻止上面所提到的指令碼執行
+ lua指令碼呼叫返回序命令的返回資料會被排序(字典序.)
+ 對 lua 的偽隨機數生成函式 math.random 和 math.randomseed 進行修改,使得每次在執行新指令碼的時候,總是擁有同樣的 seed 值.
不允許建立全域性變數
為了防止資料洩露進lua環境,redis指令碼不循序建立全域性變數.
訪問乙個全域性變數(無論是否存在)都會引起指令碼停止
使用lua操作redis資料庫能夠帶來很多便利,後續將提供例項展示lua指令碼是如何操作redis資料庫的.
Lua指令碼操作redis
eval script numkeys key key arg arg script 對應lua指令碼 numkeys 指定鍵名引數個數 key 為鍵名引數 arg 為附加引數 lua通過全域性變數keys和ar 獲取鍵名引數和附加引數,如下 local k1 keys 1 local feild ...
Redis資料庫操作
1.終端連線redis的命令redis cli h ip address linux系統下可通過ifconfig檢視ip address資訊2.在連線後選擇redis庫select number number是redis庫的編號3.檢視redis庫的keys資訊keys 4.減少redis庫連線次數...
資料庫 redis與redis操作
網上搜了以下redis的入門操作,全tm的關於怎麼安裝配置和效能特點的。基本的crud create,read,update,delete 就誰也沒說,簡直氣瘋了。先記錄下自己常用的命令,後面再回頭整理乙份常用的操作文件。命令列登入客戶端 redis cli 登入 auth password 顯示全...