在具有大量连接和高数据包stream量的千兆networking上提高TCP性能

我试图通过一个“有很多连接和高stream量小包的千兆networking”来提高我的TCP吞吐量。 我的服务器操作系统是Ubuntu 11.10 Server 64bit。

通过TCP套接字连接到我的服务器(全部在同一端口)有大约50,000(和增长)的客户端。

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

使用下面的configuration我的服务器可以处理高达30 Mbps(全双工)的stream量。

你可以请build议最佳实践调整操作系统为我的需要?

我的/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的一些信息: 何时closuresTCP SACK?

    问题可能是你的网卡上有太多的中断。 如果带宽不是问题,频率是问题:

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

       ethtool -g eth0 

    将显示当前设置(256或512个条目)。 你也许可以把这些提高到1024,2048或3172.更多的可能是没有意义的。 这只是一个环形缓冲区,如果服务器不能足够快地处理传入的数据包,那么这个环形缓冲区只会填满。

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

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

       ethtool -a eth0 

    可能会显示:

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

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

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

    如果您没有看到tx和rx,则您的networkingpipe理员必须调整交换机/路由器上的值。 在接收/发送stream量控制上的Cisco上。

    注意:更改这些值将会使您的链接停留很长时间(小于1秒)。

    • 如果所有这些都无济于事 – 也可以将网卡的速度降低到100 MBit(在交换机/路由器端口上也是如此)

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

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

    以下可能不是确定的答案,但肯定会提出一些想法

    尝试将这些添加到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 

    select性tcp ack在高带宽networking的情况下对于最佳性能是有利的。 但是要小心其他缺点 。 这里描述窗口缩放的好处。 对于第三个sysctl选项:默认情况下,TCP在连接closures时将各种连接指标保存在路由caching中,以便在不久的将来build立的连接可以使用这些连接指标设置初始条件。 通常,这会提高整体性能,但有时会导致性能下降。 如果设置,TCP将不会cachingclosures连接的度量标准。

    检查

     ethtool -k ethX 

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

    尝试使用工具

     powertop 

    而networking空闲并达到networking饱和时。 如果网卡中断是罪魁祸首,这一定会显示出来。 设备轮询是这种情况的答案。 FreeBsd在ifconfig里支持轮询切换,但linux没有这个选项。 请参阅此以启用轮询。 BroadCom也支持投票,这对你来说是好消息。

    巨型数据包的调整可能不会削减你,因为你提到你的stream量主要是小包。 但嘿试试吧!

    我build议:

     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数据库服务器和备份软件中进行testing。

    在我的情况下只有一个tuninng:

     net.ipv4.tcp_timestamps = 0 

    做出了非常大而有益的变化,网站加载时间减less了50%。

    您需要在所有CPU内核上分配负载。 开始“irqbalance”。

    我在调整列表中注意到时间戳已closures,请不要这样做。 当带宽非常昂贵,人们想要保存几个字节/数据包时,这已经是过去的日子了。 例如,TCP堆栈现在使用它来判断在“CLOSE_WAIT”中到达套接字的数据包是否是连接的旧数据包,或者是否是新连接的新数据包,并有助于RTT计算。 并且保存一个时间戳的几个字节与什么IPv6地址将要添加什么比较。 closures时间戳不是好事。

    这种closures时间戳的build议只是一个从一代系统pipe理员到下一代系统的倒退。 有点“城市传奇”之类的东西。