【问题标题】:Optimizing Redis Lua script calls to redis.call优化 Redis Lua 脚本对 redis.call 的调用
【发布时间】:2021-04-15 20:18:28
【问题描述】:

根据这个 Lua 优化文档:https://www.lua.org/gems/sample.pdf

对外部局部变量的访问(即,对于一个 封闭函数)不如访问局部变量快,但是 它仍然比访问全局变量要快。考虑下一个片段:

function foo (x)
  for i = 1, 1000000 do
    x = x + math.sin(i)
  end
  return x
end
print(foo(10))

我们可以通过在函数 foo:local 之外声明一次 sin 来优化它

sin = math.sin
function foo (x)
  for i = 1, 1000000 do
    x = x + sin(i)
  end
  return x
end
print(foo(10))

redis.call 是一个全局吗?我们可以通过定义一个指向它的局部变量来优化它吗?特别是对于多次调用redis.call 的紧密循环。

后续还有KEYSARGV 也是globals

【问题讨论】:

    标签: redis lua


    【解决方案1】:

    redis.call 是全局的吗?

    作为后续,KEYS 和 ARGV 也是全局变量吗?

    是的,redisKEYSARGV 是全局变量。

    我们可以通过删除一个指向它的局部变量来优化它吗?特别是对于多次调用 redis.call 的紧密循环。

    根据您的参考,您似乎可以使用本地变量优化 Lua 代码。但是,通常你不应该在 Lua 脚本中运行太多的操作,例如运行一个大循环并执行许多 redis 命令。因为 Redis 是单线程的,如果 Lua 脚本占用太多时间,就会阻塞 Redis。

    通常,我想将 KEYS 和 ARGV 数组中的元素分配给本地变量。不是为了效率,而是为了代码清晰。

    【讨论】:

    • 执行大约 800 次的循环是否会被认为太大。我通过降低慢日志阈值来检查每个脚本执行的时间,每次执行最多大约 2 到 3 毫秒 - 而不是微秒。这通常会变慢吗?
    • 是的,它很慢。通常,包括网络内容在内的执行应在微秒内完成。
    【解决方案2】:

    所以下面三个Redis命令都执行成功了。

    1. eval "return _G.redis.call('set', 'x', 1)" 0

    2. eval "return _G.KEYS" 1 1

    3. eval "return _G.ARGV" 0 1

    所以我猜他们都是全局变量。如果我错了,请有人纠正我...

    【讨论】:

      猜你喜欢
      • 2013-09-29
      • 2017-06-26
      • 2012-09-20
      • 1970-01-01
      • 2021-10-27
      • 2014-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多