【问题标题】:Distributing task with python and zeromq使用 python 和 zeromq 分发任务
【发布时间】:2012-03-24 14:43:35
【问题描述】:

我有一个使用 python 和 zeromq 的工作应用程序,我想对其进行优化。

简单地说,一个主节点向所有工作人员(大约 200 个)发送相同的请求,然后收集答案。根据答案,它会向一个节点发送回消息,该节点会回复。

现在我实现了一个非常简单的模式。每个工作人员都有一个 REP 套接字,服务器有一个 REQ 套接字列表。服务器遍历所有发送一般消息的套接字,然后遍历所有套接字以收集答案。最后,根据回答,服务器选择一名工人,向其发送消息并等待答复。

当然,这很慢。最慢的部分是发送 200 次相同的消息。收集也很慢。我发现分配任务和收集答案的解决方案可以实现负载平衡,这不是我需要的。我需要每个工作人员都收到消息并做出响应。

针对这种情况推荐的模式是什么?

谢谢

【问题讨论】:

  • 什么是“针对这种情况推荐的模式是什么?”
  • 例如,如果您必须处理独立的任务,您可以使用呼吸机模式来分配任务,如下所述taotetek.wordpress.com/2011/02/02/…
  • 我知道什么是模式。您实际上还没有解释您在做什么、需要当前解决方案的哪些部分,甚至没有解释为什么分发您的消息很慢。 “分发东西很慢”的经典解决方案是不分发东西,或者少做。
  • 感谢您再次尝试帮助我思考问题,但请给予一些信任。我需要分发,因为工作人员需要访问不适合一个节点的 RAM 的信息(并且访问磁盘很慢)。分发消息比到每个节点的往返行程要长两个数量级。这是有道理的,因为我做了 200 次。该往返包括通过网络堆栈的所有开销。我想知道是否有一个模式批处理所有这些调用。

标签: python distributed zeromq


【解决方案1】:

如果每个工人都需要不同的工作,Pub/sub 将无法工作。那么你需要的是一个工作池实现。要么以循环方式推出作业(只需使用绑定在服务器上的推送套接字并让每个客户端从中拉出,zeromq 将执行循环),要么让每个工作人员从服务器请求作业,如果作业至少具有最低的复杂性,并且作业之间的差异很大,这是一种更好的方法。 zeromq 主页和网络上的指南中有很多示例:

具体实现还取决于您是否需要可靠地处理作业。

【讨论】:

  • 谢谢,但正如我的问题中所述,每个工人都做同样的事情(但在他们自己的数据部分)。
【解决方案2】:

我不知道 zmq。这是一个可能不起作用的模式,只是为了开始:

一个主节点向所有worker(大约200个)发送相同的请求

主 PUB 绑定 *:3140 发送

worker SUB connect masterhost:3140 SUBSCRIBE recv

然后收集答案

worker PUSH 连接 masterhost:3141 发送

主 PULL 绑定 *:3141 recv

根据答案,它会向一个节点发送回消息,该节点会回复。

master REQ connect workerhost:3142 send recv

worker REP 绑定 *:3142 recv 发送

【讨论】:

  • 我终于有时间来实现和测试这个了。第一部分(分发相同的任务)快 100 倍,因为我使用 pub/sub 分发而不是循环通过 200 个套接字。第二部分(收集答案)仍然很慢(需要 8 毫秒)。我正在做的是在拉插座中调用 recv 200 次。有没有办法告诉 zeromq:“等待 200 条消息并在准备好时将它们作为数组返回”?
  • 为什么“等待 200 条消息并在准备好后将它们作为数组返回”比您已经在做的要快?除非有其他东西让你慢下来,否则我认为只有使用多个线程来拉取消息才会更快,你可以尝试一下。
  • @AaronWatters:0MQ 套接字不是线程安全的。 不要跨线程共享它们。
  • @Hernan:每秒 25k 条消息对于通用 PULL 套接字来说听起来不错。您如何获得8 ms 号码?您可以尝试调整套接字、操作系统网络选项。在 Python 中调用 200 次虚拟函数大约需要 1 微秒。 .recv() 释放/重新获取 GIL,因此它可能导致延迟。
猜你喜欢
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2011-12-10
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 2021-09-28
  • 2021-09-05
相关资源
最近更新 更多