redis: EVAL and the TIME



我喜欢redis的Lua脚本,但我对TIME有很大的问题。

我将事件存储在SortedSet中

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

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

好的,但这不起作用-我无法访问TIME(Servertime)。

有没有什么方法可以在不将时间作为参数传递给我的lua脚本的情况下从服务器获取时间?还是把时间当作争论来打发是最好的方式?

这是明确禁止的(据我记忆所及)。这背后的原因是,lua函数必须是确定性的,并且只依赖于它们的参数。如果这个Lua调用被复制到一个具有不同系统时间的从机上,该怎么办?

编辑(作者:Linus G Thiel):这是正确的。来自redis EVAL文档:

作为纯函数的脚本

脚本的一个非常重要的部分是编写纯函数的脚本。Redis实例中执行的脚本是通过发送脚本而不是生成的命令在从属服务器上复制的。

[…]

为了在脚本中强制执行此行为,Redis执行以下操作:

  • Lua不导出访问系统时间或其他外部状态的命令
  • 如果一个脚本调用一个Redis命令,该命令能够在RANDOMKEY、SRANDMEMBER、TIME等Redis随机命令之后更改数据集,Redis将以错误的方式阻止该脚本。这意味着,如果脚本是只读的并且不修改数据集,则可以自由调用这些命令。请注意,随机命令并不一定意味着使用随机数的命令:任何不确定的命令都被认为是随机命令(在这方面最好的例子是TIME命令)

关于为什么会出现这种情况,如何在不同的场景中处理这种情况,以及脚本可以使用哪些Lua库,有很多信息。我建议您阅读整个文档!

最新更新