在Rails中运行大量长时间运行的后台作业

时间:2016-10-14 21:46:35

标签: ruby-on-rails ruby delayed-job digital-ocean

我们正在构建一个网络应用,用户将上传需要在后台处理的大型文件。该任务涉及调用第三方API,因此每个作业可能需要几个小时才能完成。我们正在使用DelayedJob来运行后台作业。每个用户开始一个后台工作,每个工作都需要几个小时才能完成,这将很快增加很多后台工作。我想知道为此设置部署的最佳方法是什么?我们目前托管在DigitalOcean上。我已经开除了10名DelayedJob工作人员。每个(理想情况下)占用157MB。在积极运行时,它使用大约900 MB。我们现在的用户群非常小,所以这不是问题,但很快就会出现问题。所以在一个4GB的液滴上,我一次可能像2或3个工人一样跑。我们该如何处理这个问题?我们是否应该考虑使用DigitalOcean的API按需自动旋转廉价的液滴?我们应该每月订阅高记忆水滴吗?如果我们使用自动旋转的液滴,我们应该坚持使用DigitalOcean还是Heroku会更有意义?或者整个方法是错误的,我们是否应该从一个完全不同的方向接近它?任何帮助/建议将非常感谢。

谢谢!

2 个答案:

答案 0 :(得分:1)

听起来,您可以通过内存限制您可以在DigitalOcean主机上运行的工作人员数量。

如果您担心扩展,我会专注于让工作人员尽可能高效。你有没有做过任何基准测试来了解900MB内存的分配位置?我不确定这些工作的性质是什么,但你提到了大文件。您是否正在将这些文件的内容读入内存,或者是否正在将它们流式传输?你在使用带有SQL的数据库吗?在使用批处理端点时,您是否正在进行许多小型API调用?您是否正在分配必须进行垃圾收集的中间变量?你可以在发送之前压缩文件吗?

看看工作结构本身。我发现后台工作对于许多较小的工作而不是一个较大的工作最有效。这允许执行并行发生,并在所有工作人员之间实现更多负载平衡。你甚至可以找到一份可以创造其他工作的工作。如果您需要一个作业来在一组作业完成时编排回调,则https://github.com/salsify/delayed_job_groups_plugin处有一个DelayedJobGroup插件,允许您仅在兄弟作业完成后调用最终作业。我的目标是单个作业的执行时间不到30秒。这是随意的,但它说明了我对小型工作的意思。

像亚马逊这样的托管服务提供商提供了一些现场实例,您可以在没有保证可用性的服务器上支付更低的价格。这些与我之前提到的少得多的工作方法配对得很好。

最后,Ruby可能不适合这项工作。有更快的语言,如果您受到内存或CPU的限制,您可能会考虑使用其他语言(如Javascript,Go或Rust)编写这些作业及其工作程序。这些可以很好地与Ruby堆栈配对,但可以将计算成本较高的子程序卸载到更快的语言中。

最后,像许多扩展问题一样,如果你有比时间更多的钱,你总是可以投入更多的硬件。至少有一段时间。

答案 1 :(得分:0)

我的记忆和时间对你来说更有问题。你必须在这个过程中使用sidekiq gem,因为它会消耗更少的时间和内存消耗来完成相同的工作,因为它使用redis作为数据库,它是键值对db.if问题继续使用java脚本。