Redis 模式:你将如何缓存过期的空闲/占用资源?

Redis pattern: how would you cache free / occupied ressource with expiration?

这是我这周正在处理的问题,我有点碰壁了。

假设我有 100 个资源可用于完成一些快速任务。

我想为客户做的,尽可能快:

  1. 获取第一个可用资源
  2. 将其标记为已占用
  3. 使用它
  4. 将其标记为免费。 对于这种东西,我觉得使用sorted set是最好的。

但是因为我的客户端不是很安全并且有时会在它运行的代码中间失败我真的想在我将资源标记为已占用时设置过期时间这样资源就不能永远处于占用状态.

这听起来像是一个非常普遍的问题,我敢肯定有很多关于如何使用 Redis 修复它的文献,但我找不到任何文献。

我发现了很多 "Maintaining a global leaderboard" 类问题的模式和示例,但是 none 这些示例处理了密钥过期。

我目前有这样的解决方案:

for ressource in ressources:
    if GET <ressource> == 0:
        SET <ressource> 1, EX=10
        use_ressource(<ressource>)
        SET <ressource> 0, EX=10
    else:
        continue

事实是,一旦我使用了大量资源,这可能需要大量操作才能找到第一个空闲资源,尽管 Redis 非常快,但此代码段的扩展性不佳。

超出我的想象:

  • 维护一组免费资源
  • 维护一组已用资源
  • expired事件通知上设置keyspace listener

需要资源时,随机select一个SRANDMEMBER and move it to the in-use resources set with SMOVE. In this same transaction, set up a simple expire key with a good prefix, the name/type of the resource, and required TTL with SETEX

设置一个 redis keyspace notification consumer(仍然是新的,但是查看他们的最新技术 Redis Gears 以获得超级简化的版本!)监听您分配的前缀的 expired 事件.当这些事件之一发生时,运行 与上述相同的 SMOVE 逻辑,只是将资源移回空闲资源集中。

关于实际资源本身,当它们完成时,让它们 self-expire 它们的跟踪键和通知消费者可以处理状态刷新:)

这应该可以为您提供所需的灵活性!


这里有类似的问题,一些答案可能有用:How to "EXPIRE" the "HSET" child key in redis?