2

我有一个要在 Redis 中运行的小型 Lua 脚本,我对获取执行时间很感兴趣。

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

我已经四处寻找我可以进行的函数/调用,它将返回上次运行脚本的执行时间,但还没有找到任何东西。

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

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

4

4 回答 4

4

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

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

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

于 2012-11-05T16:15:56.333 回答
2

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

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

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
}
于 2014-03-18T12:04:13.510 回答
0

编辑: rld 已过时。

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

于 2015-04-07T14:43:52.433 回答
0

从 Redis v3.2 开始,您可以选择通过调用新API来复制命令而不是脚本。这将允许您在不触发非确定性错误的情况下redis.replicate_commands()调用执行写入操作的脚本。TIME

于 2016-02-05T13:29:41.053 回答