如何确定Redis中Lua脚本的执行时间?

时间:2012-11-05 12:00:18

标签: time lua redis execution

我有一个小的Lua脚本可以在Redis中运行,我有兴趣获得执行时间。

由于Redis的性质和它的Lua实现,我不能在脚本的开始/返回点使用TIME函数,并在返回中包含此信息以进行处理(参见http://redis.io/commands/eval - Scripts as pure功能)。这会导致错误:(error) ERR Error running script (call to f_a49ed2fea72f1f529843d6024d1515e76e69bcbd): Write commands not allowed after non deterministic commands

我已经四处搜索了我可以制作的函数/调用,它将返回上次运行脚本的执行时间,但还没有找到任何内容。

我正在使用PHP和Predis库。虽然我可以从PHP端检查执行时间,但我希望删除传输开销并找出Lua脚本阻止访问数据库的时间。如果我不需要更改存储在Redis中的任何数据,我已经成功地返回了时间,这些时间大约是PHP报告时间的十分之一。

如何在Redis中确定Lua脚本的执行时间,而不是通过PHP?

4 个答案:

答案 0 :(得分:4)

您可以通过将slowlog-log-slow-than参数更改为0来激活Redis慢速日志功能。它将记录所有命令的执行时间(包括Lua脚本,以及执行时间)。

慢速日志保存在内存队列中,您必须定期转储以收集数据。根据流量的大小,您可能需要增加slowlog-max-len以确保捕获您感兴趣的执行时间。

您可以使用slowlog get command转储慢速日志。由你来过滤掉你不需要的结果。 AFAIK,不可能在数据收集时过滤(仅保留Lua统计数据)。

答案 1 :(得分:2)

如果在构建Redis时启用os模块,则可以在脚本内部使用os.clock()。

https://github.com/antirez/redis/blob/unstable/src/scripting.c的第484行将#if 0更改为#if 1

void luaLoadLibraries(lua_State *lua) {
    luaLoadLib(lua, "", luaopen_base);
    luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);
    luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);
    luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);
    luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug); 
    luaLoadLib(lua, "cjson", luaopen_cjson);
    luaLoadLib(lua, "struct", luaopen_struct);
    luaLoadLib(lua, "cmsgpack", luaopen_cmsgpack);

#if 0 /* Stuff that we don't load currently, for sandboxing concerns. */
    luaLoadLib(lua, LUA_LOADLIBNAME, luaopen_package);
    luaLoadLib(lua, LUA_OSLIBNAME, luaopen_os);
#endif
}

答案 2 :(得分:0)

编辑:rld已过时。

您可以使用rld(https://github.com/RedisLabs/redis-lua-debugger)并将其打印到日志中 - 日志具有计时信息(尽管rld会导致脚本运行速度变慢,自然而然)。

答案 3 :(得分:0)

从Redis v3.2开始,您可以通过调用新的 [HttpPost] public ActionResult Footer(EmailModel model) { return PartialView("~/Views/Shared/_Footer.cshtml"); } API选择replicate commands instead of scripts。除此之外,这将允许您在执行写入操作的脚本中调用redis.replicate_commands(),而不会触发非确定性错误。