我只是发现了关于配置选项CELERYD_PREFETCH_MULTIPLIER
( 文档 )。 默认值是4,但(我认为)我想要的预取关闭或尽可能低。 我将它设置为1,现在,这是足够接近我正在寻找,但还是有一些事情我不明白:
这是为什么预取一个好主意? 我真的不明白了一个道理吧,除非有很多的消息队列和工人(在我的情况之间的延迟,他们目前在同一台主机上运行,并且在最坏的情况可能最终在同一个数据在不同的主机上运行中央)。 该文件只提到的缺点,但不能说明什么优势。
许多人似乎将其设置为0,期待能够关闭预取这种方式(一个合理的假设在我看来)。 然而,0表示没有限制预取。 为什么会有人曾经想无限的预取,不说完全消除您在第一时间推出了任务队列的并发/异步?
为什么预取不会被关闭? 它可能不是性能关闭它在大多数情况下是个好主意,但有一个技术原因没有可能呢? 或者它只是没有实现?
有时候,这个选项连接到CELERY_ACKS_LATE
。 例如。 罗杰·胡写 «[...]往往是什么[用户]真正想要的是有个工人只能作为有子进程保留尽可能多的任务。 但是,这也不是没有可能使后期确认[...]»我不明白,这两个选项是如何连接的,为什么一个不可能没有其他。 连接的另一提到可以发现在这里 。 有人可以解释为什么这两个选项连接?
老问题,但还是加入我的答案的情况下,它可以帮助别人。 我从初步的测试结果的理解是一样的,在大卫Wolever的答案。 我只是在芹菜3.1.19测试这个越来越-Ofair
确实工作。 只是,这并不意味着在工作节点级别禁用预取。 这将继续发生。 使用-Ofair
具有不同的效果,其是在池工作水平。 总之,要完全禁用预取,这样做:
- 设置
CELERYD_PREFETCH_MULTIPLIER = 1
- 设置
CELERY_ACKS_LATE = True
在全球范围内或任务等级 - 使用
-Ofair
而启动工人 - 如果设置并发为1,则步骤不需要3。 如果你想有一个更高的并发性,那么第3步是必不可少的,以避免可能运行长时间运行任务的节点任务正在备份。
添加一些细节:
我发现,工作节点总是会被默认预取。 你只能控制它多少任务预取使用CELERYD_PREFETCH_MULTIPLIER
。 如果设置为1,只会预取尽可能多的任务,如游泳池工人(并发)的节点数目。 所以,如果你有并发= N,由节点预取的最大任务数为n。
如果没有-Ofair
选项,发生了什么事对我来说是,如果池工作进程的一个正在执行长时间运行的任务时,其他工人在节点也将停止处理已经由节点预取的任务。 通过使用-Ofair
,即改变。 即使在节点一个工人正在执行长时间运行的任务,别人就不会停止处理,并将继续处理由节点预取的任务。 所以我看到预取的两个层次。 一是在工作节点级别。 另外在每个工人的水平。 使用-Ofair
我似乎在工人层次来禁用它。
如何ACKS_LATE
关系? ACKS_LATE = True
意味着,只有当任务成功完成任务将得到承认。 如果不是这样,我想,当它是由一个工作人员接收到它会发生。 在预取的情况下,首要任务是由工作人员接收(原木证实),但将在以后执行 。 我刚刚意识到预取的消息显示“未确认的消息”下的RabbitMQ。 所以我不知道,如果设置为True
是绝对必要的。 无论如何,我们有我们的任务设置其他原因方式(晚ACK)。
只是一个警告:因为我与Redis的经纪人+芹菜3.1.15,所有我读过有关建议的测试CELERYD_PREFETCH_MULTIPLIER = 1
禁用预取证明是错误的。
为了证明这一点:
- 设置
CELERYD_PREFETCH_MULTIPLIER = 1
- 队列将分别需要几秒钟最多5个任务(例如,
time.sleep(5)
开始看任务队列的长度在Redis的: watch redis-cli -c llen default
启动celery worker -c 1
- 请注意,在Redis的队列长度会立即下降从
5
至3
CELERYD_PREFETCH_MULTIPLIER = 1
不防止预取 ,它简单地限制了预取到每个队列1级的任务。
-Ofair
, 尽管文档中说什么 ,也不会阻止预取 。
短修改源代码的,我还没有找到完全禁用预取的任何方法。
因为我的stackcred不够高,我不能大卫Wolever的回答发表评论。 所以,我陷害我的评论作为一个答案,因为我想分享我的芹菜3.1.18和MongoDB的经纪人经验。 我设法停止与以下预取:
- 添加
CELERYD_PREFETCH_MULTIPLIER = 1
到芹菜配置 - 添加
CELERY_ACKS_LATE = True
到芹菜配置 - 开始芹菜工作者选择:
--concurrency=1 -Ofair
离开CELERY_ACKS_LATE到默认,工人还在进行预取。 就像OP我不完全掌握预取和后期的ACK之间的联系。 我明白大卫说:“CELERY_ACKS_LATE = true以阻止确认消息,当他们到达一个工人”,但我不明白为什么迟到的ACK将与预取不兼容。 从理论上讲预取仍允许ACK晚权 - 即使不在芹菜编码为这样?