【问题标题】:Can I profile Lua scripts running in Redis?我可以分析在 Redis 中运行的 Lua 脚本吗?
【发布时间】:2013-04-28 12:45:06
【问题描述】:

我有一个使用分布式 Redis 后端的集群应用程序,动态生成的 Lua 脚本被分派到 redis 实例。 Lua 组件脚本可能会变得相当复杂并且运行时间很长,我希望能够分析它们以找到热点。

SLOWLOG is useful 告诉我我的脚本很慢,以及它们到底有多慢,但这不是我的问题。我知道它们有多慢,我想弄清楚它们的哪些部分是慢的。

The redis EVAL docs 很清楚,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

【问题讨论】:

标签: lua redis profiling


【解决方案1】:

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

count 钩子:在解释器执行每个 计数指令。 (此事件仅在 Lua 执行 Lua 函数。)

您必须根据在回调中收到的计数构建分析器。

PepperfishProfiler 将是一个很好的起点。它使用您没有的os.clock,但您可以只使用钩子计数来进行非常粗略的近似。

PiL 23.3 – Profiles 也涵盖了这一点

【讨论】:

  • 这让我走上了正确的道路——至少在我认为能够满足 Redis 要求的限制的情况下如此接近。我将使用我想出的分析挂钩来编辑我的问题。谢谢!
【解决方案2】:

在标准 Lua C 中,你不能。它不是一个内置函数——它只返回秒。因此,有两种选择:您可以编写自己的 Lua 扩展 DLL 以返回以毫秒为单位的时间,或者:

您可以使用毫秒分辨率的时间进行基本基准测试。您可以使用 LuaSocket 访问当前毫秒时间。尽管这会为您的项目增加一个依赖项,但它是进行简单基准测试的有效方法。

require "socket"
t = socket.gettime();

【讨论】:

  • Lua 脚本在 Redis 服务器中运行。我可以使用的唯一库是:base、table、string、math、debug、cjson 和 cmsgpack。
  • 啊。我能想到的唯一方法是手动添加库。它是开源的。不过,这会很痛苦。我很惊讶你不能添加自己的库。
  • 计时函数的限制是有目的的——你甚至不能调用内置的时间函数,因为这会破坏 redis-cluster 实现所需的确定性执行的保证。
  • 您可以将自己的库作为 DLL 形式的 Lua 插件附加吗?
  • 我必须重新编译 Redis 并静态链接它们——这不是不可能的,但我想先看看是否有一个简单的按钮......
猜你喜欢
  • 2021-08-30
  • 2023-03-12
  • 1970-01-01
  • 2017-11-24
  • 2016-08-10
  • 2013-05-17
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
相关资源
最近更新 更多