为什么来自同一主机的多个连接比来自不同主机的多个连接具有更好的吞吐量?
我怀疑是与内核有关的东西(Linux),但确认会很有帮助。
更多细节我有 1 个接收器进程,我们称之为 R。它接受传入连接并使用 select() 接收数据。
我有 3 个发送方进程 S1、S2、S3。它们连接到 R 并以固定速率(即每秒 200Mbit)发送数据。
如果 S1、S2 和 S3 在同一台机器上,我会得到比将它们分别放在不同的机器上更好的结果。(在这两种情况下,R 都在其他机器上)
例如:主机 0 上的 R,主机 2 上的 S1、S2、S3,R 以 600Mbit/s 的速度接收
R 在主机 0 上,S1 在主机 1 上,S2 在主机 2 上,S3 在主机 3 上,R 以 480Mbit/s 接收
对于我来说这看起来是违反直觉的,我期望的情况相反,因为在第二种情况下,发送方不必共享网卡和处理器(并不是说处理器或网卡会成为瓶颈......)
[上面的主机是 Linux 集群中的节点,配有专用的全双工千兆交换机。它们运行的是 2.6.24-24-generic(我猜是最新的 Ubuntu)]
答案1
我怀疑这与交换机如何管理争用有关;如果只有一个发送方,则不会发生争用;如果有三个发送方都尽可能快地推送,则交换机可能会开始丢弃数据包,从而导致 TCP 退避和重新传输。
我想您可以通过将 3 张卡放入接收器并将它们直接连接到发送器来测试这一点(不要认为您需要千兆交叉电缆)
答案2
我相信这是一个经典的管道效率问题。
如果有多个发送方主机,它们都将开始通过线路发送以太网帧。这些帧将到达交换机背板,并在连接到 host0 的端口中排队。Host0 将尽可能快地接收这些帧,但发送方将以比 host0 交换机端口所能提供的每秒多得多的帧数快速淹没交换机。它们试图通过只能读取 1 千兆位/秒的端口推送 3 千兆位/秒。
通常,如果这些帧堆积在 port0 队列中,交换机将能够缓冲这些帧。但它们无法创造奇迹。因此交换机将开始丢弃帧。结果是大量 TCP 数据包将丢失。您可以通过检查发送方主机中此计数器的增加来验证这一点:
netstat -s|grep ‘段重传’
你可以想象,即使采用退避算法,重传也只会让拥塞情况更加严重
如果只有一台主机,它将以 1 Gigabit/s 的速度传输。接收器可能会收到所有以太网帧,并且应该可以正常工作。我还建议使用 UDP 进行一对一测试,这样您会得到更好的结果。完成此任务的一个好工具是“iperf”。
祝你好运!
答案3
为了便于讨论,我假设使用 TCP/IP 进行通信。如果这是错误的,请评论并告知我。
您可能可以捕获数据包并获取完整的详细信息,但这可能会将争论点从单台机器上的单个协调 TCP/IP 堆栈转移到不同机器上的多个单独的 TCP/IP 堆栈,而千兆交换机可能是一种无法真正解决问题的廉价产品。
在您最初的场景中,一台服务器使用相同的 IP 堆栈向另一台服务器发送数据。如今,大多数服务器 NIC 都具有 TCP 卸载功能,并且硬件中有很多东西,因此它们可以很好地协调 IP 堆栈,确定何时发送哪些帧,并进行适当的交错。这可能使标准 NIC 比您购买的大多数交换机更好用。但是,通过将其移动到单独的服务器,您已将争用点转移到交换机,而交换机实际上只知道第 2 层(将帧发送到 x mac 地址),当它需要将多个高吞吐量连接交错到单个端口时,它可能只是有一个非常糟糕的芯片和内存,导致不一致的延迟(称为抖动)、超限甚至丢帧。这是因为以前,交换机所要做的就是将帧从端口 1 复制到端口 2,反之亦然,但现在它有很多工作要做,因为它有大量来自 3 个源的帧,它必须尝试在几微秒内进行交错。
不过,我应该提到一些可能存在问题的更基本的问题:
如果您的电缆质量稍差,或者电缆被轻微挤压,导致线路上出现一些额外的阻抗,这可能会影响吞吐量,请始终检查是否有丢失的数据包/帧,并务必检查接口是否有错误。我不知道它在 Linux 上的表现如何,但在 FreeBSD 上 netstat -I 将显示输入/输出错误的数量。
另外,请确保您没有任何自动协商错误,即其中一个接口协商为半双工。这在千兆速度下并不常见,但在混合使用 100Mb 和千兆时可能非常常见,而且 Solaris 的协商能力特别差。