Lua 操作 Redis

雖然redis服務是單線程的服務,單步的redis操作是線程安全的,但是當我們在高并發(fā)的情況下,需要一系列的redis邏輯操作,而這些操作需要保證線程安全和原子性。這時候就需要Lua登場。
Lua 為靜態(tài)語言提供更多的靈活性,Lua體積小、啟動速度快。 Redis Lua 腳本出現(xiàn)之前 Redis 是沒有服務器端運算能力的,主要是用來存儲,用做緩存,運算是在客戶端進行。有了 Lua 的支持,客戶端可以定義對鍵值的運算,減少編譯的次數(shù),總之??梢宰?Redis 更為靈活。redis 甚至在源代碼中加入了Lua腳本的解釋器,eval。

redis 缺點

  1. 如此會破壞數(shù)據(jù)的一致性,試想如果兩個客戶端先后獲?。╣et)一個值,它們分別對鍵值做不同的修改,然后先后提交結(jié)果,最終 Redis 服務器中的結(jié)果肯定不是某一方客戶端所預期的。
  2. 浪費了數(shù)據(jù)傳輸?shù)木W(wǎng)絡帶寬。

基本概念

1. Redis 2.6.0

  • 從Redis 2.6.0 開始, Redis在服務器端內(nèi)置Lua解釋器,支持通過Lua腳本操作Redis

2. EVAL

  • 通過Lua操作Redis最常用的命令之一, 第一個參數(shù) Lua腳本

3. EVALSHA

  • 通過Lua操作Redis最常用的命令之一, 第一個參數(shù)是Lua腳本生成的SHA值; 可以節(jié)省帶寬

4. 串行

  • Lua腳本在Redis服務器端是串行執(zhí)行的,因此可以實現(xiàn)類似事務的功能。

最簡單的Lua腳本

hello.lua

local msg = "hello world!"
return msg

運行命令

redis-cli -h ****(ip) -p ***(port) eval "$(cat hello.lua)" 0

運行這段代碼會打印"Hello,world!", EVAL在第一個參數(shù)是我們的lua腳本, 這我們用cat命令從文件中讀取我們的腳本內(nèi)容。第二個參數(shù)是這個腳本需要訪問的Redis 的鍵的數(shù)字號。我們簡單的 “Hello Script" 不會訪問任何鍵,所以我們使用 0

get和set 的例子

getSet.lua

local key = KEYS[1]
local value = ARGV[1]
redis.call('set', key, value)
return redis.call('get', key)

運行命令

redis-cli -h ****(ip) -p ***(port) eval "$(cat getSet.lua)" 1 age 18
運行結(jié)果.png

call() 的參數(shù)就是發(fā)給Redis的命令:首先set key value ,然后 get key,這兩個命令將依次執(zhí)行,當這個腳本執(zhí)行時,Redis服務不會做任何操作(單線程),它將非??焖龠\行。

我們將會訪問兩個Lua表:KEYSARGV。表單是關聯(lián)性數(shù)組和結(jié)構(gòu)化數(shù)據(jù)的Lua唯一機制。對于我們的意圖,你可以把它們看做是一個你所熟悉的任意語言對等的數(shù)組,但是提醒兩個很容易困擾到新手的兩個Lua定則:
表是基于1的,也就是說索引以數(shù)值1開始。所以在表中的第一個元素就是KEYS[1],第二個就是KEY[2]等等。
表中不能有nil值。如果一個操作表中有[1, nil, 3, 4],那么結(jié)果將會是[1]——表將會在第一個nil截斷。
當調(diào)用這個腳本時,我們還需要傳遞KEYSARGV表的值,為Redis編寫Lua腳本時,每個KEY都是通過KEYS表指定。ARGV表用來傳遞參數(shù)。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容