Redis:以原子方式将随机成员从一组移动到另一组

标签 redis

SRANDMEMBER 返回集合中的随机成员。 SPOP 从集合中随机删除一个成员。 SMOVE 将指定成员从一个集合移动到另一个集合。

如何一次性将随机成员从一个集合移动到另一个集合? 我不想解雇 SRANDMEMBER,等待其结果,然后调用 SMOVE。

我尝试使用 EVAL 脚本,但它不能与 SRANDMEMBER 一起使用,发出“在非确定性命令后不允许写入命令”。

该操作必须是 O(1) 且原子的。

最佳答案

Redis v3.2 之前的版本

Redis 可以防止 Lua 脚本内的随机写入,这样复制就不会被破坏(脚本也在从属服务器上进行评估)。也就是说,这是一个伪随机解决方案:

local t = redis.call("SMEMBERS", KEYS[1])
local n = redis.call("SCARD", KEYS[1])
local r = math.random(1, n+1)
redis.call("SMOVE", KEYS[1], KEYS[2], t[r])
return t[r]

注释:

  1. 伪随机 - Redis 确保对随机的调用实际上是确定性的
  2. 集合大小 - 由于会获取集合的所有成员,因此您应该小心不要在较大的集合上运行它。

v3.2 及更高版本

从 3.2 开始,您可以通过先验调用 replicate_commands() 来更加随机。

关于Redis:以原子方式将随机成员从一组移动到另一组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27132901/

相关文章:

c# - Redis Optimization with .NET,以及如何从 Hash 存储和获取元素的具体示例

redis - 我可以为 redis zset 定义自定义比较函数吗?

php - 云服务器需要向 Router 后面的客户端推送消息

caching - 我的缓存守护进程应该驻留在哪里?

node.js - 在 Node 中使用redis获取哈希键的所有字段和值

redis - 在管道中发送多个redis write命令时,是否需要读取返回值?

nosql - Redis、CouchDB 还是 Cassandra?

Redis Booksleeve,临时设置

heroku - Resque失去与heroku上redis的连接

python - 使用 python-rq 在远程服务器上执行长任务