Redis在行动-不公平的信号量

时间:2018-07-30 14:04:11

标签: redis semaphore

我正在阅读Redis in action e-book关于semaphores的一章。这是使用redis实现信号量的python代码

def acquire_semaphore(conn, semname, limit, timeout=10):
   identifier = str(uuid.uuid4())

   now = time.time()

   pipeline = conn.pipeline(True)
   pipeline.zremrangebyscore(semname, '-inf', now - timeout)

   pipeline.zadd(semname, identifier, now)

   pipeline.zrank(semname, identifier)
   if pipeline.execute()[-1] < limit:

      return identifier

   conn.zrem(semname, identifier)

   return None
  

此基本信号灯效果很好-很简单,而且非常快。但   依赖于每个进程可以访问相同的系统时间   如果有多个,获取信号量可能会导致问题   主机。对于我们的特定用例来说,这不是一个大问题,但是如果我们   有两个系统A和B,其中A的运行速度比10毫秒还要快   B,如果A得到了最后一个信号量,而B试图得到一个信号量   在10毫秒内,B实际上会“窃取” A的信号量而没有   一个了解。

我没有听懂这是什么意思:如果A ran even 10 milliseconds faster than B然后B would actually “steal” A’s semaphore without A knowing it.

我的想法:A的时间为10:10:10:200,B的时间为10:10:10:190,A得到了信号量。然后,B尝试在10毫秒内获取信号量(现在B的本地时间为10:10:10:200)。 B将删除过期的项目并添加其。 steal A的信号灯如何B?同时,如果A的时间为10:59,而B的时间为11:02,则B可能会由于时差而删除A的信号量。但这不是本书中描述的情况。

1 个答案:

答案 0 :(得分:0)

如果B的运行速度比A慢10毫秒,则B的得分小于A,因为我们使用本地时间作为排序集的得分。

因此,B的等级,即pipeline.zrank(semname, identifier)小于A的等级,其等级小于limit,即if pipeline.execute()[-1] < limit:。 B认为它得到了信号量,即return identifier。实际上,它从窃取了信号量。