Redis之lua腳本


Redis的lua腳本

Redis在2.6推出了腳本功能,允許開發者使用 Lua 語言編寫腳本傳到 Redis 中執行。

1、使用lua腳本的優點

(1)減少網絡開銷:多次網絡請求的操作,可以用一個請求完成,原先多次請求的邏輯放在redis服務器上完成。使用腳本,減少了網絡往返時延。

(2)原子操作:Redis會將整個腳本作為一個整體執行,中間不會被其他命令插入。管道不是原子的,不過redis的批量操作命令(類似mset)是原子的

(3)替代redis的事務功能redis自帶的事務功能很雞肋,報錯不支持回滾,而redis的lua腳本幾乎實現了常規的事務功能,支持報錯回滾操作;官方推薦如果要使用redis的事務功能可以用redis lua替代。

2、可以使用 EVAL命令對Lua腳本進行求值。EVAL命令的格式如下: 

EVAL script numkeys key [key ...] arg [arg ...]

說明:

script:是一段Lua腳本程序 ,它會被運行在Redis服務器上下文中,這段腳本不必(也不應該)定義為一個Lua函數。

numkeys:用於指定鍵名參數的個數。

key [key ...]: 從EVAL的第三個參數開始算起,表示在腳本中所用到的那些Redis鍵(key),這些鍵名參數可以在 Lua中通過全局變量KEYS數組,用1為基址的形式訪問( KEYS[1] , KEYS[2] ,以此類推)。

 arg [arg ...]:在命令的最后,那些不是鍵名參數的附加參數 arg [arg ...] ,可以在Lua中通過全局變量ARGV數組訪問,訪問的形式和KEYS變量類似( ARGV[1] 、 ARGV[2]) 

例如:

eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second

 在 Lua 腳本中,可以使用 redis.call() 函數來執行Redis命令。

 Jedis調用示例:

jedis.set("product_stock_10000", "15"); //初始化商品10000的庫存
String script = " local count = redis.call('get', KEYS[1]) " +
  " local a = tonumber(count) " +
  " local b = tonumber(ARGV[1]) " +
  " if a >= b then " +
  "   redis.call('set', KEYS[1], count‐b) " +
  "   return 1 " +
  " end " +
  " return 0 "; Object obj = jedis.eval(script, Arrays.asList("product_stock_10000"), Arrays.asList("10")); System.out.println(obj);

注意:不要在Lua腳本中出現死循環和耗時的運算,否則redis會阻塞,將不接受其他的命令, 所以使用時要注意不能出現死循環、耗時的運算。redis是單進程、單線程執行腳本。管道不會阻塞redis。

lua 腳本執行報錯會進行回滾操作。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM