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]
注释:
- 伪随机 - Redis 确保对随机的调用实际上是确定性的
- 集合大小 - 由于会获取集合的所有成员,因此您应该小心不要在较大的集合上运行它。
v3.2 及更高版本
从 3.2 开始,您可以通过先验调用 replicate_commands()
来更加随机。
关于Redis:以原子方式将随机成员从一组移动到另一组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27132901/