Linux 如何扩展UDP读取吞吐量?

Linux 如何扩展UDP读取吞吐量?,linux,Linux,设置:两台linux(CentOS 6)服务器通过专用的GigE链路背靠背连接。每台服务器具有24个核心和32GB RAM 客户端:模拟器在一个线程中尽可能快地拍摄UDP数据包。每个数据包大小为256字节。我发现最大吞吐量约为200000包/秒 服务器:在一个线程中接收UDP套接字上的数据包并执行轻量级解析。我看到最大吞吐量约为200000包/秒,CPU one 1核在处理过程中的利用率约为85%。没有数据包丢失,接收缓冲区设置为128M以防万一 现在我有23个我想使用的额外内核,但只要我在服务

设置:两台linux(CentOS 6)服务器通过专用的GigE链路背靠背连接。每台服务器具有24个核心和32GB RAM

客户端:模拟器在一个线程中尽可能快地拍摄UDP数据包。每个数据包大小为256字节。我发现最大吞吐量约为200000包/秒

服务器:在一个线程中接收UDP套接字上的数据包并执行轻量级解析。我看到最大吞吐量约为200000包/秒,CPU one 1核在处理过程中的利用率约为85%。没有数据包丢失,接收缓冲区设置为128M以防万一

现在我有23个我想使用的额外内核,但只要我在服务器端添加一个用于接收数据的线程和一个用于通过专用套接字在客户端发送数据的客户端线程,我就会看到服务器端大量的数据包丢失

服务器线程彼此完全独立,除了I/O之外不会阻塞。它们也不会在套接字上竞争,因为它们中的每一个都会从自己的UDP套接字上吸取数据包

我看到以下行为:

  • CPU在每个内核上大约占85%,而一个称为ksoftirqd/xx的进程使用大约90%的额外内核
  • 我正在丢失数据包,每个线程的吞吐量下降到大约120000个数据包/秒
  • Google表示ksoftirqd使用CPU处理软中断,而大量系统调用(UDP读取)可能是该内核线程CPU使用率高的原因之一

    我重复了这个实验,将我的进程固定在同一个物理套接字上的一堆内核上,我看到性能提高到150000个包/秒,但仍然有一些相当大的包丢失


    有没有一种方法可以提高我的程序的可伸缩性和最小化丢包?

    第一次,每秒200000个包,每个包有256个(数据)字节,一旦你考虑UDP、IP和以太网开销,你的运行容量就只有你的千兆链接的带宽的一半。以每秒推送的数据包速率,许多交换机(例如)会倒下


    第二,你可能被IRQ杀了。更好的网卡具有可调功能,让您可以用更少的IRQ来换取更大的延迟(它们每N个数据包只中断一次)。确保已启用该选项。(一个需要检查的地方是您的以太网卡的模块参数。)

    您可以设置内核接收缓冲区,但请注意,如果IRQ占用了您所有的CPU,这将不会有帮助

    int n = 1024 * 512; //experiment with it
    if (setsockopt(socket, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1) {
      //oops... check this
    }
    
    您还应该将最大接收缓冲区设置为一个较大的值,以便内核不会限制您的设置:

    sysctl -w net.core.rmem_max=<value>
    
    sysctl-w net.core.rmem\u max=
    
    如果您的应用程序每秒需要200000个数据包,则可能是您的协议设计得不好,或者是您在做其他错误的事情

    20万包来自哪里?互联网上的不同主机?也许你应该平衡一下它或者别的什么


    DeBoeRT指出,每秒200K包代表了大量带宽,这将是非常昂贵的互联网,你可能应该考虑协议重新设计。< / P>我已经将接收缓冲区设置为128M,使用SysTcL。它不起作用。当我有大量的容量时,我需要找出是什么引起了争论。它要么是网卡,要么是套接字接口,因为我分析了我的代码以防止任何冲突。谢谢derobert。在这种情况下,服务器是背靠背连接的。没有涉及任何开关。我确实同意我正在把它推向极限,但这就是我实验的全部要点。是否有一个例子,你可以建议一个具体的卡?任何关于去哪里找的建议都会对我有帮助。我可以测试并重新发布。IRQ处理和SoftIRQ处理之间有什么区别吗?说到内核,我是个傻瓜。任何评论都会帮助我解决这个问题。谢谢。@Ravi:do a
    vmstat 1
    ,列中的
    是每秒接收的硬件IRQ数,对于网卡,它们的处理通常包括从网卡获取一些帧到内核,并通知内核处理它们,内核将在SoftIRQ(net SoftIRQ)上这样做。您希望合并工作,并避免不断使用硬IRQ中断有用的工作,这就是中断缓解的目的。@RaviChamarthy:我从来没有尝试过提高每秒数据包的限制,但我想应该试试Intel卡
    modinfo e1000
    modinfo e1000e
    将为您提供选项,文档/network/e1000.txt(等)有望对此进行解释。我会使用
    procinfo-n5-Sd
    (5是刷新时间,可以随意使用)。@derobert感谢您的指导。我的卡是Intel GigE以太网卡,模块是您建议的e1000。我将InterruptThrottrate设置为每秒5000次中断,可以将ksoftirqd/xx的CPU利用率降低到1核的5%,并将数据包处理增加到每个线程180000个数据包,而数据包丢失率仅为5%。谢谢。流量在背靠背连接的服务器之间。协议不在我的控制之下。这是一个收集应用程序,我需要收集源程序生成的所有数据。我正在推动重新设计协议,同时我需要解决规模问题。谢谢