繁体   English   中英

后台作业需要两倍于rails内相同操作的时间

[英]Background job taking twice the time that the same operation within rails

在我的Rails应用程序中,我有一个很长的计算需要大量的数据库访问。

为了缩短它,我的计算耗时25秒。

在后台作业(一个大的单个工作者)中实现相同的计算时,相同的计算需要两倍的相同时间(即50秒)。 我已经尝试了几种技术来将工作放在后台进程中,没有对我的性能产生影响=>使用DelayJob / Sidekiq /在我的rails中执行该过程但是在为工作创建的线程中,但是所有都具有相同的影响我的表现* 2。

这种性能差异仅存在于rails'生产'环境中。 看起来有一个由rails完成的优化,这在我的后台作业中没有完成。

我的技术环境如下=>

  • 我正在使用ruby 2.0 / rails 4
  • 我正在使用独角兽(但没有它我有同样的问题)。
  • 这项工作是使用Rails.cache来存储一些部分计算。
  • 我正在使用postgresql

有没有人知道这种影响可能来自哪里?

我假设您将后台作业速度与Web请求期间运行操作的速度进行比较? 如果是这样,您可能会受益于Rails的QueryCache ,后者在Web请求期间缓存数据库查询。 尝试禁用它,如下所述:

全局禁用Rails SQL查询缓存

如果这导致作业的Web请求版本与后台作业一样长,那么您就找到了罪魁祸首。 然后,您可以在后台作业上启用查询缓存以加快速度(如果它对您的应用程序有意义)。

后台工作不是需要用于加速事情的东西。 它的主要意义是“发射并忘记”并同步删除25秒计算并异步添加更多计算。 因此,您可以提供她请求正在处理的用户响应,并在以后计算时返回。

您可以通过将大任务分成一些小任务并同时运行来从后台工作中获取速度增益。 在你的情况下,我认为这是不可能使用的,因为在你的计算中依赖于操作。

因此,如果您想加快计算速度,则需要研究数据结构的非规范化,并在更新此计算的源数据时为您的大计算存储一些计算值。 因此,您将根据用户对结果的请求计算较少,而对数据存储的计算更多。 这是使用后台工作的好地方。 因此,您完成数据更新,为更新缓存创建后台任务。 如果用户在此任务完成之前请求计算,您仍需要等待缓存填充。

更新:我想我仍然需要回答你的主要问题。 所以基本上这个后台任务处理的额外时间来自实现。 由于“火灾和遗忘”的方法,没有人需要后台任务调度程序将消耗大量的处理器时间来监控新的工作。 我不完全确定,但如果你的计算会复杂两倍,那么时间增益将是25秒。

我的猜测是,额外的时间来自后台工作人员加载rails和所有应用程序的需要。 我的线索是,你说在生产模式下Rails的差异最大。 在生产模式下,对应用程序的后续调用使用app和类缓存。

如何检查这个假设:

更改后台作业以执行以下操作:

  1. 启动工作程序之前打印日志消息
  2. 启动工人
  3. 运行你的计算。 作为计算启动的一部分,打印日志消息
  4. 打印另一条日志消息
  5. 再次运行您的计算
  6. 打印另一条日志消息

然后比较两次运行计算。

当然,你也可以从数据库缓存中获得额外的时间好处,代码可能仍然驻留在内存中等等。但是如果第二次运行速度要快得多,那么第二次运行没有重启Rails的事实就更为重要。

此外,步骤1和3之间的日志消息之间的时间也将帮助您了解启动时间。

修复

干嘛要等? 最重要的是:为什么你需要更快的结果? 例如,告诉您的用户结果将在计算后通过电子邮件发送给他们。 或者让您的用户看到计算在后台进行,然后向他们显示结果。

任何长时间运行计算的关键是在后台进行,并鼓励用户不要等待结果。 他们应该能够做其他事情,直到他们得到结果。

自动开始计算一旦用户登录,或在他们做了一些有趣的事情后,就开始计算。 这样,当(和如果)用户要求计算时,答案将要么已经完成,要么很快就会完成。

根据需要缓存结果并破坏缓存与上面类似,定期自动开始计算。 如果用户更改了某些数据,则通过破坏缓存重新开始计算。 如果计算过程中更改了数据,还有一些方法可以暂停任何正在进行的计算。

预先计算部分计算为什么要花费25秒或更多时间进行dbms计算? 可能是你应该改变计算。 调查添加索引,汇总表,反规范化,将计算拆分为可预先计算的较小步骤等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM