lua與redis結合

一,Redis和Lua結合redis

1:redis.call:在腳本中調用Redis命令,遇到錯誤會直接返回緩存

2:redis.pcall:在腳本中調用Redis命令,遇到錯誤會記錄錯誤並繼續執行安全

3:Lua數據類型和Redis返回值類型對應服務器

(1)數字——整數dom

(2)字符串——字符串模塊化

(3)表類型——多行字符串函數

(4)表類型(只有一個ok字段存儲狀態信息)——狀態回覆ui

(5)表類型(只有一個err字段存儲錯誤信息)——錯誤回覆this

4:eval命令:在Redis中執行腳本編碼

(1)格式是:eval 腳本內容key參數數量[key…] [arg…]

(2)經過key和arg兩類參數來向腳本傳遞數據,在腳本中分別用KEYS和ARGV來獲取

注意:

對於KEYS和ARGV的使用並非強制的,也能夠不從KEYS去獲取鍵,而是在腳本中硬

編碼,好比:redis.call(‘get’,’user:’..ARGV[1]) 0 key1 ,照樣能取

到」user:key1」對應的值。

可是這種寫法,就沒法兼容集羣,也就是說不能在集羣中使用。要兼容集羣,建議

的方式是在客戶端獲取全部的key,而後經過KEYS傳到腳本中。

5:evalsha命令:能夠經過腳本摘要來運行,其餘同eval。執行的時候會根據摘要去找緩存的

腳本,找到了就執行,不然會返回錯誤。

6:script load:將腳本加入緩存,返回值就是SHA1摘要

7:script exists:判斷腳本是否已經緩存

8:script flush:清空腳本緩存

9:script kill:強制終止腳本的執行,若是腳本中修改了某些數據,那麼不會終止腳本的執

行,以保證腳本執行的原子性

二,沙箱

爲了保證Redis服務器的安全,而且要確保腳本的執行結果只和腳本執行時

傳遞的參數有關,Redis禁止腳本中使用操做文件或系統調用相關的函數,腳本

中只能對Redis數據進行操做,這就是沙箱。

Redis會禁用腳本的全局變量,以保證腳本之間是隔離的,互不相干的。

三, Redis對隨機數和隨機結果的處理

1:爲了確保執行結果能夠重現,Redis對隨機數的功能進行了處理,以保證每次執

行腳本生成的隨機數列都相同

2:Redis還對產生隨機結果進行了處理,好比smembers或hkeys等,數據都是無序

的,Redis會對結果按照字典進行順序排序

3:對於會產生隨機結果但沒法排序的命令,好比指揮產生一個元素,Redis會在這

類命令執行後,把該腳本標記爲lua_random_dirty,此後只容許調用讀命令,不

許修改,不然返回錯誤,這類Redis命令有:spop、srandmember、randomkey、

time。

四,MetaTable

用來實現重載操做符功能,基本示例以下:

1:自定義操做的函數,示例:

myAdd={}

function myAdd.__add(f1,f2)

--具體的操做

end

2:爲已有的table設置自定義的操做模板,示例:

setmetatable(tableA,myAdd)

setmetatable(tableB,myAdd)

3:對兩個table作加的操做,示例:

tableA+tableB

這個時候就會調用自定義的myAdd了,等於重載了默認的_add方法,myAdd的__add方法就是MetaMethod

4:Lua內建約定的MetaMethod :

__add(a, b) 、__sub(a, b)、__mul(a, b)、__div(a, b)、__mod(a, b)、__pow(a, b) 、

__unm(a) 取反、__concat(a, b)、__len(a)、__eq(a, b)、__lt(a, b)、__le(a, b)、__index(a, b)

對應表達式a.b、__newindex(a, b, c) 對應表達式a.b = c、__call(a, ...)

五,面向對象

Lua腳本的面向對象相似於JavaScript的面向對象,都是模擬的,好比:

1:直接建立對象:local user={userId='user1',userName='sishuok'}

2:添加新屬性:user.age = 12

3:添加方法

function user:show(a)

redis.log(redis.LOG_NOTICE,'a='..a..',age='..self['age'])

end

裏面的self就至關於this

4:就能夠調用方法了:user:show('abc')

5:作個子類來繼承user:

local child={address='bj'}

setmetatable(child,{__index=user})

__index在這裏起的做用就相似於JS中的Prototype

6:繼承了天然就能夠調用父類的屬性和方法了:child:show('child')

7:固然你還能夠定義本身的方法去覆蓋父類的方法:

function child:show(a)

redis.log(redis.LOG_NOTICE,'child='..a..',age='..self['age']..',address=='..self.address)

end

六,模塊化

注意:這種方式不能在Redis中使用,目前不支持

1:能夠直接使用require(「model_name」)來載入別的lua文件,文件的後綴

是.lua。載入的時候就會直接執行那個文件

2:載入一樣的lua文件時,只有第一次的時候會去執行,後面的相同的都不執行了

3:若是要讓每一次文件都執行,可以使用dofile(「model_name」)函數

4:若是要載入後不執行,等須要的時候執行,可以使用loadfile(「model_name」)

函數,這種是把loadfile的結果賦值給一個變量,好比:

local abc = loadfile(「載入的lua」) 後面須要運行時: abc()

相關文章
相關標籤/搜索