我有很多芹菜节点在不同的Linux机器上运行。简化的群集如下所示:
我有一个长期运行的 taskA 从远程文件服务器下载(巨大的)文件,我想在 taskA后触发 taskB 在同一台计算机上完成其作业,因为这是 taskA 下载文件的地方,该文件基本上是 taskB 的输入。我知道Celery应该是分发的,但在某些情况下,像这样一个拥有真正分布式解决方案的人会很昂贵。
请注意,在图中,nodeA上的taskA触发同一节点上的taskB,而在nodeB上运行的taskA触发nodeB上的taskB(运行" parent"任务的同一节点)。
apply()不起作用,因为我希望排队 taskB()在有备用工作进程(在同一节点上)时运行。
我开始探索在每个节点上拥有唯一队列的可能性(所以nodeA有queueA,nodeB有queueB等),但我不知道如何从taskA获取可用的队列名称,所以我可以在队列上排队任务同一个节点。 (这可能会解决我的问题。)
我试图在Celery文档中找到解决方案,但我找不到任何可以帮助我的方法。任何想法都会非常感激。
答案 0 :(得分:1)
您可以使用apply method直接触发taskB。
此方法将在本地执行任务,而不发送给代理。
请注意,这相当于只有一个任务具有更高级的重试策略。
可以将第一个任务发布到通用队列,同时可以在serverABC上运行的taskA中调度第二个任务,并传递特定的队列名称,如“FILE_PROCESSING_SERVER_ABC”,其中只有在serverABC上运行的worker被配置为consumer。通过这种方式,taskA将在任何服务器上运行,而B将被强制运行在仅属于运行taskA的worker的特定队列上。 有关手动路由的更多信息here。
根据Aaron的建议,您可以使用环境变量来存储计算机X的队列,并在计划任务B时从任务A中检索它。
答案 1 :(得分:1)
如果您对每个节点的队列都没有问题。我使用每个主机设置来保存该队列的名称。这样,TaskA可以查找正确的队列来运行taskB。