通过大量连接和小数据包高流量提高千兆网络上的TCP性能


37

我正在尝试通过“具有大量连接和小数据包高流量的千兆网络”来提高TCP吞吐量。我的服务器操作系统是Ubuntu 11.10 Server 64bit。

通过TCP套接字(都在同一端口上)连接到我的服务器的大约50,000个(并且正在增长)客户端。

我的数据包中有95%的大小为1-150字节(TCP标头和有效载荷)。其余5%从150到4096+字节不等。

通过下面的配置,我的服务器可以处理高达30 Mbps(全双工)的流量。

您能建议最佳实践来调整操作系统以满足我的需求吗?

我的/etc/sysctl.cong样子是这样的:

kernel.pid_max = 1000000
net.ipv4.ip_local_port_range = 2500 65000
fs.file-max = 1000000
#
net.core.netdev_max_backlog=3000
net.ipv4.tcp_sack=0
#
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.somaxconn = 2048
#
net.ipv4.tcp_rmem = 4096 87380 16777216 
net.ipv4.tcp_wmem = 4096 65536 16777216
#
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_mem = 50576   64768   98152
#
net.core.wmem_default = 65536
net.core.rmem_default = 65536
net.ipv4.tcp_window_scaling=1
#
net.ipv4.tcp_mem= 98304 131072 196608
#
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_rfc1337 = 1
net.ipv4.ip_forward = 0
net.ipv4.tcp_congestion_control=cubic
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
#
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192

这是我的限制:

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 193045
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1000000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1000000

[添加]

我的网卡如下:

$ dmesg | grep Broad
[    2.473081] Broadcom NetXtreme II 5771x 10Gigabit Ethernet Driver bnx2x 1.62.12-0 (2011/03/20)
[    2.477808] bnx2x 0000:02:00.0: eth0: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fb000000, IRQ 28, node addr d8:d3:85:bd:23:08
[    2.482556] bnx2x 0000:02:00.1: eth1: Broadcom NetXtreme II BCM57711E XGb (A0) PCI-E x4 5GHz (Gen2) found at mem fa000000, IRQ 40, node addr d8:d3:85:bd:23:0c

[添加2]

ethtool -k eth0
Offload parameters for eth0:
rx-checksumming: on
tx-checksumming: on
scatter-gather: on
tcp-segmentation-offload: on
udp-fragmentation-offload: off
generic-segmentation-offload: on
generic-receive-offload: on
large-receive-offload: on
rx-vlan-offload: on
tx-vlan-offload: on
ntuple-filters: off
receive-hashing: off

[添加3]

 sudo ethtool -S eth0|grep -vw 0
 NIC statistics:
      [1]: rx_bytes: 17521104292
      [1]: rx_ucast_packets: 118326392
      [1]: tx_bytes: 35351475694
      [1]: tx_ucast_packets: 191723897
      [2]: rx_bytes: 16569945203
      [2]: rx_ucast_packets: 114055437
      [2]: tx_bytes: 36748975961
      [2]: tx_ucast_packets: 194800859
      [3]: rx_bytes: 16222309010
      [3]: rx_ucast_packets: 109397802
      [3]: tx_bytes: 36034786682
      [3]: tx_ucast_packets: 198238209
      [4]: rx_bytes: 14884911384
      [4]: rx_ucast_packets: 104081414
      [4]: rx_discards: 5828
      [4]: rx_csum_offload_errors: 1
      [4]: tx_bytes: 35663361789
      [4]: tx_ucast_packets: 194024824
      [5]: rx_bytes: 16465075461
      [5]: rx_ucast_packets: 110637200
      [5]: tx_bytes: 43720432434
      [5]: tx_ucast_packets: 202041894
      [6]: rx_bytes: 16788706505
      [6]: rx_ucast_packets: 113123182
      [6]: tx_bytes: 38443961940
      [6]: tx_ucast_packets: 202415075
      [7]: rx_bytes: 16287423304
      [7]: rx_ucast_packets: 110369475
      [7]: rx_csum_offload_errors: 1
      [7]: tx_bytes: 35104168638
      [7]: tx_ucast_packets: 184905201
      [8]: rx_bytes: 12689721791
      [8]: rx_ucast_packets: 87616037
      [8]: rx_discards: 2638
      [8]: tx_bytes: 36133395431
      [8]: tx_ucast_packets: 196547264
      [9]: rx_bytes: 15007548011
      [9]: rx_ucast_packets: 98183525
      [9]: rx_csum_offload_errors: 1
      [9]: tx_bytes: 34871314517
      [9]: tx_ucast_packets: 188532637
      [9]: tx_mcast_packets: 12
      [10]: rx_bytes: 12112044826
      [10]: rx_ucast_packets: 84335465
      [10]: rx_discards: 2494
      [10]: tx_bytes: 36562151913
      [10]: tx_ucast_packets: 195658548
      [11]: rx_bytes: 12873153712
      [11]: rx_ucast_packets: 89305791
      [11]: rx_discards: 2990
      [11]: tx_bytes: 36348541675
      [11]: tx_ucast_packets: 194155226
      [12]: rx_bytes: 12768100958
      [12]: rx_ucast_packets: 89350917
      [12]: rx_discards: 2667
      [12]: tx_bytes: 35730240389
      [12]: tx_ucast_packets: 192254480
      [13]: rx_bytes: 14533227468
      [13]: rx_ucast_packets: 98139795
      [13]: tx_bytes: 35954232494
      [13]: tx_ucast_packets: 194573612
      [13]: tx_bcast_packets: 2
      [14]: rx_bytes: 13258647069
      [14]: rx_ucast_packets: 92856762
      [14]: rx_discards: 3509
      [14]: rx_csum_offload_errors: 1
      [14]: tx_bytes: 35663586641
      [14]: tx_ucast_packets: 189661305
      rx_bytes: 226125043936
      rx_ucast_packets: 1536428109
      rx_bcast_packets: 351
      rx_discards: 20126
      rx_filtered_packets: 8694
      rx_csum_offload_errors: 11
      tx_bytes: 548442367057
      tx_ucast_packets: 2915571846
      tx_mcast_packets: 12
      tx_bcast_packets: 2
      tx_64_byte_packets: 35417154
      tx_65_to_127_byte_packets: 2006984660
      tx_128_to_255_byte_packets: 373733514
      tx_256_to_511_byte_packets: 378121090
      tx_512_to_1023_byte_packets: 77643490
      tx_1024_to_1522_byte_packets: 43669214
      tx_pause_frames: 228

有关SACK的一些信息:何时关闭TCP SACK?



限制因素是什么?您的CPU是否用完了?如果是这样,那么您就是在树错了树。您需要查看CPU在做什么。
David Schwartz

你有什么网卡?
SaveTheRbtz

1
顺便说一句:为什么您要关闭SACK?
尼尔斯2012年

1
您应该重新考虑使用Broadcom NIC ...
Hubert Kario,2012年

Answers:


21

问题可能是您在网卡上收到了太多的中断。如果带宽不是问题,则频率是问题:

  • 打开网卡上的发送/接收缓冲区

    ethtool -g eth0
    

将显示当前设置(256或512个条目)。您可以将它们提高到1024、2048或3172。更多的选择可能没有意义。这只是一个环形缓冲区,仅在服务器无法足够快地处理传入数据包时才填满。

如果缓冲区开始填充,则流量控制是告诉路由器或交换机减速的另一种方法:

  • 打开服务器及其上连接的交换机/路由器端口的入/出流控制。

    ethtool -a eth0
    

可能会显示:

Pause parameters for eth0:
Autonegotiate:  on
RX:             on
TX:             on

在/ var / log / messages中检查eth0的当前设置。检查类似:

eth0:链路速度为1000 Mbps,全双工,流量控制tx和rx

如果看不到tx和rx,则网络管理员必须调整交换机/路由器上的值。在接收/发送流控制上的Cisco。

当心:更改这些值将使您的链接在很短的时间内(少于1秒)断开和连接。

  • 如果所有这些都无济于事-您还可以将网卡的速度降低到100 MBit(在交换机/路由器端口上执行相同的操作)

    ethtool -s eth0 autoneg off && ethtool -s eth0 speed 100
    

但在您的情况下,我会说-提高NIC环形缓冲区中的接收缓冲区。


ethtool我的角度来看您的号码-将网卡的接收缓冲区设置为最大以避免RX丢弃。我希望您的Broadcom有足够的这些。
尼尔斯2012年

1
使用TCP增加缓冲几乎从来不是一个好主意。我们已经有太多缓冲了:bufferbloat.net/projects/bloat/wiki/Introduction
rmalayter 2012年

3
此缓冲区是直接在NIC上的硬件缓冲区。我将用更多详细信息更新我的答案。由于您丢失传入的数据包,因此需要该缓冲区。我有一台类似的服务器,必须切换到其他NIC(从板载Broadcom到PCIe Intel)才能增加这些缓冲区。之后,我再也没有遇到丢失的RX数据包的情况。
尼尔斯2012年

@malayter:这是第2层上的环形缓冲区。请参阅我的最新答案。
尼尔斯2012年

1
最后,我们有1GB。在不同的地方有很多调优,所以不能真正说出一个单一的问题。
2012年

5

跟随也许不是确定的答案,但肯定会提出一些想法

尝试将它们添加到sysctl.conf

##  tcp selective acknowledgements. 
net.ipv4.tcp_sack = 1
##enable window scaling
net.ipv4.tcp_window_scaling = 1
##
net.ipv4.tcp_no_metrics_save = 1

在高带宽网络的情况下,选择性tcp ack可以实现最佳性能。但请注意其他缺点此处描述了窗口缩放的好处。至于第三个sysctl选项:默认情况下,当连接关闭时,TCP会将各种连接度量标准保存在路由缓存中,以便不久的将来建立的连接可以使用它们来设置初始条件。通常,这会提高整体性能,但有时可能会导致性能下降。如果设置,TCP将不会在关闭连接时缓存指标。

检查与

ethtool -k ethX

查看是否启用了卸载。当今大多数以太网NIC都支持TCP校验和卸载和大段卸载,而且Broadcom显然也支持它。

尝试使用工具

powertop

网络空闲时以及达到网络饱和时。这肯定会显示NIC中断是否是罪魁祸首。设备轮询就是对这种情况的一种解决方案。FreeBsd在ifconfig内部支持轮询开关,但是linux没有这样的选择。咨询以启用轮询。据说BroadCom还支持轮询,这对您来说是个好消息。

由于您提到流量主要由小数据包构成,因此巨型数据包调整可能无法为您解决。但是,还是请尝试一下!


2kaji,明天我会尝试您的建议。关于PowerTop-如果我的目标是性能,我应该调整节电吗?
2012年

是的,当然这也可能会有所帮助。我提到powertop只是为了确保中断是否有害。中断的频率也可以从其他工具收获
卡基

我看到很高的“重新安排中断”-这可能是原因吗?什么是“重新安排中断”?
工人2012年


是的..我看过该教程,但是它是针对笔记本电脑的,而我看到服务器中的中断很高。将尝试将其应用于服务器。
工人2012年

2

您需要在所有CPU内核之间分配负载。启动“ irqbalance”。


1
如果单个IRQ的频率很高,这将无济于事。IRQBalance尝试将单个IRQ分配给适合的逻辑处理器-但是,为单个IRQ服务的处理器永远不会超过一个。
尼尔斯,

2

我在调整列表中注意到时间戳已关闭,请不要这样做。当带宽真的很昂贵并且人们想节省几个字节/数据包时,这是过去的旧时代。例如,如今,TCP堆栈使用它来判断“ CLOSE_WAIT”中到达套接字的数据包是用于连接的旧数据包,还是用于新连接的新数据包,并有助于进行RTT计算。与将要添加的IPv6地址相比,为时间戳节省几个字节没有什么意义。关闭时间戳记弊大于利。

关于关闭时间戳的建议只是一种回退,可以使它从一代sysadmin传递到下一代。有点像“城市传奇”之类的东西。


2

我建议:

kernel.sem = 350 358400 64 1024
net.core.rmem_default = 262144
net.core.rmem_max = 4194304
net.core.wmem_default = 262144
net.core.wmem_max = 4194304
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_adv_win_scale = 2
net.ipv4.tcp_moderate_rcvbuf = 1
net.ipv4.tcp_rmem = 4096 262144 4194304
net.ipv4.tcp_wmem = 4096 262144 4194304
net.ipv4.tcp_keepalive_time = 900
net.ipv4.tcp_keepalive_intvl = 900
net.ipv4.tcp_keepalive_probes = 9

在RHEL上的Oracle DB服务器和备份软件中进行了测试。


5
这些数字是可配置的,因为没有一种“万能的”。这意味着数字本身并不有价值。可能有用的是您用来决定要使用哪些数字的方法。
kasperd '16

2

就我而言,只有一个tuninng:

net.ipv4.tcp_timestamps = 0

进行了非常大且有用的更改,网站加载时间减少了50%。


为了使此设置发生,必须在您的设置中严重破坏某些内容。在正常情况下,时间戳使用的带宽不到1%,并且与其他方式相比,TCP可以更紧密地进行重传。
kasperd '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.