当太多作业待处理时,Ruby、DelayedJob 会变慢

标签 ruby delayed-job

当表 delayed_jobs 开始增长到数百个以上时,工作人员的性能开始呈指数下降。

最佳答案

我已经多次被这个问题困扰,所以我将我的发现公开给 future 的新手来面对这个噩梦。

DelayedJobs 项目中存在与此问题相关的几个问题:

问题出在 avery Worker run 中使用的 DelayedJob 查询中:

UPDATE `delayed_jobs` SET `locked_at` = '2014-04-17 22:32:20', `locked_by` = 'host:b38f770a-f3f3-4b2a-8c66-7c8eebdb7fea pid:2' WHERE ((run_at <= '2014-04-17 22:32:20' AND (locked_at IS NULL OR locked_at < '2014-04-17 18:32:20') OR locked_by = 'host:b38f770a-f3f3-4b2a-8c66-7c8eebdb7fea pid:2') AND failed_at IS NULL) ORDER BY priority ASC, run_at ASC LIMIT 1

在我的例子中,对于少于 1000 个作业,可能需要近 1 秒的时间......并且随着更多作业待处理而呈指数增长。

我找到的唯一解决方案是 this blog 中公开的解决方案,简而言之:由于问题是初始查询缺乏合适的索引,解决方案是批量拆分表:

-- stop workers
select max(id) from delayed_jobs; -- -> 10010
create table delayed_jobs_backup like delayed_jobs;
insert into delayed_jobs_backup select * from delayed_jobs where id < 10010;
delete from delayed_jobs where id < 10010;
-- start workers
-- while jobs in delayed_jobs_backup do
  -- wait until the batch have been processed
  insert into delayed_jobs select * from delayed_jobs_backup limit 1000;
  delete from delayed_jobs_backup limit 1000;
-- end

关于当太多作业待处理时,Ruby、DelayedJob 会变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40360455/

相关文章:

ruby - Date 与 nil 的比较失败 - ruby

ruby-on-rails - 使用 delay_job 的 ActiveJob 不会在测试中创建 delay_jobs 行

ruby-on-rails - 如何查询delay_job处理程序

ruby - ruby 异常如何导致 mutices 解锁?

ruby - 我可以在方法签名中指定鸭子类型吗?

sql - 导致 cpu 达到 100% 的 PostgreSQL 查询。给定 90k 条记录,成本为 7000 可以吗?

ruby-on-rails - 如何使延迟的工作依赖于另一项工作?

ruby-on-rails - 延迟作业到 sidekiq : Reset password email not working

ruby - Sinatra 的良好表单助手?

javascript - 在javascript中追加ruby部分,并传递一个rails变量