3

我使用线性同余生成器 ( http://en.wikipedia.org/wiki/Linear_congruential_generator ) 来生成暴露给用户的 ID。

nextID = (a * LastID + c) % m

现在我想在 Redis 中实现 LCG。这就是问题所在:获取当前 ID 并在 Redis 外部生成下一个 ID 不是多用户安全的。Redis 有 2 个可用于简单计数器的命令:INCRBY 和 INCRBYFLOAT,但不幸的是,Redis 本身不支持模运算。目前我看到的唯一方法是使用 EVAL 命令并编写一些 lua 脚本。

更新1:

一些lua类似物

INCRBY LCG_Value ((LCG_Value*a+c)%m)-LCG_Value

似乎是实现这一目标的一种巧妙方法。

4

1 回答 1

3

服务器端 Lua 脚本可能是最简单、更有效的方法。

现在它也可以通过使用 multi/exec 块的 Redis 原始操作来完成。这是伪代码:

while not successful:
   WATCH LCG_Value
      $LastID = GET LCG_value
      $NextID = (a*$LastID+c)%m
   MULTI
      SET LCG_value $NextID
   EXEC

当然,它的效率低于以下 Lua 脚本:

# Set the initial value
SET LCG_value 1

# Execute Lua script with on LCG_value with a, c, and m parameters
EVAL "local last = tonumber(redis.call( 'GET', KEYS[1]));
      local ret = (last*ARGV[1] + ARGV[2])%ARGV[3];
      redis.call('SET',KEYS[1], ret);
      return ret;
" 1 LCG_value 1103515245 12345 2147483648

注意:整个脚本执行是原子的。请参阅评估文档。

于 2013-06-11T06:59:44.720 回答