文章目录
- 背景说明
- Redis Lua调试器特点
- Redis Lua调试器快速入门
- Redis Lua debug命令
- 参考文章
背景说明
使用Redis
开发分布式应用时,难免会遇到需要使用分布式锁来确保某一小段逻辑的原子性操作,如:当存在某个key
对应的值A
大于值B
时,则返回false
;否则A + 1
。试想一下,如果用到分布式锁,是不是有点感觉像是杀鸡用宰牛刀?
由于Redis
的操作都是原子性的,所以我们可以将如上所述的类似逻辑采用Lua
脚本表述作为一个原子任务向redisClient
提交,可以避免采用分布式锁。如脚本:
local key = KEYS[1]
local expire_time = tonumber(ARGV[1])
local max_count = tonumber(ARGV[2])
-- 验证key是否存在,不存在设置过期时间
local is_key_exists = redis.call("EXISTS", key)
-- 存在
if is_key_exists == 1 then
local key_count = redis.call("get", key)
if tonumber(key_count) >= max_count then
return false;
else
redis.call("incr", key)
return true;
end
else
redis.call("incr", key);
redis.call("expire", key, expire_time)
return true;
end
但此时发现,在Redis
中调试是个困难的事情。但幸好,从Redis 3,2
版本开始,提供了Lua script debugger
来解决此问题。
Redis Lua调试器特点
Redis Lua
调试器代号为LDB
,特点如下:
- 支持单步调试
- 支持静态和动态断点
- 支持将被调试的脚本载入至调试终端
- 支持对
Lua
变量进行观察 - 支持追踪脚本执行的
Redis
命令 - 支持以美观方式打印
Redis
值及Lua
值 - 能够在无线循环及长时间执行步骤中模拟出断点
- 采用
CS
模型,S
即Redis
服务器,C
即redis-cli
客户端 - 默认情况下,每个调试会话都是
fork
子进程进行的。所以调试过程中不会影响Redis
其他操作;调试结束后,本次会话中的内容都会被回滚 - 你也可以将调试会话设置成同步模式,但是此时必须注意调试时会影响
Redis
所有其他的操作,且调试会话产生的结果都会被保存下来
Redis Lua调试器快速入门
以我们在刚开始提供的Lua
脚本,假设其目录为~/Desktop/tmp/test.lua
。此时执行命令(需要先cd
到redis-cli
命令目录下):
-- async mode
redis-cli --ldb --eval redis_lua_file redis_key , param1 param2
-- sync mode
redis-cli --ldb-sync-mode --eval redis_lua_file redis_key , param1 param2
~ redis-cli --ldb --eval ~/Desktop/tmp/test.lua key , 1 3
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 6, stop reason = step over
-> 6 local key = KEYS[1]
lua debugger>
注意:
redis-cli
里的逗号前后都是有空格的。我这里示例是本地有开启redis-server
,如果没有开启也可以连接到远程redis server
进行调试。另外,key
表示的是要传入脚本中处理的redis key
,其后的1和3则是参数,中间用空格隔开。
之后所要做的就是在debugger
里输入s
命令回车,表示执行下一步,直至程序结束或有异常退出为止。
Redis Lua debug命令
参考文章