我能在Redis中分析运行的Lua脚本吗?

我有一个集群应用程序,使用分布式 Redis 后端,动态生成的 Lua 脚本分配到 Redis 实例。Lua 组件脚本可能会变得相当复杂,并且具有重要的运行时,我想能够对它们进行剖析以查找热点。

SLOWLOG 对于告诉我脚本运行缓慢以及它们缓慢的程度非常有用,但这不是我的问题。我知道它们有多慢,我想要找出哪些部分是慢的。

Redis EVAL 文档明确指出 redis 不会向 lua 导出任何计时函数,这使得它似乎可能是一种无望的做法。

因此,除非自定义 Redis 分支,否则有没有办法告诉我的 Lua 脚本的哪些部分比其他部分更慢呢?

编辑 我采用了 Doug 的建议并使用 debug.sethook - 这是我在脚本顶部插入的钩子例程:

redis.call('del', 'line_sample_count')
local function profile()
  local line = debug.getinfo(2)['currentline']
  redis.call('zincrby', 'line_sample_count', 1, line)
end
debug.sethook(profile, '', 100)

然后,查看我脚本的最热门的 10 行:

ZREVRANGE line_sample_count 0 9 WITHSCORES
点赞
用户88888888
用户88888888

在标准的 Lua C 中,你不能直接获取毫秒级别的时间,因为它不是一个内置函数,只返回秒数。因此,有两个选项可用:你可以编写自己的 Lua 扩展 DLL 以返回毫秒级别的时间,或者:

你可以使用毫秒级别的时间进行基本的基准测试。你可以使用 LuaSocket 访问当前的毫秒级别时间。虽然这会给你的项目添加一个依赖项,但这是进行简单基准测试的有效方法。

require "socket"
t = socket.gettime();
2013-05-04 03:42:47
用户33252
用户33252

如果您的脚本是处理绑定的(不是 I/O 绑定),那么您可能可以使用 debug.sethook 函数和计数钩子:

计数钩子:在解释器执行每个计数指令后调用。(此事件仅在 Lua 执行 Lua 函数时发生。)

您需要基于回调中接收到的计数构建性能分析器。

PepperfishProfiler 是一个不错的起点。它使用 os.clock,而您则可以使用钩子计数进行一个非常粗略的近似。

这也在 PiL 23.3 – Profiles 中涉及。

2013-05-04 04:48:03