我正在尝试将Celery与Kubernetes一起使用。我在另一个pod中使用Redis作为消息代理,我为Celery的每个队列都有多个pod。
想象一下,如果我有3个队列,我会有3个不同的pod(即工人)可以接受和处理请求。
到目前为止一切正常,但我的问题是,如果我克隆一个队列的pod以便为一个队列拥有两个pod,会发生什么?
我认为客户端(即Django)使用Redis创建一条新消息发送给工作人员并开始工作,但我不清楚会发生什么,因为我有两个pod监听同一个队列?第一个pod是否接受请求并启动作业并阻止另一个pod接受请求?
(我试着在Celery的文档上搜索一下,看看我是否能找到任何线索,但我不能。这就是我问这个问题的原因)
答案 0 :(得分:3)
我猜你使用的是基本任务类型,它采用'直接'队列类型,而不是'扇出'或'主题'队列,后两者有很大差异,这里不再讨论。
使用Redis作为代理传输时,celery / kombu使用Redis list
对象作为队列存储(source),使用命令LPUSH
发布消息{{1}消费消息。
简而言之,BRPOP
(doc)在没有要从给定列表中弹出的元素时阻止连接,如果列表不为空,则从给定的尾部弹出一个元素名单。保证this operation is atomic,没有两个连接可以获得相同的元素。
Celery利用此功能来保证至少一次消息传递。使用确认不会影响此保证。
在您的情况下,多个pod中有多个芹菜工作者,但它们都连接到一个相同的Redis服务器,所有这些服务器都被阻止使用相同的密钥,尝试从同一个列表对象中弹出一个元素。当新消息到达时,将会有一个且只有一个工作人员可以获得该消息。
答案 1 :(得分:0)
在工作人员确认该消息之前,不会从队列中删除任务消息。工人可以提前预订许多消息,即使工人因电源故障或其他原因被杀,该消息也会被重新传递给另一名工人。
更多:http://docs.celeryproject.org/en/latest/userguide/tasks.html
两名工作人员(小组)将接收任务并独立完成任务。它就像有一个pod,但处理任务的速度是其两倍。