【问题标题】:What pattern of ZMQ must be used for the following scenario?以下场景必须使用哪种 ZMQ 模式?
【发布时间】:2016-03-15 20:07:28
【问题描述】:

我最近开始学习 ZMQ (Python)。我必须承认,我发现很难理解 PUSH/PULL 和 DEALER/ROUTER 模式。

我的问题陈述如下:

  1. N 客户端数量(例如 100 个)将在上午 10:00:00(时:分:秒)发送请求(查询某些数据、访问资源等)
  2. 服务器必须在上午 10:00:00 处理所有 N 请求。
  3. 假设一个请求需要 30 秒才能完成,所有客户端 (100) 必须在上午 10:00:30 收到响应
  4. 我应该使用哪种 ZMQ 模式?

我知道REQ/REP 是同步的,我不能使用该模式来解决特定问题。 (服务器一次只能处理一个请求)

请帮助我提供使用 ZMQ 开发客户端/服务器应用程序的示例程序/链接。 (服务器一次必须至少处理 100 个请求)

如果第二天请求的数量增加,我是否可以使用 ZMQ 进行扩展?
如果可以,如何?

【问题讨论】:

    标签: python zeromq


    【解决方案1】:

    您有 N 客户端和 1 个服务器。
    服务器将无法同时完成 N 请求。
    显然,服务器可以使用 crontab 或其他调度机制在上午 10:00:00 开始处理 N 请求。

    合适的 ZMQ 模式似乎是 PUSH/PULL。见http://zguide.zeromq.org/page:all

    然后导航到Figure 6 - Fair Queuing.

    回答您的扩展问题:您可以将服务器视为请求的单个入口点,在服务器后面有一些 (>= N) 并行工作人员。此架构显示在Figure 20 - Multithreaded Server。

    该架构理论上可以解决并发问题,但有几点重要说明:

    1. 真正的并行执行只有在您为每个工作人员有一个单独的 CPU 内核时才可用(注意:它们可能分布在使用tcp:// 地址的多台机器上)。如果您有可用的< N 内核,您最终会遇到这样一种情况:您使工作并行,而操作系统再次使其按顺序运行。

    2. 如果工作器上的执行时间受 I/O 限制(即数据库查询、文件系统访问等),请将您的图表切割成更小的节点,并仅使 CPU 限制的任务并行。

    3. 单个服务器,即使它只将请求转发到一个工作池,也是一个可伸缩性限制。在您的设计中的某一时刻,您需要做出与CAP theorem 相关的选择。

    【讨论】:

    • 抱歉@Freek,ZeroMQ 是一个非常有用的工具箱,一个琐碎的PUSH/PULL 原始行为模式并不能解决该方案。如上所述,传入请求的排队并不是设计的基石。
    • PUSH/PULL 模式假设一个服务器(在原始帖子中提到了 N 个客户端和 1 个服务器)。我同意您的观点,即该架构无法提供并发性。我编辑了答案以解决并发性和可扩展性问题(“多线程服务器”以及下面的所有内容)。
    • @deepak:不完全。在 REQ/REP 中,请求将被逐个处理。请求 i+1 仅在 i 返回给客户端后才开始。在带有工作池的 ROUTER/DEALER 中,多个请求将同时在工作池上。但是操作系统中的调度程序必须在工作人员之间切换;实际上,任何时候都只有一个任务计算。对于 I/O 密集型任务,这仍然是一种加速,尽管它不是最好的方法。
    • 所以我们与N 客户合作。每个都有一个REQ 套接字。有 1 个服务器有一个 ROUTER 套接字和一个 DEALER 套接字(来自 ZeroMQ 指南中的图 20 的示例)。有Nworker,每个都有REPsocket;所有这些工作人员都连接到DEALER(参见代码:zguide.zeromq.org/py:mtserver)。然后客户端上的每个send() 都会自动路由到可用的工作人员。
    • 假设工作人员主要受 I/O 限制(如查询外部数据源),这将使工作并行。缺点是大型线程池不是运行并行作业的最有效方式。如果工作更多地受 CPU 限制,那么单核机器上的性能不会提升。
    【解决方案2】:

    可扩展性优先:

    是的,ZeroMQ 是一个强大的工具。如果不涉及底层细节,您的方案在服务器端进程管理方面的问题比任何ZeroMQ 相关部分的问题都多。

    一旦需要更多的能力,ZeroMQ 可以通过在模式的处理端添加适当的资源来提高它的处理能力,并且您的客户端(请求者)代码不必更改 SLOC。


    硬实时约束:

    如果您的1-2-3 原理图的时间允许在服务器端(并且我们谈论毫秒和微秒的不准确性,以满足 30 秒硬实时并行性,这在 100 多个处理任务中直截了当 4- core / 8-core / MPPA-manycore 处理器单元),
    您的代码
    可以继续
    一个可扩展的负载平衡消息代理[Figure 32],它可以解决以并发方式1-2-3方案。

    如果努力满足 10:00:30:000.000000 毫秒的障碍,您的处理端必须分散 - 即 [worker] 进程的更多真实主机(不是任何虚拟机一种“按需”的云供应小说)。

    一个单一的服务器根本无法在小于30[sec] 的N > 2 中创建N*30[sec](不要忘记并发调度和消息处理流开销的成本)。


    现实世界的系统架构必须包含更多的“线”:

    如果您的代码努力投入生产,而不仅仅是一个学术示例,则必须完成更多工作,才能为现实世界的生产环境提供生存能力。

    Pieter HINTJEN 的书“Code Connected, Vol.1”(查看我在 ZeroMQ 上的帖子以找到 pdf 链接)是一本关于 ZeroMQ 现实设计的好书。

    ZeroMQ 的共同之父 Martin SUSTRIK 的另一篇精彩文章来自 low-level truths about the ZeroMQ implementation details & scale-ability


    结语: REQ/REP 原始行为通信模式在现实世界中是危险的,因为如果传输(无论出于何种原因)丢失了一个数据包和“钟摆”式消息传递变得不完整并永远锁定。

    【讨论】:

    • 目前,我正在使用 uWSGI 作为应用服务器,想法是拥有“N”个 uWSGI 工作进程(将连接到 REP 套接字并等待回复)和“K”个 ZMQ REP 套接字(它将完成所有处理工作)。这是使用的理想 ZMQ 模式,这样工作人员就不会花费很长时间来响应。有 N == K 是否理想。请提出建议。注意 uWSGI 还允许指定线程数。
    猜你喜欢
    • 1970-01-01
    • 2011-02-19
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多