【问题标题】:Conditional Work Queue Insertion for beanstalkd?beantalkd 的条件工作队列插入?
【发布时间】:2009-12-23 20:19:51
【问题描述】:

我正在使用 beanstalkd 的 Perl 客户端。我需要一种简单的方法来避免将相同的工作排入队列两次。

我需要的东西基本上需要等到有 K 个元素,然后将它们组合在一起。为此,我有制作人:

insert item(s) into DB
insert a queue item into beanstalkd

消费者:

while ( 1 ) {
   beanstalkd.retrieve
   if ( DB items >= K )
       func_to_process_all_items
   kill job
}

这与请求/处理的数量呈线性关系,但在以下情况下:

insert 1 item
... repeat many times ...
insert 1 item

假设所有这些插入发生在检索作业之前,这将添加 N 个队列项,它会执行以下操作:

check DB, process N items
check DB, no items
... many times ...
check DB, no items

有没有更聪明的方法来做到这一点,这样它就不会不必要地插入/处理以后的作业请求?

【问题讨论】:

    标签: perl algorithm beanstalkd


    【解决方案1】:

    我有一个相关的要求。我只想在几分钟内处理一次特定的作业,但生产者可以将同一作业的多个实例排队。我使用 memcache 存储作业标识符并将密钥的到期时间设置为几分钟。

    当工作人员尝试将作业标识符添加到内存缓存时,只有第一个会成功 - 如果添加作业 ID 失败,工作人员将删除该作业。几分钟后,密钥从 memcache 中过期,可以再次处理作业。

    不是特别优雅,但它确实有效。

    【讨论】:

      【解决方案2】:

      这对你有用吗?:

      1. 创建两个 Tubes“buffer”和“live”。您的制作人始终只添加到“缓冲”管中。
      2. 创建两个工作人员,一个监视“缓冲区”,另一个监视调用阻塞 reserve() 调用的“实时”
      3. 每当“缓冲”工作人员返回保留位置时,如果少于 K 个项目,它就会埋葬该工作。如果正好有 K 个,那么它会“踢”所有 K 个工作并将它们转移到“实时”管中。
      4. “实时”观察者现在将自行返回reserve()

      您只需要注意作业不会从隐藏状态返回到缓冲区队列。执行此操作的故障安全方法可能是删除它,然后将其添加到实时状态。

      两个单独的队列仅用于更清晰的分离。您可以对单个队列执行相同的操作,方法是埋葬所有作业,直到有 K-1 个作业,然后在第 K 个作业到达时,将所有作业踢活。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-25
        • 1970-01-01
        • 2018-06-20
        • 1970-01-01
        相关资源
        最近更新 更多