【问题标题】:Redis in action - unfair semaphoreRedis 在行动 - 不公平的信号量
【发布时间】:2018-07-30 14:04:11
【问题描述】:

我正在阅读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 将删除过期的项目并添加其自身。 B怎么能stealA的信号量?同时,如果A的时间是10:59,B的时间是11:02,那么B因为时差可以去掉A的信号量是可能的。但这不是书中描述的情况。

【问题讨论】:

    标签: redis semaphore


    【解决方案1】:

    如果 B 比 A 慢 10 毫秒,那么 B 的分数小于 A,因为我们使用本地时间作为排序集的分数。

    所以 B 的等级,即pipeline.zrank(semname, identifier),小于 A 的等级,它小于 limit,即if pipeline.execute()[-1] &lt; limit:。 B 认为它得到了信号量,即return identifier。事实上,它窃取来自 A 的信号量。

    【讨论】:

    • 啊,我怎么错过了?!你成就了我的一天
    猜你喜欢
    • 2011-12-30
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多