c++ - 这个小型数据/命令广播应用程序的建议网络拓扑?

标签 c++ linux sockets network-programming signal-processing

我们正在组装一个系统,该系统通过模数转换器卡读取约 32 个电压信号,对它们进行一些初步处理,并将结果(仍分为 32 个 channel )作为 UDP 数据包传递到网络,在那里它们被另一台计算机拾取并以各种方式 (a) 显示,(b) 进一步处理,(c) 搜索改变采集系统状态的标准,或 (d) AC 的某种组合。同时,GUI 进程在执行后面这些进程的计算机(vis 计算机)上运行,它通过 UDP 分组命令消息更改数据生成计算机和 vis 计算机的多个进程中的状态。

我是网络编程的新手,正在努力选择网络拓扑。对于不需要灵活传递数据、命令和命令确认的相对较小的应用程序,是否有任何关于网络拓扑的启发式方法(或书籍章节、论文)?

系统详情:

  • 原始数据采集发生在单个 Linux 机器上。简单地处理数据、保存到磁盘并推送到网络使用大约 25% 的 CPU 容量和少量内存。不到 0.5 Mb/sec 的数据进入网络。数据生成的所有代码都是用 C++ 编写的。
  • 另一台 linux 机器运行多个可视化/处理/GUI 进程。 GUI 控制采集机器和可见/处理/GUI 计算机本身的进程。这段代码主要是用 C++ 编写的,还有一些用 Python 编写的小实用程序。
  • 我们将编写其他应用程序来监听原始数据、处理过的数据和所有传递的命令;这些应用程序也需要发出命令——我们无法预测我们想要编写多少这样的模块,但我们期望有 3 或 4 个数据密集型进程将所有 32 个输入流转换为单个输出;以及 3 或 4 个一次性小应用程序,如“命令记录器”。模块化要求意味着我们希望旧的数据生成器和命令发布器不知道有多少监听器。我们还希望命令能够被接收者确认。
  • 两台机器通过交换机连接,数据包(数据和命令,以及确认)以 UDP 发送。

  • 我们正在考虑的五种可能性:
  • 数据流、命令和确认以端口号为目标。数据生成器将独立数据流作为 UDP 数据包发送到可视化计算机上由独立可视化进程绑定(bind)的不同端口号。每个进程还绑定(bind)一个用于传入命令的监听端口,以及另一个用于传入确认到传出命令的端口。这个选项看起来不错,因为内核负责传输/过滤数据包;但很糟糕,因为在面对不可预测的添加模块时,很难看出进程如何相互寻址;它似乎也导致绑定(bind)端口的爆炸式增长。
    enter image description here
  • 数据流通过端口号定位到各自的可视化器,每个进程绑定(bind)一个端口来监听命令。但是所有命令发布者都将他们的命令发送到一个包转发进程,该进程知道所有进程的命令输入端口,并将每个命令转发给所有进程。确认也被发送到这个通用命令输入端口并转发到所有进程。我们将有关每个命令的预期目标和每个确认的信息打包到命令/确认包中,因此进程本身必须筛选所有命令/确认以找到与它们相关的命令/确认。
    enter image description here
  • 包转发进程也是所有数据包的目标。所有数据包和所有命令包都被转发到大约 40 个不同的进程。这显然会给子网带来更多流量;它还清理了绑定(bind)端口的爆炸。
    enter image description here
  • 两个数据包分发器可以在可视计算机上运行 - 一个向所有端口广播命令/确认。另一个只向可能需要数据的端口广播数据。
  • 我们的 32 个可视化流程可以捆绑到 1 个流程中,为 32 个信号绘制数据,从而大大减少选项 3 导致的额外流量。

  • 如果您已经尝试在少数机器上的多个进程之间传递数据,并且对哪些策略是稳健的有一些智慧或经验法则,我将非常感谢您的建议! (欢迎在图片中要求澄清)

    最佳答案

    我没有足够的代表将这个问题移到programmers.stackexhange.com,所以我会在这里回答。

    首先,我将向您抛出相当多的技术,每个技术您都需要看一看。

  • Hadoop一个map-reduce框架。能够获取大量数据,并跨分布式节点进行处理。
  • Kafka一个非常高性能的消息传递系统。我建议将其视为您的消息总线。
  • ZooKeeper一个分布式系统,可以让您“弄清楚”分布式系统的所有不同方面。这是一个分布式的协调系统
  • Pub/Sub Messaging
  • ∅mq另一个允许发布/订阅消息传递和其他 N 对 N 消息传递安排的套接字库。

  • 既然我已经向您介绍了一些技术,我将解释我将要做什么。

    创建一个允许您创建 N 个连接器的系统。这些连接器可以处理图中的数据/命令 N,其中 N 是特定信号。意思是如果你有 32 个信号,你可以用 32 个连接器设置你的系统来“连接”。这些连接器可以处理双向通信。因此您的接收/命令问题。单个连接器将其数据发布到特定于该信号的主题的 Kafka 之类的东西。

    使用发布/订阅系统。基本上发生的事情是连接器将其结果发布到指定的主题。这个话题是你选择的。然后处理器,UI、业务逻辑等监听特定主题。这些都是任意的,您可以根据需要进行设置。
     ============         =============      =====     ============       =============
     = Signal 1=  < --- > = Connector = < -- = K = --> = "signal 1" --->  = Processor =
     ============         =============      = a =     ============       =============
                                             = f =
     ============         =============      = k =     ============       =============
     = Signal 2=  < --- > = Connector = < -- = a = --> = "signal 2" --->  = Processor =
     ============         =============      =   =     ============   |   =============
                                             =   =                    |
     ============         =============      =   =     ============   |  
     = Signal 3=  < --- > = Connector = < -- =   = --> = "signal 3" --- 
     ============         =============      =====     ============       
    

    在此示例中,第一个连接器将其结果“发布”到主题“信号 1”,其中第一个处理器正在监听该主题。发送到该主题的任何数据都会发送到第一个处理器。第二个处理器正在监听“信号 2”和“信号 3”数据。这表示类似于同时检索不同信号的用户界面。

    要记住的一件事是,这可能发生在您选择的任何主题中。如果您认为重要,“处理器”可以收听所有主题。

    关于c++ - 这个小型数据/命令广播应用程序的建议网络拓扑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7128843/

    相关文章:

    c++ - 使用 vim 作为 c++11 IDE

    linux - 如何制作完美的死符号链接(symbolic link)

    c - 如何检测另一个守护进程是否终止

    java - 当没有传入连接时 SelectionKey.isAcceptable() 返回 "true"

    sockets - Chrome API : What Happened to `chrome(.experimental).sockets`

    c++ - 从 Windows 为 OSX 编译 C++

    c++ - 当我告诉它停止时,为什么程序会继续运行?

    php - 如何找出哪个代码正在使用 Sendmail?

    python - 当客户端断开连接时,服务器打印无尽的换行符

    c++ - cout 不命名类型