redis:EVAL 和 TIME EVAL命令允许在Redis服务器上执行Lua脚本,并在同一原子操作中读取和写入数据。此外,TIME命令用于检索服务器的当前时间戳。这些命令可帮助实现更复杂的、跨多个Redis命令的操作。

我喜欢使用 Lua 脚本编写 Redis,但是我在处理时间方面遇到了一个大问题。

我将事件存储在 SortedSet 中。

分数就是时间,这样在我的应用程序中,我可以在给定的时间窗口内查看所有事件。

redis.call('zadd', myEventsSet, TIME, EventID);

好的,但是这行不通——我无法访问时间(服务器时间)。

有没有办法在不将时间作为参数传递给我的 Lua 脚本的情况下从服务器获取时间?还是将时间作为参数传递是最好的方法?

点赞
用户125816
用户125816

这是明确禁止的(据我所记)。这背后的推理是你的 Lua 函数必须是确定性函数,并且仅仅依赖于它们的参数。假如这个 Lua 调用被复制到系统时间不同的从服务器上,那么会发生什么呢?

编辑(由 Linus G Thiel 提供): 这是正确的。参见 Redis EVAL 文档:

把脚本看作纯函数

脚本是一种非常重要的工具,能够执行 Redis 支持的大多数 Redis 命令集。但是脚本能够做到的比任何一种 Redis 命令集都更强大,通过使用编程语言 Lua 能够快速地编写复杂的数据处理逻辑或业务逻辑。

完整的 Redis 命令集在脚本语言 Lua 中并不全都可用。

执行在 Redis 实例中的脚本会通过发送脚本而不是发送指令的方式复制给从服务器。

[...]

为了在 Redis 中让脚本的行为像纯函数一样,Redis 执行如下行为:

  • Lua 并没有出口可以访问系统时间和其他外在状态的命令。
  • 如果一个脚本调用了 Redis 命令,能够在 Redis 随机命令(RANDOMKEY、SRANDMEMBER、TIME)之后改变数据集的结构,那么 Redis 会以错误方式阻塞该脚本。这意味着,如果脚本是只读的,并且不修改数据集,那么它可以调用那些命令。需要注意的是,随机命令并不一定意味着使用了随机数的命令:任何非确定性命令都视为随机命令(在这方面最佳的例子是 TIME 命令)。

有大量信息可用于解释这个问题在不同场景下的处理方式,以及有哪些 Lua 库可用于脚本。我们建议你阅读整个文档!

2012-09-03 09:07:49