2

我需要用独特的元素在 Redis 中实现队列。 目前,我正在使用 Redis List 来实现 Queue (LPUSH, RPOP) 和 Redis Sortedset/set 来实现唯一性。

`  
def push(key):
    if redis_cache.zadd('UNIQUE', key, 1):
        redis_cache.lpush('QUEUE', key)
    else:
       print "Key Exist"
`
`
def pop():
    key = redis_cache.rpop('QUEUE')
    redis_cache.zrem('UNIQUE', key)
    return key
`

Redis 缓存服务器使用更多 CPU 的密钥负载/请求较高。以及上述方法占用更多内存(在 List 和 Sortedset 中排序相同的键) 是否有任何其他方法可以实现具有键唯一性的 Redis 队列

4

3 回答 3

3

我实际上会考虑使用单个排序集,将分数设置为时间戳并使用ZADD“NX”标志。这将提供排序和唯一性。

于 2019-11-15T16:43:56.597 回答
1

首先,您应该使用Set, 而不是Sorted Set检查密钥是否已经存在。Sorted Set使用比 更多的内存Set

其次,您的代码不是原子的。如果要使其原子化,则需要使用 Lua 脚本或事务。

有没有其他方法来实现具有键唯一性的 Redis 队列?

随机订单队列

如果您不关心队列的顺序,即不需要 FIFO,则可以使用Set不带 a的单个List来实现具有随机出序的队列。此解决方案将节省更多内存,而且速度更快,因为它只需要向 Redis 发送一个命令。

// in queue
SADD UNIQUE key

// out queue, pop a random member.
SPOP UNIQUE
于 2019-11-15T08:29:29.740 回答
0

根据这个答案,您必须在进行多个操作 - 时间成本(如果在删除过程中找到,则删除然后再次添加)或维护一个单独的集合 - 内存成本(您的方法)之间进行选择。LREM 是 O(N),其中 N 是列表的长度,但一个元素的 SREM 复杂度是 O(1),因为 N 是要删除的成员数。SISMEMBER 总是 O(1)。

于 2019-11-15T07:58:24.993 回答