赞
踩
参考:
Redis从2.6.0版本开始支持Lua脚本,通过在服务器嵌入Lua环境,Redis客户端可以使用Lua脚本,直接在服务器端原子地执行多个Redis命令。
1.使用Lua脚本的好处:
2.相关命令:
EVAL script numkeys key [key ...] arg [arg ...]
KEYS
数组访问,下标从1开始,如: KEYS[1]、KEYS[2]ARGV
数组访问,下标从1开始,如:ARGV[1]、ARGV[2]示例:
(1)使用KEYS
数组、ARGV
数组
redis> eval "return {KEYS[1], KEYS[2], ARGV[1], ARGV[2]}" 2 key1 key2 arg1 arg2
1) "key1"
2) "key2"
3) "arg1"
4) "arg2"
(2)输出list中所有元素
redis> rpush nums 1 2 3
(integer) 3
redis> eval "return redis.call('lrange', KEYS[1], 0, -1)" 1 nums
1) "1"
2) "2"
3) "3"
(3)集合去重
使用lua脚本文件方式,在命令行里执行,和在redis里执行不太一样,命令如下:
redis-cli --eval lua_file key1 key2 , arg1 arg2 arg3
示例:
redis> sadd nums 1 2 3
(integer) 3
redis> smembers nums
1) "1"
2) "2"
3) "3"
-- key local key = KEYS[1] -- 所有参数 local args = ARGV -- 初始化result local result = {} -- 判断元素是否存在 for m, n in ipairs(args) do local is_repeat = redis.call("sismember", key, n) if (is_repeat) then table.insert(result, 1, n) end end return result
$ redis-cli --eval ./member.lua nums , 1 2
1) "2"
2) "1"
SCRIPT LOAD script
:将脚本 script 添加到脚本缓存中,但并不立即执行这个脚本
EVALSHA sha1 numkeys key [key ...] arg [arg ...]
:根据给定的 sha1 校验码,执行Lua脚本
EVAL
命令示例:
redis> script load "return 'hello redis'"
"69dd69fc0ba1e25d8e2972008b6baee8eccf7da6"
redis> evalsha 69dd69fc0ba1e25d8e2972008b6baee8eccf7da6 0
"hello redis"
SCRIPT EXISTS script [script ...]
:查看指定的脚本是否已经被保存在缓存当中
SCRIPT FLUSH
:从脚本缓存中移除所有脚本示例:
redis> script load "return 'hello redis'"
"69dd69fc0ba1e25d8e2972008b6baee8eccf7da6"
redis> script exists 69dd69fc0ba1e25d8e2972008b6baee8eccf7da6
1) (integer) 1
redis> script flush
OK
redis> script exists 69dd69fc0ba1e25d8e2972008b6baee8eccf7da6
1) (integer) 0
SCRIPT KILL
:杀死当前正在运行的 Lua 脚本,当且仅当这个脚本没有执行过任何写操作时,这个命令才生效
注:
SCRIPT KILL
执行之后,当前正在运行的脚本会被杀死,执行这个脚本的客户端会从 EVAL 命令的阻塞当中退出,并收到一个错误作为返回值。示例:
客户端A:
# 当前没有正在执行的脚本
redisA> script kill
(error) NOTBUSY No scripts in execution right now.
# 客户端B执行脚本,客户端A杀死运行的脚本
redis> script kill
OK
(0.92s)
客户端B:
# 脚本死循环
redisB> eval "local a = 1; while 1 do a=1; end" 0
# 被杀死后,返回以下信息
(error) ERR Error running script (call to f_c8600a7388e4dd63490c59ede33602dbef5971eb): @user_script:1: Script killed by user with SCRIPT KILL...
(5.00s)
SCRIPT DEBUG YES|SYNC|NO
:使用EVAL可以开启对脚本的调试
注:LDB可以设置成两种模式:同步和异步。
示例:
(1)redis内调试
# 异步调试,回退修改后的数据 redis> script debug yes OK # 测试脚本 redis> eval "local a = 1; \n local b = 2; \n return 3" 0 * Stopped at 1, stop reason = step over -> 1 local a = 1; # 使用 n 单步调试 redis> n * Stopped at 2, stop reason = step over -> 2 local b = 2; redis> n * Stopped at 3, stop reason = step over -> 3 return 3 redis> n (integer) 3 (Lua debugging session ended -- dataset changes rolled back)
(2)命令行内调试
使用第一节中的示例(3),命令中添加--ldb
进入调试模式:redis-cli --ldb --eval ./member.lua nums , 1 2
--ldb-sync-mode
进入同步模式,此时服务器其他链接被阻塞,调试结束后修改后的数据会被保存调试示例:【参考:http://blog.huangz.me/2017/redis-lua-debuger-introduction.html】
$ redis-cli --ldb --eval ./member.lua nums , 1 2 Lua debugging session started, please use: quit -- End the session. restart -- Restart the script in debug mode again. help -- Show Lua script debugging commands. * Stopped at 2, stop reason = step over -> 2 local key = KEYS[1] lua debugger> n * Stopped at 5, stop reason = step over -> 5 local args = ARGV lua debugger> n * Stopped at 8, stop reason = step over -> 8 local result = {} lua debugger> n * Stopped at 11, stop reason = step over -> 11 for m, n in ipairs(args) do lua debugger> n * Stopped at 12, stop reason = step over -> 12 local is_repeat = redis.call("sismember", key, n) lua debugger> n <redis> sismember nums 1 <reply> 1 * Stopped at 13, stop reason = step over -> 13 if (is_repeat) then lua debugger> n * Stopped at 14, stop reason = step over -> 14 table.insert(result, 1, n) lua debugger> n * Stopped at 11, stop reason = step over -> 11 for m, n in ipairs(args) do lua debugger> n * Stopped at 12, stop reason = step over -> 12 local is_repeat = redis.call("sismember", key, n) lua debugger> n <redis> sismember nums 2 <reply> 1 * Stopped at 13, stop reason = step over -> 13 if (is_repeat) then lua debugger> n * Stopped at 14, stop reason = step over -> 14 table.insert(result, 1, n) lua debugger> n * Stopped at 11, stop reason = step over -> 11 for m, n in ipairs(args) do lua debugger> n * Stopped at 17, stop reason = step over -> 17 return result lua debugger> n 1) "2" 2) "1" (Lua debugging session ended -- dataset changes rolled back)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。