如何获得我的 sidekiq 工人的限制?

时间:2021-04-05 08:54:47

标签: ruby-on-rails sidekiq

我的数据库中有 200000 个用户

我需要遍历每条记录来处理一些事情。

所以我有一个 rake 任务来迭代每个用户,主要逻辑将在一个工人中。现在我想获得可以同时运行的工人的限制。如果限制是 50000,那么我可以将我的用户分成 4 个集合,对于每个集合,我将分别调用 Worker。

任务:

namespace :users do
  task data: :environment do
   confirmed_users = User.where('confirmed_at IS NOT NULL').where('id <= 50000')
   confirmed_users.each do |user|
     MyWorker.perform_async(user.id)
   end#confirmed_users.each do |user|

   confirmed_users = User.where('confirmed_at IS NOT NULL').where('id > 50000 and id <= 100000')
   confirmed_users.each do |user|
     MyWorker.perform_async(user.id)
   end#confirmed_users.each do |user|

   confirmed_users = User.where('confirmed_at IS NOT NULL').where('id > 100000 and id <= 150000')
   confirmed_users.each do |user|
     MyWorker.perform_async(user.id)
   end#confirmed_users.each do |user|

   confirmed_users = User.where('confirmed_at IS NOT NULL').where('id > 200000')
   confirmed_users.each do |user|
     MyWorker.perform_async(user.id)
   end#confirmed_users.each do |user|

 end
end

如果我能知道sidekiq的限制,我就可以让用户动态设置。我想知道这是在更短的时间内完成流程的正确方法。或者有什么方法可以在更短的时间内处理我的所有记录?

1 个答案:

答案 0 :(得分:1)

Sidekiq 只能同时处理与工作线程/线程一样多的作业。其余的将被放置在队列中,队列实际上是无限的。 20 万个工作没有问题。

您的问题可能来自使用 1 个 sql 查询查询 20 万个作业的速度缓慢,并且在从中创建作业时必须将结果保存在内存中。

使用 find_each 告诉 Rails 批量查找记录并一一产生。

namespace :users do
  task data: :environment do
    User.where('confirmed_at IS NOT NULL').find_each do |user|
      MyWorker.perform_async(user.id)
    end
  end
end

但是,由于您只需要 id,而不是整个用户对象,我们也可以删除对象启动以加快速度。

User.where('confirmed_at IS NOT NULL').in_batches.each do |batch|
  batch.pluck(:id).each do |id|
    MyWorker.perform_async(user.id)
  end
end

如果这还不够快,还有 Sidekiq::Client.push_bulk。它只会为每一批次向 redis 发出一个请求。可能需要在此处调整批量大小。

User.where('confirmed_at IS NOT NULL').in_batches.each do |batch|
  args = batch.pluck(:id).map { |id| [id] } # args is [[1], [2], [3], etc...]
  Sidekiq::Client.push_bulk('class' => MyWorker, 'args' => args)
end
相关问题