dot Redis 8 来了——而且是开源的

了解更多

打开红色盒子:Redis Lua 调试器

更新:redis-lua-debugger 与 Redis v3 及以上版本不兼容

想象一个红色盒子。你把东西放进盒子里,然后等待其他东西出来(或者不出来)。 盒子出来的东西(或者不出来)完全取决于你告诉盒子你想要它做什么。这个盒子起源于 Terrah 的月球,所以它只理解月球语言,这是一种既陌生又与你已经习惯的东西相似的语言。为了让它按照你的指示行事,你需要非常详细地解释你想要它做什么,否则盒子根本无法工作。当盒子确实工作时,你得到的东西并不总是你认为你会得到的。红色盒子有一种古怪的幽默感,并且似乎在你试图窥视其内部运作以了解哪里出错时,你的挫败感不断增加而蓬勃发展。

这就是我有时在尝试编写即使是最简单的 Redis Lua 脚本时的感受。 并不是说盒子坏了,根本不是。 问题完全在于我的程序员技能以及我倾向于在各处洒满错误的独特倾向。 我最近写了用于跟踪和调试 Redis Lua 脚本的 5 种方法,但所有这些方法(不包括最后一种)都需要乏味地在代码中添加和删除调试打印输出。 所以我找到了一种更好的方法,结果就是我们的 Redis Lua 调试器(或者简称“rld”),它拥有以下功能

  • 完全非交互式调试器
  • 简单且原生的安装,只有 ~6KB 的有效负载
  • 输出打印到本地和远程控制台
  • 代码行执行跟踪
  • 最先进的自动监视机制,报告新变量和值更改
  • 报告函数调用、返回和参数 – 并进行实时分析

关于 Redis Lua 调试器,首先要知道的是它是用 Lua 编写的,并且在 Redis 中运行。 这意味着除了脚本和 Redis 之外,你不需要任何东西来使用 rld。 要使用 rld,你首先需要通过像运行任何常规脚本一样运行它来将其加载到你的 Redis 中 – 这将导致 rld 钻入你的 Redis 的 Lua 环境,直到下次服务器重新启动或调用SCRIPT FLUSH

rld 可以使用 Redis 的日志文件和 Pub/Sub(分别是上述文章中的方法 1 和 4)作为其输出。 为了保持跟踪,只需跟踪日志文件和/或订阅 `rld` 频道。 请注意,在你加载 rld 后,它将保持休眠状态,直到你的 Lua 脚本显式激活它,并且只要脚本运行或直到 rld 停止,它将保持活动状态。

因此,要实际使用 rld 调试你的脚本,你需要通过调用其 `start` 函数来打开它 – 只需在你的 Lua 脚本的开头添加以下行

rld.start()

现在你可以运行你的脚本了。 它将正常执行(或者更确切地说,非正常执行,因为我们毕竟是在谈论调试),但与此同时,rld 将跟踪它并打印有关其执行的信息。 仔细阅读输出,直到你达到那个 Aha!/#facepalm 的时刻。

这是一个示例 – 考虑以下名为 prog.lua 的 Lua 脚本

rld.start()

local function isanswer(n)
  local answer = 42
  if n == answer then
    return true
  else
    return false
  end
end

local t = isanswer(ARGV[1])

return ARGV[1] .. " " .. (t and "is" or "isn't") .. " the answer"

现在,加载 rld(如果你还没有加载)并运行脚本 – 因为我传递了 42 作为参数,所以我希望它是正确的答案

foo@bar:~$ redis-cli --eval rld.lua
"rld v0.1.0 loaded to Redis"
foo@bar:~$ redis-cli --eval prog.lua , 42
"42 isn't the answer"

哇! 等等! 刚刚发生了什么? 简单,只要查看您的日志

foo@bar:~$ tail -n 19 /var/log/redis_6379.log 
[891] 31 Dec 06:37:09.001 # [rld] -- rld v0.1.0 loaded to Redis
[891] 31 Dec 06:37:09.492 # [rld] -- rld v0.1.0 started
[891] 31 Dec 06:37:09.492 # [rld] ARGV[1] = '42'
[891] 31 Dec 06:37:09.492 # [rld] at Lua:@user_script (line: 10)
[891] 31 Dec 06:37:09.493 # [rld] at Lua:@user_script (line: 12)
[891] 31 Dec 06:37:09.493 # [rld] new [isanswer] = (function)
[891] 31 Dec 06:37:09.493 # [rld] call to function Lua:isanswer
[891] 31 Dec 06:37:09.493 # [rld]     args [n] = '42'
[891] 31 Dec 06:37:09.493 # [rld]     at Lua:isanswer (line: 4)
[891] 31 Dec 06:37:09.493 # [rld]     at Lua:isanswer (line: 5)
[891] 31 Dec 06:37:09.493 # [rld]     new [answer] = 42
[891] 31 Dec 06:37:09.493 # [rld]     at Lua:isanswer (line: 8)
[891] 31 Dec 06:37:09.493 # [rld] return from function Lua:isanswer
[891] 31 Dec 06:37:09.493 # [rld] at Lua:@user_script (line: 14)
[891] 31 Dec 06:37:09.493 # [rld] new [t] is false
[891] 31 Dec 06:37:09.493 # [rld] return from function Lua:@user_script
[891] 31 Dec 06:37:09.494 # [rld] -- profiler summary:
[891] 31 Dec 06:37:09.494 # [rld] --   Lua:isanswer called x1 times
[891] 31 Dec 06:37:09.494 # [rld] -- rld exited: end of script.

你能说 Halle-Lua 吗? 这不是很宝-Lua-able 吗? rld 可以从 https://github.com/RedisLabs/redis-lua-debugger 下载。 我希望你发现它至少和我制作它一样有用。 当然,还有很多可以做的事情来改进和扩展 rld,但我认为它已经是一个 MVP 了,所以我现在发布它。 至于 prog.lua……嗯,我仍然在努力记住我忘记了什么才能修复它。 如果你发现错误,请致电 tonumber:555-1234。

问题? 反馈? 请随时通过电子邮件 ([email protected]) 或在 Twitter 上 (@itamarhaber) 联系我,谈论任何事情 – 我非常乐于助人 🙂