为什么来自同一主机的多个连接比不同主机的多个连接获得更好的吞吐量?
我怀疑是与内核相关的东西(Linux),但确认会有很大帮助。
更多细节我有一个接收器进程,我们称之为R.它接受传入连接并使用select()接收数据。
我有3个发件人进程S1,S2,S3。 他们连接到R,并以固定的速率发送数据,即每秒200Mbit。
如果S1,S2和S3在同一台机器上,我得到的结果比在不同机器上的每台机器都要好。 (R在这两种情况下在其他一些机器上)
例如:主机2上的host0,S1,S2,S3上的R,R以600Mbit / s的速率接收
主机0上的R,主机1上的S1,主机2上的S2,主机3上的S3,R以480Mbit / s接收
这看起来反直觉对我来说,我期望相反,因为在第二种情况下,发件人不必共享网卡和处理器(不要指望处理器或网卡是瓶颈…)
[上面的主机是具有专用全双工千兆位交换机的Linux群集中的节点。 他们正在运行2.6.24-24通用(最新的Ubuntu我猜)]
我怀疑这与交换机如何pipe理争用有关; 有1个发送者不存在争用,3个发送者都尽可能快地推动交换机可能开始丢弃导致TCP退避和重新传输的分组。
我想你可以通过在接收者中插入3张卡并直接连接发送者来testing(不要以为千兆位需要交叉电缆)
我相信这是一个经典的pipe道效率问题。
在多个发送者主机的情况下,他们都将开始通过电线发送以太网帧。 这些帧将到达交换机背板,并在连接到host0的端口中排队。 主机0将尽可能快地接收到这些数据,但是发送者会以比主机0交换机端口所能提供的更多的帧数每秒更多的速度将交换机充满。 他们试图通过只能读取1千兆位/秒的端口推送3千兆位/秒。
通常情况下,交换机将能够caching这些帧,如果他们堆积在port0队列。 但他们不能做奇迹。 所以交换机会开始丢帧。 结果是很多TCP数据包将会丢失。 您可以通过在发件人主机中检查此计数器的增加来validation这一点:
netstat -s | grep'segments retrans'
重传只会使拥塞变得更糟,就像你可以想象的那样 – 即使有退避algorithm
如果只有一个主机,它将以1千兆位/秒的速度传输。 接收器可能会得到所有的以太网帧,它应该工作正常。 我也build议使用UDP进行一对一的testing,你会得到更好的结果。 这个任务的一个很好的工具是'iperf'。
祝你好运!
为了讨论的缘故,我将假定TCP / IP用于通信。 如果这是错误的请评论和让我知道。
您可能需要捕获数据包并获取完整的详细信息,但是这可能会将单个协同TCP / IP堆栈在单个机器上的争用转移到单独的机器上多个单独的TCP / IP堆栈,而千兆位开关可能是一个el-cheapo,真的不能削减它。
在你原来的情况下,你有一台服务器发送到另一台服务器,使用相同的IP协议栈。 现在大多数服务器网卡都具有TCP卸载function,以及硬件上的许多东西,因此它们可以很好地协调IP协议栈,以及在何时发送帧以及进行适当的交织。 这可能使标准网卡比大多数可以购买的交换机更好。 但是,通过将其移动到单独的服务器,您将争用点移动到交换机,而交换机只需要知道第2层(将帧发送到x mac地址),就可以将多个高吞吐量连接交错一个单一的端口,它可能只是一个非常糟糕的芯片和内存,导致不一致的延迟(称为抖动),超限,甚至丢帧。 这是因为之前,所有交换机只需要复制从端口1到端口2的帧,反之亦然,但现在有很多工作要做,因为从3个源获得了很多帧,必须尝试交叉微秒。
但是,我应该提到一些更基本的问题,
如果你有一个稍微差的电缆,或者有一个小的捏,并获得了一些额外的阻抗,这可能会影响吞吐量,总是检查丢失的数据包/帧,并肯定检查你的接口的错误。 我不知道它对linux有多好,但在FreeBSD上netstat -I会显示input/输出错误的数量。
此外,请确保您没有任何自动协商错误,其中一个接口协商为半双工。 在千兆位速度下这种情况并不常见,但在千兆和100Mb混合使用时,这种情况可能会非常普遍,尤其是在谈判时。