【问题标题】:Implementing Queue with unique elements in Redis在 Redis 中实现具有唯一元素的队列
【发布时间】:2020-03-11 07:55:27
【问题描述】:

我需要用独特的元素在 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 队列

【问题讨论】:

    标签: redis amazon-elasticache redis-cache


    【解决方案1】:

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

    【讨论】:

    • 好主意!虽然顺序不是很准确(在同一秒或毫秒内添加的项目是按键排序的),并且客户端可能会作弊(通过指定以前的时间戳),但在大多数情况下,这应该是一个很好的解决方案。
    • 这是个好主意。我认为我的问题将通过这个解决方案得到解决。谢谢。
    • 使用时间戳作为score 有两个问题:1) 时间可能会倒退(例如,由于 NTP 漂移)。 2)如果ZADDs 彼此靠近,您可能会得到相同的时间戳 - 然后排序将是字典顺序,这可能不是您想要的
    【解决方案2】:

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

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

    还有没有其他方法可以实现键唯一的 Redis Queue?

    随机排序队列

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

    // in queue
    SADD UNIQUE key
    
    // out queue, pop a random member.
    SPOP UNIQUE
    

    【讨论】:

    • 是的,pop 操作中存在竞争条件。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-20
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 2011-07-11
      相关资源
      最近更新 更多