Linux 如何扩展UDP读取吞吐量?
设置:两台linux(CentOS 6)服务器通过专用的GigE链路背靠背连接。每台服务器具有24个核心和32GB RAM 客户端:模拟器在一个线程中尽可能快地拍摄UDP数据包。每个数据包大小为256字节。我发现最大吞吐量约为200000包/秒 服务器:在一个线程中接收UDP套接字上的数据包并执行轻量级解析。我看到最大吞吐量约为200000包/秒,CPU one 1核在处理过程中的利用率约为85%。没有数据包丢失,接收缓冲区设置为128M以防万一 现在我有23个我想使用的额外内核,但只要我在服务器端添加一个用于接收数据的线程和一个用于通过专用套接字在客户端发送数据的客户端线程,我就会看到服务器端大量的数据包丢失 服务器线程彼此完全独立,除了I/O之外不会阻塞。它们也不会在套接字上竞争,因为它们中的每一个都会从自己的UDP套接字上吸取数据包 我看到以下行为:Linux 如何扩展UDP读取吞吐量?,linux,Linux,设置:两台linux(CentOS 6)服务器通过专用的GigE链路背靠背连接。每台服务器具有24个核心和32GB RAM 客户端:模拟器在一个线程中尽可能快地拍摄UDP数据包。每个数据包大小为256字节。我发现最大吞吐量约为200000包/秒 服务器:在一个线程中接收UDP套接字上的数据包并执行轻量级解析。我看到最大吞吐量约为200000包/秒,CPU one 1核在处理过程中的利用率约为85%。没有数据包丢失,接收缓冲区设置为128M以防万一 现在我有23个我想使用的额外内核,但只要我在服务
有没有一种方法可以提高我的程序的可伸缩性和最小化丢包?
第一次,每秒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万包来自哪里?互联网上的不同主机?也许你应该平衡一下它或者别的什么
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%。谢谢。流量在背靠背连接的服务器之间。协议不在我的控制之下。这是一个收集应用程序,我需要收集源程序生成的所有数据。我正在推动重新设计协议,同时我需要解决规模问题。谢谢