当我同时运行zadd时如何限制有序集的最大长度?

时间:2014-11-26 08:54:59

标签: concurrency redis

我想使用redis来存储这样的数据:{id: timestamp(1416991171)}在一个有序集合中,并且它需要有一个最大长度。

我在插入一个新的成员/值对之前只检查有序集的长度。但是我不确定这是否是一个好主意,以确保最大长度,因为我将同时运行它。

代码是这样的(在ruby中):

key = "list"
max = 5
if $redis.zcard(key) < max
  $redis.zadd(key, Time.now.to_i, "foo")
end

如何确保最大长度?提前谢谢。

1 个答案:

答案 0 :(得分:2)

注意:当您使用key两次时,您的问题似乎有错字 - 一次是有序集,一次是您的标识符。我在回复中将标识符称为keyx

您有两种方法可以确保您的排序集不会超过max,即使用Redis&#39; transactionsserver-side Lua scripts。这两种方法都将确保工作流程的原子性(尽管个人而言,我更喜欢后者)。

使用事务方法,您可能会执行类似以下伪Ruby代码的操作:

key = "list"
max = 5
$redis.watch key
if $redis.zcard(key) < max
  $redis.multi
  $redis.zadd(key, Time.now.to_i, "foo")
  $redis.exec
else
  $redis.unwatch key
end

或者,使用脚本:

key = "list"
max = 5
s = <<EOF
if redis.call('ZCARD', KEYS[1]) < ARGV[1] then
   redis.call('ZADD', KEYS[1], ARGV[2], ARGV[3])
end
EOF
$redis.eval s, 1, key, max, Time.now.to_i, "foo"