Redis Lua 脚本 math.random

Eri*_*rik 4 random lua redis

我刚刚在 Redis 中发现了 Lua 环境的一个有趣的行为:

我有一个 Lua 脚本,执行一些简单的设置操作,并在脚本末尾生成像 id 这样的唯一时间戳 - 将 Redis 用作时间戳预言机 - 像这样:

...
local time = redis.call('TIME')
local millis = (tonumber(time[1]) * 1000) + math.floor(tonumber(time[2]) / 1000)
local version = string.format("%.0f",mills) .. string.format("%05d", math.random(99999))
Run Code Online (Sandbox Code Playgroud)

现在version是这样的:145209287564117083由一个时间戳和末尾的五个随机数字组成 - 至少我是这么想的。

实际发生的情况是,末尾的五个随机数字(由 生成)math.random(99999)根本不是随机的,而是始终是数字17083,无论脚本执行的频率如何。

对我来说这不是什么大问题(因为我可以在脚本返回后附加随机数字),但我没想到会出现这种行为,因此需要相当长的时间来找到我的错误。

我希望这些信息可以节省一些时间。

And*_*ght 5

如果您正在调用 lua 脚本,最好的办法是将时间作为脚本参数传递。这可以让你完全避免 redis.call("TIME") ,然后你可以用当前时间设置种子。

local time = ARGV[1];
math.randomseed(time);
local millis = (tonumber(time[1]) * 1000) + math.floor(tonumber(time[2]) / 1000)
local version = string.format("%.0f",mills) .. string.format("%05d", math.random(99999))
Run Code Online (Sandbox Code Playgroud)

这也避免了将来出现复制问题,因为所有实例都将接收相同的参数并生成相同的输出。

  • 虽然OP实际上并没有提出问题,但我认为这是“我应该如何在redis lua脚本中生成伪随机数?”这个问题的最佳答案。 (3认同)