Ruby on rails Ruby中延迟处理作业:有多少没有阻塞我的路径

Ruby on rails Ruby中延迟处理作业:有多少没有阻塞我的路径,ruby-on-rails,delayed-job,resque,sidekiq,delayed-execution,Ruby On Rails,Delayed Job,Resque,Sidekiq,Delayed Execution,我有这个项目仍然使用延迟作业作为处理作业队列。我最近发现了一个edge案例,这让我对一些事情产生了疑问:我有一个AR,我正在使用MySQL,顺便说一句,这个对象在更新时向一个有很多关联的所有元素发送一条消息。为了做到这一点,我必须实例化这个关联的所有元素,并对它们调用消息。对他们中的每一个人来说,推迟发出这条信息似乎是公平的 现在这个关联已经增长了很多,在一个边缘案例中,我有40000个对象属于这个关联。由此发送的消息现在涉及同步创建40000个延迟作业。由于这些事件发生在更新后回调而不是提交后

我有这个项目仍然使用延迟作业作为处理作业队列。我最近发现了一个edge案例,这让我对一些事情产生了疑问:我有一个AR,我正在使用MySQL,顺便说一句,这个对象在更新时向一个有很多关联的所有元素发送一条消息。为了做到这一点,我必须实例化这个关联的所有元素,并对它们调用消息。对他们中的每一个人来说,推迟发出这条信息似乎是公平的

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

现在,有很多方法可以解决这个问题:将回调更改为提交后,创建一个同步延迟作业,这将创建40000个作业我不想在一个作业中处理40000个AR对象,现在的40000个将是明天的120000个,这就是内存大决战,等等


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

事实上,Redis处理写操作的速度比MySQL快。试着运行redis benchmark,你会看到每秒超过100k次的数据

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

不,它们是同步进行的

我不想一次处理40000个AR对象


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

事实上,Redis处理写操作的速度比MySQL快。试着运行redis benchmark,你会看到每秒超过100k次的数据

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

不,它们是同步进行的

我不想一次处理40000个AR对象

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