问题描述
在我的实验室中,有一台用于测量的服务器正在Ubuntu上运行。并且有C程序,它通过TCP连接接收数据并应尽快发送答复。
组态
-
CPU:2个处理器x 4核-Intel(R)Xeon(R)CPU E5345 @ 2.33GHz
-
内存:12 GB
-
NIC:英特尔公司80003ES2LAN千兆位以太网控制器/82546EB千兆位以太网控制器
-
网络交换机:Cisco Catalyst 2960
-
数据信息:数据块来了。每10毫秒。数据块大小约为1000字节
接收数据包时的网络延迟非常关键(数十微秒很重要)。我对程序进行了最大程度的优化,但是我没有调整Ubuntu的经验。
在Ubuntu中可以配置什么以减少本地处理/发送数据包的延迟?
最佳方案
老实说,I wouldn’t be using Ubuntu for this …但是有些选项可以应用于任何Linux变体。
您将要创建网络堆栈缓冲区:
net.core.rmem_default = 10000000
net.core.wmem_default = 10000000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
如果应用程序正在写入磁盘,则可能需要更改调度程序/电梯(例如deadline
电梯)。
在服务器级别,您可以修改CPU调速器以及电源和CPU频率管理(P-States,C-States)。
在操作系统级别,您可以更改应用程序的实时优先级(chrt
),进行优化以减少中断,将其固定到一个或一组CPU(taskset
)并停止任何不必要的服务或守护程序。
您还可以在以下位置看到一些建议:How to troubleshoot latency between 2 linux hosts
如果不了解所涉及的硬件或网络设备,就很难获得更具体的信息。
次佳方案
如果您要走高性能的道路,通常您将希望运行尽可能少的其他(计划的)进程,因为它们会干扰您的应用程序。
与传统的UNIX操作系统一样,Linux被设计为以公平的方式同时运行多个应用程序,并试图防止资源匮乏,而您的目标恰恰相反,除了您的应用程序之外,其他所有事物都将挨饿。在OS级别上的简单步骤是更改nice级别和应用程序的实时优先级,更改scheduler或使用real-time内核。
通常对TCP /IP进行调整,以防止连接断开并有效利用可用带宽。为了从非常快速的链接中获得尽可能低的延迟,而不是从某些中间链接受到更多限制的连接中获得最大的带宽,您将调整网络堆栈的调整。
sysctl -a
将显示许多可以调整的内核设置。设置取决于您是否使用IPv4或IPv6,以及您在应用程序中已经做过但感兴趣的确切事情,可能是:
-
net.ipv4.tcp_window_scaling=1
RFC 1323-支持大于64K的IPV4 TCP窗口大小-高带宽网络通常需要 -
net.ipv4.tcp_reordering=3
IPV4数据包可以在TCP数据包流中重新排序的最大时间,而无需TCP假定数据包丢失并进入缓慢启动。 -
net.ipv4.tcp_low_latency=1
旨在优先考虑低延迟而不是较高的吞吐量;设置= 1禁用IPV4 TCP预队列处理 -
net.ipv4.tcp_sack=0
设置为1启用对IPV4的选择性确认,这需要启用tcp_timestamps并增加一些数据包开销,如果您没有数据包丢失,则不需要 -
net.ipv4.tcp_timestamps=0
仅在需要麻袋的情况下建议使用。 -
net.ipv4.tcp_fastopen=1
启用以在打开的SYN数据包中发送数据。
kernel source中的大多数(如果不是全部)记录得更好。
当然,您可以编写原始TCP套接字,并在很大程度上将by-pass编码为内核TCP /IP堆栈。
高度优化的系统通常在受信任的网络中运行,并且会禁用其本地(iptables)防火墙。