lua指令碼操作redis資料庫

2021-08-09 01:31:35 字數 2890 閱讀 4731

參考:

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 顯示全...