【问题标题】:Multi-tenant resque, and avoiding one tenant clogging the queue多租户resque,避免一个租户阻塞队列
【发布时间】:2016-02-15 22:56:28
【问题描述】:

我们有一个运行resque 用于后台处理的多租户应用程序。

我们偶尔会遇到的问题是单个租户在很短的时间内执行大量的后台工作。这基本上会阻塞队列一段时间——当我们处理这个单一租户的积压工作时,所有其他租户的工作都会被延迟。

是的,我们可以添加更多工人。但这并不是真正的“解决方案”,它更像是一种创可贴,仍然会导致其他租户的延迟——只是随着我们处理速度更快而延迟更短。

是否有更多多租户友好的方式来使用resque?还是完全对多租户友好的后台队列?

我们正在研究:

  • 每个租户使用一个队列,每个租户一个工作人员(动态创建的队列?)
  • 修改 resque 使其以某种方式轮询每个租户的队列

我们只是想知道我们是否缺少一些东西/更好的方法......

【问题讨论】:

    标签: redis background-process resque php-resque


    【解决方案1】:

    您可以使用 Rails.cache 为每个参与者维护临时作业计数器,并根据活动作业的数量将作业分配到不同的队列。

    您需要对作业进行子类化以支持不同的队列,并编写一个方法来解析为作业的正确类。比如:

    class Worker
    
       cattr_acessor :tenant_id
    
       class Worker::Low < Worker
         @queue = :low
       end
    
       class Worker::High < Worker
         @queue = :high
       end
    
       def self.queued
          "#{name}::#{resolved_queue(tenant_id)}".constantize
       end
    
       def self.resolved_queue tenant_id
         count = job_count(tenant_id)
         if count > 1000
           'Low'
         else
           'High'
         end
       end
    
       def self.cache_key tenant_id
         "job_count/#{tenant_id}"
       end
    
       def self.job_count tenant_id
         Rails.cache.fetch(cache_key(tenant_id)){0}
       end
    
       def self.job_count_increment tenant_id
         Rails.cache.fetch(cache_key(tenant_id)){0}
         Rails.increment(cache_key(tenant_id)){0}
       end
    
       def self.job_count_decrement tenant_id
         count = Rails.cache.fetch(cache_key(tenant_id)){0}
         Rails.decrement(cache_key(tenant_id)){0} if count > 0
       end
    end
    

    然后在运行工作程序时调用Worker.queued(tenant_id).perform,并确保在应用程序中将Worker.tenant_id 设置为before_filters。有关队列和优先级的更多信息,请参阅Resque Priorities and Queue Lists

    您应该在作业队列上调用增量并从作业内调用减量。

    丑陋,但可行。

    并且可以通过一些元编程使其更加枯燥 - 将这些方法提取到一个模块中,然后确保在模块包含上生成队列子类。

    【讨论】:

    • 唯一的问题是它可能会将事物无序地推入队列,对吗?因此,如果有人超过了 1000 的限制,那么我们就开始将东西推入低队列。但是一旦它处理到 999 级别,我们就开始再次将内容推入中等队列。因此,我们可能会有在初始大批量之后执行的东西,但在大批量结束之前得到处理。对吗?
    • 可能是,但不太可能,因为中等的最后一个作业可能会在低速的第一个作业之后处理
    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-11-23
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多