我正在尝试提高“具有大量连接和高小数据包流量的千兆网络”上的 TCP 吞吐量。我的服务器操作系统是 Ubuntu 11.10 Server 64 位。
大约有 50,000 个(并且还在增长)客户端通过 TCP 套接字(都在同一个端口上)连接到我的服务器。
我的 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
[添加]
我的 NIC 如下:
$ 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?
答案1
问题可能是你的网卡中断太多。如果带宽不是问题,那么频率就是问题:
打开网卡上的发送/接收缓冲区
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 环形缓冲区中的接收缓冲区。
答案2
以下可能不是明确的答案,但肯定会提出一些想法
尝试将这些添加到 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
查看卸载是否已启用。TCP 校验和卸载当今大多数以太网网卡都支持大段卸载,显然博通也支持它。
尝试使用工具
powertop
当网络空闲时以及当网络达到饱和时。这肯定会显示 NIC 中断是否是罪魁祸首。设备轮询是解决这种情况的答案。FreeBSD 支持在 ifconfig 中轮询开关,但 Linux 没有这样的选项。请咨询这启用轮询。据说 BroadCom 也支持轮询,这对您来说是个好消息。
巨型数据包调整可能对你来说不太适用,因为你提到你的流量大部分都是小数据包。不过,无论如何,还是试试吧!
答案3
我在调整列表中注意到时间戳已关闭,请不要这样做。这是对过去带宽非常昂贵且人们希望节省几个字节/数据包的旧时代的回顾。例如,现在 TCP 堆栈使用它来判断“CLOSE_WAIT”中到达套接字的数据包是连接的旧数据包还是新连接的新数据包,并有助于 RTT 计算。与 IPv6 地址将要添加的内容相比,为时间戳节省几个字节根本算不了什么。关闭时间戳弊大于利。
关闭时间戳的建议只是一代又一代系统管理员不断传颂的旧话。有点像“都市传奇”。
答案4
就我而言,仅需进行一次调整:
net.ipv4.tcp_timestamps = 0
做出了非常大且有用的改变,网站加载时间减少了50%。