1

我有这个项目,它仍然使用延迟作业作为处理作业队列。我最近发现了一个让我质疑一些事情的边缘案例:我有这个 AR(顺便说一下,我正在使用 MySQL)对象,它在更新时会向 has_many 关联的所有元素发送一条消息。为了做到这一点,我必须实例化这个关联的所有元素,并在它们上调用消息。对他们每个人来说,延迟这个消息的调用似乎只是公平的。

现在该关联已经增长了很多,在极端情况下,我有 40000 个属于该关联的对象。因此,消息发送现在涉及(同步)创建 40000 个延迟作业作业。由于这些发生在更新后回调而不是提交后,因此它们(ab)使用相同的连接,而不是利用任何上下文切换。短版,我在同一连接上有 1 个更新语句和 40000 个插入的管道。出于这个原因,此更新在生产中消耗了相当多的时间。

现在,有很多方法可以解决这个问题:将回调更改为提交后,创建 1 个(同步)延迟作业,这将创建 40000 个作业(我不想在一个作业中处理 40000 个(AR)对象,现在的 40000 明天将是 120000,这就是记忆世界末日),等等……

但我真正考虑的是将我的延迟处理队列切换到 resque 或 sidekiq。他们使用redis,因此写入性能要好得多。他们使用一些东西而不是 MySQL,这意味着连接不会相互阻塞。我唯一的问题是:一次 40000 次写入 redis 会花费我多少钱?并且:这些选项中的任何一个是否首先将作业存储在内存中,而不是阻止对客户端的响应并将它们延迟存储在 redis 中?所以,我真正的问题是:在这种极端情况下,这种延迟会耽误我多少时间?

4

1 回答 1

4

事实上,Redis 可以比 MySQL 更快地处理写入。尝试运行redis-benchmark,您将看到 100k+ 写入/秒的数字。

这些选项中的任何一个是否首先将作业存储在内存中,而不是阻止对客户端的响应并将它们延迟存储在redis中?

不,它们是同步进行的。

我不想在一项工作中处理 40000 个(AR)对象

也许您应该尝试混合方法:每个作业处理 N 个对象的块。批量写入应该比 40k 单独写入快。而且它可以很好地扩展(批量大小将保持不变,无论是 40k 还是 400k 项目)。

于 2013-03-18T08:57:58.143 回答